summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-04-03 11:15:51 -0700
committerH.J. Lu <hjl.tools@gmail.com>2012-04-03 11:15:51 -0700
commitc924cab2fd8932bdfb107c4ca7d26128ba56f19e (patch)
tree0eea6430e211564fc331f66625373ec761837982
parent4c15f6d5728cb694d7d954b2c20409fdc0400b9e (diff)
parent3cef948a814542119083003a3c35a24e036230b6 (diff)
downloadgcc-hjl/x32/addr32.tar.gz
Merge remote-tracking branch 'origin/master' into hjl/x32/addr32hjl/x32/addr32
-rw-r--r--ChangeLog6
-rw-r--r--config/ChangeLog9
-rw-r--r--config/math.m47
-rw-r--r--config/mmap.m46
-rwxr-xr-xcontrib/gcc_update1
-rw-r--r--gcc/ChangeLog497
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in19
-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.h4
-rw-r--r--gcc/bb-reorder.c2
-rw-r--r--gcc/cfganal.c12
-rw-r--r--gcc/cfgcleanup.c22
-rw-r--r--gcc/cfgexpand.c9
-rw-r--r--gcc/cfghooks.c37
-rw-r--r--gcc/cfgloop.c10
-rw-r--r--gcc/cfgloopmanip.c2
-rw-r--r--gcc/cfgrtl.c8
-rw-r--r--gcc/cgraph.c8
-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.gcc30
-rw-r--r--gcc/config/arm/arm.c28
-rw-r--r--gcc/config/arm/arm.h10
-rw-r--r--gcc/config/arm/arm.opt2
-rw-r--r--gcc/config/avr/avr-c.c6
-rw-r--r--gcc/config/avr/avr.c111
-rw-r--r--gcc/config/avr/avr.h32
-rw-r--r--gcc/config/avr/avr.opt4
-rw-r--r--gcc/config/avr/driver-avr.c21
-rw-r--r--gcc/config/avr/genmultilib.awk119
-rw-r--r--gcc/config/avr/multilib.h70
-rw-r--r--gcc/config/avr/t-avr6
-rw-r--r--gcc/config/avr/t-multilib54
-rw-r--r--gcc/config/cris/linux.opt2
-rw-r--r--gcc/config/h8300/h8300-protos.h1
-rw-r--r--gcc/config/h8300/h8300.c49
-rw-r--r--gcc/config/h8300/h8300.md16
-rw-r--r--gcc/config/h8300/h8300.opt9
-rw-r--r--gcc/config/i386/biarch64.h2
-rw-r--r--gcc/config/i386/biarchx32.h28
-rw-r--r--gcc/config/i386/gnu-user64.h9
-rw-r--r--gcc/config/i386/i386.c210
-rw-r--r--gcc/config/i386/i386.h4
-rw-r--r--gcc/config/i386/i386.opt10
-rw-r--r--gcc/config/i386/sse.md12
-rw-r--r--gcc/config/ia64/ia64.c80
-rw-r--r--gcc/config/ia64/vms.h3
-rw-r--r--gcc/config/linux-android.h4
-rw-r--r--gcc/config/m68k/m68k.opt2
-rw-r--r--gcc/config/mep/mep.opt2
-rw-r--r--gcc/config/pa/pa-hpux.opt2
-rw-r--r--gcc/config/pa/pa64-hpux.opt2
-rw-r--r--gcc/config/picochip/picochip.opt2
-rw-r--r--gcc/config/rs6000/sysv4.opt2
-rw-r--r--gcc/config/sh/sh.c220
-rw-r--r--gcc/config/sh/sh.opt2
-rw-r--r--gcc/config/sparc/long-double-switch.opt2
-rw-r--r--gcc/config/sparc/sparc.opt2
-rw-r--r--gcc/config/v850/v850.opt2
-rw-r--r--gcc/config/vax/vax.opt2
-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/ChangeLog45
-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.c50
-rw-r--r--gcc/cp/tree.c5
-rw-r--r--gcc/cp/typeck.c5
-rw-r--r--gcc/cp/typeck2.c11
-rw-r--r--gcc/cprop.c14
-rw-r--r--gcc/cse.c10
-rw-r--r--gcc/doc/invoke.texi17
-rw-r--r--gcc/double-int.c112
-rw-r--r--gcc/double-int.h3
-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/expmed.c5
-rw-r--r--gcc/expr.c35
-rw-r--r--gcc/fortran/ChangeLog9
-rw-r--r--gcc/fortran/match.c6
-rw-r--r--gcc/fortran/parse.c2
-rw-r--r--gcc/ggc-page.c26
-rw-r--r--gcc/gimple-fold.c23
-rw-r--r--gcc/gimple.h1
-rw-r--r--gcc/go/gofrontend/expressions.cc3311
-rw-r--r--gcc/go/gofrontend/expressions.h304
-rw-r--r--gcc/go/gofrontend/gogo.cc6
-rw-r--r--gcc/go/gofrontend/parse.cc2
-rw-r--r--gcc/go/gofrontend/statements.cc26
-rw-r--r--gcc/go/gofrontend/types.cc145
-rw-r--r--gcc/go/gofrontend/types.h8
-rw-r--r--gcc/go/gofrontend/unsafe.cc8
-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.c70
-rw-r--r--gcc/omp-low.c4
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/testsuite/ChangeLog125
-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/overload/virtual2.C31
-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/compile/pr52750.c11
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr52760.c27
-rw-r--r--gcc/testsuite/gcc.dg/pr52691.c24
-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/avr/torture/builtins-2.c46
-rw-r--r--gcc/testsuite/gcc.target/i386/pr52736.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/pr52754.c33
-rw-r--r--gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/allocate_class_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/allocate_with_typespec_4.f902
-rw-r--r--gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f902
-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/pack18.adb12
-rw-r--r--gcc/testsuite/gnat.dg/pack18_pkg.ads21
-rw-r--r--gcc/testsuite/gnat.dg/specs/aggr5.ads19
-rw-r--r--gcc/testsuite/gnat.dg/vect7.adb20
-rw-r--r--gcc/testsuite/gnat.dg/vect7.ads15
-rw-r--r--gcc/tracer.c18
-rw-r--r--gcc/trans-mem.c11
-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-cfgcleanup.c1
-rw-r--r--gcc/tree-data-ref.c156
-rw-r--r--gcc/tree-data-ref.h32
-rw-r--r--gcc/tree-eh.c3
-rw-r--r--gcc/tree-flow.h3
-rw-r--r--gcc/tree-inline.c2
-rw-r--r--gcc/tree-mudflap.c6
-rw-r--r--gcc/tree-pass.h1
-rw-r--r--gcc/tree-ssa-ccp.c13
-rw-r--r--gcc/tree-ssa-forwprop.c12
-rw-r--r--gcc/tree-ssa-loop.c2
-rw-r--r--gcc/tree-ssa-pre.c4
-rw-r--r--gcc/tree-ssa-threadupdate.c54
-rw-r--r--gcc/tree-vect-generic.c7
-rw-r--r--gcc/tree-vect-slp.c15
-rw-r--r--gcc/tree.c4
-rw-r--r--gcc/varasm.c19
-rw-r--r--libffi/ChangeLog36
-rw-r--r--libffi/src/powerpc/ffi.c13
-rw-r--r--libffi/src/sparc/v9.S2
-rw-r--r--libffi/src/x86/ffi.c25
-rw-r--r--libffi/src/x86/win32.S30
-rw-r--r--libgcc/ChangeLog21
-rw-r--r--libgcc/config/avr/lib1funcs.S14
-rw-r--r--libgcc/config/i386/linux-unwind.h21
-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/dir.go2
-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/libcall_posix.go2
-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
-rwxr-xr-xlibgo/mksysinfo.sh5
-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/ChangeLog70
-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/functional22
-rw-r--r--libstdc++-v3/libsupc++/Makefile.am31
-rw-r--r--libstdc++-v3/libsupc++/Makefile.in30
-rw-r--r--libstdc++-v3/src/Makefile.am97
-rw-r--r--libstdc++-v3/src/Makefile.in118
-rw-r--r--libstdc++-v3/src/c++11/Makefile.am24
-rw-r--r--libstdc++-v3/src/c++11/Makefile.in33
-rw-r--r--libstdc++-v3/src/c++11/compatibility-atomic-c++0x.cc5
-rw-r--r--libstdc++-v3/src/c++11/compatibility-c++0x.cc5
-rw-r--r--libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc72
-rw-r--r--libstdc++-v3/src/c++11/future.cc20
-rw-r--r--libstdc++-v3/src/c++11/mutex.cc28
-rw-r--r--libstdc++-v3/src/c++98/Makefile.am59
-rw-r--r--libstdc++-v3/src/c++98/Makefile.in75
-rw-r--r--libstdc++-v3/src/c++98/compatibility-ldbl.cc6
-rw-r--r--libstdc++-v3/src/c++98/compatibility-list-2.cc6
-rw-r--r--libstdc++-v3/src/c++98/compatibility-list.cc6
-rw-r--r--libstdc++-v3/src/c++98/compatibility.cc6
-rw-r--r--libstdc++-v3/testsuite/20_util/function/10.cc37
-rw-r--r--libstdc++-v3/testsuite/20_util/function_objects/mem_fn/adl.cc44
-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
-rw-r--r--libstdc++-v3/testsuite/Makefile.am1
-rw-r--r--libstdc++-v3/testsuite/Makefile.in1
472 files changed, 22597 insertions, 8273 deletions
diff --git a/ChangeLog b/ChangeLog
index c652b194298..45c3ef3d59a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-28 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/52737
+ * contrib/gcc_update (files_and_dependencies):
+ Remove gcc/config/avr/t-multilib from touch data.
+
2012-03-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* MAINTAINERS (OS Port Maintainers): Remove irix.
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/contrib/gcc_update b/contrib/gcc_update
index 0289d9b2663..b81fc0ce458 100755
--- a/contrib/gcc_update
+++ b/contrib/gcc_update
@@ -83,7 +83,6 @@ gcc/config/arm/arm-tune.md: gcc/config/arm/arm-cores.def gcc/config/arm/gentune.
gcc/config/arm/arm-tables.opt: gcc/config/arm/arm-arches.def gcc/config/arm/arm-cores.def gcc/config/arm/arm-fpus.def gcc/config/arm/genopt.sh
gcc/config/avr/avr-tables.opt: gcc/config/avr/avr-mcus.def gcc/config/avr/genopt.sh
gcc/config/avr/t-multilib: gcc/config/avr/avr-mcus.def gcc/config/avr/genmultilib.awk
-gcc/config/avr/multilib.h: gcc/config/avr/avr-mcus.def gcc/config/avr/genmultilib.awk
gcc/config/c6x/c6x-tables.opt: gcc/config/c6x/c6x-isas.def gcc/config/c6x/genopt.sh
gcc/config/c6x/c6x-sched.md: gcc/config/c6x/c6x-sched.md.in gcc/config/c6x/gensched.sh
gcc/config/c6x/c6x-mult.md: gcc/config/c6x/c6x-mult.md.in gcc/config/c6x/genmult.sh
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 729f51f8846..e20c0e437cd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,500 @@
+2012-04-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * expr.c (get_bit_range): Add OFFSET parameter and adjust BITPOS.
+ Change type of BITOFFSET to signed. Make sure the lower bound of
+ the computed range is non-negative by adjusting OFFSET and BITPOS.
+ (expand_assignment): Adjust call to get_bit_range.
+
+2012-04-03 Sandeep Kumar Singh <Sandeep.Singh2@kpitcummins.com>
+
+ * h8300/h8300.c (h8300_current_function_monitor_function_p):
+ New function. Added to check monitor functions.
+ (h8300_option_override): Modified to generate error/warning
+ messages for invalid combinations of different command line
+ options.
+ * h8300/h8300.md: Generate 'rte' for monitor functions. Do not
+ save EXR on stack for monitor function in case of H8S target
+ when "-mno-exr" is passed.
+ * h8300/h8300-protos.h
+ (h8300_current_function_monitor_function_p): Add prototype.
+ * doc/invoke.texi: Document H8S options.
+
+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
+ crtbegin_so%O%s for -shared.
+ (ANDROID_ENDFILE_SPEC): Use crtend_so%O%s for -shared.
+
+2012-03-29 Richard Guenther <rguenther@suse.de>
+
+ * tree-flow.h (struct pre_expr_d): Remove forward declaration.
+ (add_to_value): Remove.
+ (print_value_expressions): Likewise.
+ * tree-ssa-pre.c (add_to_value): Make static.
+ (print_value_expressions): Likewise.
+ * gimple.h (gimple_adjust_this_by_delta): Remove.
+ * gimple-fold.c (gimple_adjust_this_by_delta): Likewise.
+
+2012-03-29 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/50708
+ * double-int.h (rshift_double): Remove.
+ * double-int.c (lshift_double): Use absu_hwi to make count
+ positive.
+ (rshift_double): Make static, take unsigned count argument,
+ remove handling of negative count argument.
+ (double_int_rshift): Dispatch to lshift_double.
+
+2012-03-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/biarch64.h (TARGET_64BIT_DEFAULT): Add
+ OPTION_MASK_ABI_64.
+
+ * config/i386/gnu-user64.h (SPEC_64): Support TARGET_BI_ARCH == 2.
+ (SPEC_X32): Likewise.
+ (MULTILIB_DEFAULTS): Likewise.
+
+ * config/i386/i386.c (isa_opts): Remove -m64.
+ (ix86_target_string): Properly handle -m32/-m64/-mx32.
+ (ix86_option_override_internal): Properly
+ set OPTION_MASK_ISA_64BIT and OPTION_MASK_ISA_X32 as well as
+ handle -m32, -m64 and -mx32.
+
+ * config/i386/i386.h (TARGET_X32): Replace OPTION_ISA_X32
+ with OPTION_ABI_X32. Moved after TARGET_LP64.
+ (TARGET_LP64): Changed to OPTION_ABI_64.
+
+ * config/i386/i386.opt (m64): Replace ISA_64BIT with ABI_64.
+ (mx32): Replace ISA_X32 with ABI_X32.
+
+2012-03-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree.c (tree_size) <VECTOR_CST>: New case.
+
+2012-03-28 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.c (ix86_modes_tieable_p): Handle 32bit AVX modes.
+ (ix86_expand_vector_move_misalign): Remove un-needed gen_lowpart calls.
+
+2012-03-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/52691
+ * tree-ssa-ccp.c (optimize_stdarg_builtin): Optimize
+ __builtin_va_start to __builtin_next_arg if the latter is
+ builtin_decl_explicit_p rather than when it is not.
+
+ PR middle-end/52750
+ * tree-vect-generic.c (vector_element): Perform multiplication
+ for pos in bitsizetype type instead of idx type.
+
+2012-03-28 Richard Guenther <rguenther@suse.de>
+
+ * loop-init.c (loop_optimizer_init): If loops are preserved
+ perform incremental initialization of required loop features.
+ (loop_optimizer_finalize): If loops are to be preserved only
+ clean up optional loop features.
+ (rtl_loop_done): Forcefully free loops here.
+ * cgraph.c (cgraph_release_function_body): Forcefully free loops.
+ * cfgexpand.c (expand_gimple_cond): Properly add new basic-blocks
+ to existing loops.
+ (construct_init_block): Likewise.
+ (construct_exit_block): Likewise.
+ (gimple_expand_cfg): Clear LOOP_CLOSED_SSA loop state. Cleanup
+ the CFG after expanding.
+ * cfgloop.c (verify_loop_structure): Calculate or verify dominators.
+ If we needed to calculate them, free them afterwards.
+ * tree-pass.h (PROP_loops): New define.
+ * tree-ssa-loop.c (pass_tree_loop_init): Provide PROP_loops.
+ * basic-block.h (CLEANUP_CFG_CHANGED): New.
+ * cfgcleanup.c (merge_blocks_move): Protect loop latches.
+ (cleanup_cfg): If we did something and have loops around, fix them up.
+ * cse.c (rest_of_handle_cse_after_global_opts): Call cleanup_cfg
+ with CLEANUP_CFG_CHANGED.
+ * cfghooks.c (merge_blocks): If we merge a loop header into
+ its predecessor, update the loop structure.
+ (duplicate_block): If we copy a loop latch, adjust loop state
+ to note we may have multiple latches.
+ (delete_basic_block): Mark loops for fixup if we remove a loop.
+ * cfganal.c (forwarder_block_p): Protect loop latches, headers
+ and preheaders.
+ * cfgrtl.c (rtl_can_merge_blocks): Protect loop latches.
+ (cfg_layout_can_merge_blocks_p): Likewise.
+ * cprop.c (bypass_block): If we create a loop with multiple
+ entries, mark it for removal.
+ * except.c (emit_to_new_bb_before): Add the new basic-block
+ to existing loops.
+ * tree-eh.c (lower_resx): Likewise.
+ * omp-low.c (finalize_task_copyfn): Do not copy PROP_loops.
+ (expand_omp_taskreg): Likewise.
+ * tree-inline.c (initialize_cfun): Likewise.
+ * tree-mudflap.c (add_bb_to_loop): Prototype.
+ (mf_build_check_statement_for): Properly add new basic-blocks
+ to existing loops.
+ * tree-ssa-threadupdate.c (thread_block): Mark loops for fixup
+ if we remove a loop.
+ (thread_through_loop_header): Likewise.
+ * trans-mem.c (tm_log_emit_save_or_restores): Properly add
+ new basic-blocks to existing loops.
+ (expand_transaction): Likewise.
+ * Makefile.in (except.o): Add $(CFGLOOP_H).
+ (expr.o): Likewise.
+ (cgraph.o): Likewise.
+ (cprop.o): Likewise.
+ (cfgexpand.o): Likewise.
+ (cfganal.o): Likewise.
+ (trans-mem.o): Likewise.
+ (tree-eh.o): Likewise.
+
+2012-03-28 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/52692
+ * config/avr/avr.c (TARGET_BUILTIN_DECL): New define.
+ (avr_builtin_decl): New static function.
+ (struct avr_builtin_description, avr_bdesc): Move up.
+ Add GTY marker. Add field fndecl. Remove redundant field id.
+ (avr_init_builtins): Initialize avr_bdesc[ID].fndecl.
+ (avr_expand_builtin): Code cleanup because .id is removed.
+
+2012-03-28 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/52737
+ * config.gcc (tm_file): Remove avr/multilib.h.
+
+ * doc/invoke.texi (AVR Options): Adjust documentation of -mtiny-stack.
+
+ * config/avr/genmultilib.awk: Remove code to generate multilib.h.
+ (BEGIN): Use -msp8 as multilib option instead of -mtiny-stack.
+ * config/avr/t-avr: Remove generation of multilib.h.
+ * config/avr/t-multilib: Regenerate.
+ * config/avr/multilib.h: Remove.
+ * config/avr/avr.opt (-msp8): New option.
+ (avr_sp8): New variable.
+ * config/avr/driver-avr.c (avr_device_to_sp8): New function.
+ * config/avr/avr.h (AVR_HAVE_SPH): New define.
+ (AVR_HAVE_8BIT_SP): Also set by avr_sp8 i.e. -msp8.
+ (avr_device_to_sp8): New prototype.
+ (EXTRA_SPEC_FUNCTIONS): Add { "device_to_sp8", avr_device_to_sp8 }
+ (DRIVER_SELF_SPECS): New define.
+ * config/avr/avr-c.c (avr_cpu_cpp_builtins): New built-in defines:
+ __AVR_SP8__, __AVR_HAVE_SPH__.
+ * config/avr/avr.c (output_movhi): Use AVR_HAVE_SPH instead of
+ AVR_HAVE_8BIT_SP to decide if SP_H is present.
+ (avr_file_start): Ditto.
+
+2012-03-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/52736
+ * config/i386/sse.md (sse2_loadlpd splitter): Use offset 0
+ instead of 8 in adjust_address.
+
+2012-03-27 Aurelien Buhrig <aurelien.buhrig.gcc@gmail.com>
+
+ PR middle-end/51893
+ * expmed.c (store_bit_field_1): Fix wordnum value for big-endian
+ targets.
+
+2012-03-27 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/50751
+ * config/sh/sh.c (sh_legitimize_address, sh_legitimize_reload_address):
+ Rearrange conditional logic. Move displacement address calculations
+ to ...
+ (sh_find_mov_disp_adjust): ... this new function.
+
+2012-03-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/arm/arm.opt (mapcs): Remove MaskExists.
+ * config/cris/linux.opt (mno-gotplt): Likewise.
+ * config/i386/i386.opt (mhard-float): Likewise.
+ (msse4): Likewise.
+ (mno-sse4): Likewise.
+ * config/m68k/m68k.opt (mhard-float): Likewise.
+ * config/mep/mep.op (mcop32): Likewise.
+ * config/pa/pa-hpux.opt (msio): Likewise.
+ * config/pa/pa64-hpux.opt (mgnu-ld): Likewise.
+ * config/picochip/picochip.opt (mlittle): Likewise.
+ * config/sh/sh.opt (mrenesas): Likewise.
+ * config/sparc/long-double-switch.opt (mlong-double-128): Likewise.
+ * config/sparc/sparc.opt (mhard-float): Likewise.
+ * config/v850/v850.opt (mv850es): Likewise.
+ * config/vax/vax.opt (mg-float): Likewise.
+
2012-03-27 Martin Jambor <mjambor@suse.cz>
PR middle-end/52693
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 5839a3d6cbc..7fc43becf8f 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20120327
+20120403
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 716b3a43d2a..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
@@ -2159,7 +2160,7 @@ trans-mem.o : trans-mem.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_INLINE_H) \
$(DIAGNOSTIC_CORE_H) $(DEMANGLE_H) output.h $(TRANS_MEM_H) \
$(PARAMS_H) $(TARGET_H) langhooks.h \
- tree-pretty-print.h gimple-pretty-print.h
+ tree-pretty-print.h gimple-pretty-print.h $(CFGLOOP_H)
ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(GGC_H) $(HASHTAB_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) hosthooks.h \
@@ -2468,7 +2469,8 @@ tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \
tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) langhooks.h \
$(GGC_H) $(TREE_PASS_H) coretypes.h $(TIMEVAR_H) pointer-set.h \
- $(TREE_DUMP_H) $(TREE_INLINE_H) tree-iterator.h toplev.h $(DIAGNOSTIC_CORE_H)
+ $(TREE_DUMP_H) $(TREE_INLINE_H) tree-iterator.h toplev.h \
+ $(DIAGNOSTIC_CORE_H) $(CFGLOOP_H)
tree-ssa-loop.o : tree-ssa-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) output.h \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TREE_PASS_H) $(TIMEVAR_H) \
@@ -2814,7 +2816,7 @@ except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
dwarf2asm.h dwarf2out.h toplev.h $(DIAGNOSTIC_CORE_H) $(HASHTAB_H) intl.h $(GGC_H) \
gt-except.h $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) $(DWARF2_H) \
$(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TIMEVAR_H) $(TREE_FLOW_H) \
- tree-pretty-print.h sbitmap.h $(COMMON_TARGET_H)
+ tree-pretty-print.h sbitmap.h $(COMMON_TARGET_H) $(CFGLOOP_H)
expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) $(EXPR_H) $(OPTABS_H) \
$(LIBFUNCS_H) $(INSN_ATTR_H) insn-config.h $(RECOG_H) output.h \
@@ -2912,7 +2914,7 @@ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
$(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) cif-code.def \
value-prof.h $(EXCEPT_H) $(IPA_UTILS_H) $(DIAGNOSTIC_CORE_H) \
- ipa-inline.h $(LTO_STREAMER_H)
+ ipa-inline.h $(LTO_STREAMER_H) $(CFGLOOP_H)
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) \
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
@@ -3010,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) \
@@ -3029,7 +3031,7 @@ cprop.o : cprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h $(DIAGNOSTIC_CORE_H) \
$(TM_P_H) $(PARAMS_H) cselib.h $(EXCEPT_H) $(TREE_H) $(TIMEVAR_H) \
intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) \
- $(DF_H)
+ $(DF_H) $(CFGLOOP_H)
gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h $(DIAGNOSTIC_CORE_H) \
@@ -3149,7 +3151,7 @@ cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(DIAGNOSTIC_H) toplev.h $(DIAGNOSTIC_CORE_H) $(BASIC_BLOCK_H) $(FLAGS_H) debug.h $(PARAMS_H) \
value-prof.h $(TREE_INLINE_H) $(TARGET_H) $(SSAEXPAND_H) $(REGS_H) \
tree-pretty-print.h gimple-pretty-print.h $(BITMAP_H) sbitmap.h \
- $(INSN_ATTR_H) $(INTEGRATE_H)
+ $(INSN_ATTR_H) $(INTEGRATE_H) $(CFGLOOP_H)
cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \
$(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \
output.h $(FUNCTION_H) $(EXCEPT_H) $(TM_P_H) $(INSN_ATTR_H) \
@@ -3158,7 +3160,8 @@ cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_H) \
$(TREE_PASS_H) $(DF_H) $(GGC_H) $(COMMON_TARGET_H)
cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h insn-config.h $(RECOG_H) $(TM_P_H) \
- $(TIMEVAR_H) $(OBSTACK_H) $(DIAGNOSTIC_CORE_H) vecprim.h sbitmap.h $(BITMAP_H)
+ $(TIMEVAR_H) $(OBSTACK_H) $(DIAGNOSTIC_CORE_H) vecprim.h sbitmap.h \
+ $(BITMAP_H) $(CFGLOOP_H)
cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h $(DIAGNOSTIC_CORE_H) \
$(FUNCTION_H) $(EXCEPT_H) $(TIMEVAR_H) $(TREE_H) $(EXPR_H) sbitmap.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 3ff1cd645ea..f8cdea0085d 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -741,6 +741,7 @@ edge find_edge (basic_block, basic_block);
#define CLEANUP_NO_INSN_DEL 16 /* Do not try to delete trivially dead
insns. */
#define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */
+#define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */
/* In lcm.c */
extern struct edge_list *pre_edge_lcm (int, sbitmap *, sbitmap *,
@@ -829,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/cfganal.c b/gcc/cfganal.c
index e27bbb2c6be..d361ff08f98 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h"
#include "sbitmap.h"
#include "timevar.h"
+#include "cfgloop.h"
/* Store the data structures necessary for depth-first search. */
struct depth_first_search_dsS {
@@ -94,6 +95,17 @@ forwarder_block_p (const_basic_block bb)
|| !single_succ_p (bb))
return false;
+ /* Protect loop latches, headers and preheaders. */
+ if (current_loops)
+ {
+ basic_block dest;
+ if (bb->loop_father->header == bb)
+ return false;
+ dest = EDGE_SUCC (bb, 0)->dest;
+ if (dest->loop_father->header == dest)
+ return false;
+ }
+
for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
if (INSN_P (insn) && flow_active_insn_p (insn))
return false;
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index c695878802c..3824797485d 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -779,6 +779,11 @@ merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
if (e->flags & EDGE_FALLTHRU)
{
int b_index = b->index, c_index = c->index;
+
+ /* Protect the loop latches. */
+ if (current_loops && c->loop_father->latch == c)
+ return NULL;
+
merge_blocks (b, c);
update_forwarder_flag (b);
@@ -2976,6 +2981,23 @@ cleanup_cfg (int mode)
if (!(mode & CLEANUP_CFGLAYOUT))
delete_dead_jumptables ();
+ /* ??? We probably do this way too often. */
+ if (current_loops
+ && (changed
+ || (mode & CLEANUP_CFG_CHANGED)))
+ {
+ bitmap changed_bbs;
+ timevar_push (TV_REPAIR_LOOPS);
+ /* The above doesn't preserve dominance info if available. */
+ gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
+ calculate_dominance_info (CDI_DOMINATORS);
+ changed_bbs = BITMAP_ALLOC (NULL);
+ fix_loop_structure (changed_bbs);
+ BITMAP_FREE (changed_bbs);
+ free_dominance_info (CDI_DOMINATORS);
+ timevar_pop (TV_REPAIR_LOOPS);
+ }
+
timevar_pop (TV_CLEANUP_CFG);
return changed;
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 75d2b162865..d148853143b 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "ssaexpand.h"
#include "bitmap.h"
#include "sbitmap.h"
+#include "cfgloop.h"
#include "regs.h" /* For reg_renumber. */
#include "integrate.h" /* For emit_initial_value_sets. */
#include "insn-attr.h" /* For INSN_SCHEDULING. */
@@ -1940,6 +1941,8 @@ expand_gimple_cond (basic_block bb, gimple stmt)
false_edge->flags |= EDGE_FALLTHRU;
new_bb->count = false_edge->count;
new_bb->frequency = EDGE_FREQUENCY (false_edge);
+ if (current_loops && bb->loop_father)
+ add_bb_to_loop (new_bb, bb->loop_father);
new_edge = make_edge (new_bb, dest, 0);
new_edge->probability = REG_BR_PROB_BASE;
new_edge->count = new_bb->count;
@@ -4118,6 +4121,8 @@ construct_init_block (void)
ENTRY_BLOCK_PTR);
init_block->frequency = ENTRY_BLOCK_PTR->frequency;
init_block->count = ENTRY_BLOCK_PTR->count;
+ if (current_loops && ENTRY_BLOCK_PTR->loop_father)
+ add_bb_to_loop (init_block, ENTRY_BLOCK_PTR->loop_father);
if (e)
{
first_block = e->dest;
@@ -4185,6 +4190,8 @@ construct_exit_block (void)
EXIT_BLOCK_PTR->prev_bb);
exit_block->frequency = EXIT_BLOCK_PTR->frequency;
exit_block->count = EXIT_BLOCK_PTR->count;
+ if (current_loops && EXIT_BLOCK_PTR->loop_father)
+ add_bb_to_loop (exit_block, EXIT_BLOCK_PTR->loop_father);
ix = 0;
while (ix < EDGE_COUNT (EXIT_BLOCK_PTR->preds))
@@ -4556,6 +4563,8 @@ gimple_expand_cfg (void)
timevar_push (TV_POST_EXPAND);
/* We are no longer in SSA form. */
cfun->gimple_df->in_ssa_p = false;
+ if (current_loops)
+ loops_state_clear (LOOP_CLOSED_SSA);
/* Expansion is used by optimization passes too, set maybe_hot_insn_p
conservatively to true until they are all profile aware. */
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index c4c51cc4404..bc1b7a2f582 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -508,6 +508,7 @@ delete_basic_block (basic_block bb)
{
loop->header = NULL;
loop->latch = NULL;
+ loops_state_set (LOOPS_NEED_FIXUP);
}
remove_bb_from_loops (bb);
@@ -682,8 +683,18 @@ merge_blocks (basic_block a, basic_block b)
cfg_hooks->merge_blocks (a, b);
+ /* If we merge a loop header into its predecessor, update the loop
+ structure. */
if (current_loops != NULL)
- remove_bb_from_loops (b);
+ {
+ if (b->loop_father->header == b)
+ {
+ remove_bb_from_loops (a);
+ add_bb_to_loop (a, b->loop_father);
+ a->loop_father->header = a;
+ }
+ remove_bb_from_loops (b);
+ }
/* Normally there should only be one successor of A and that is B, but
partway though the merge of blocks for conditional_execution we'll
@@ -998,7 +1009,29 @@ 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 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->header == bb)
+ {
+ add_bb_to_loop (new_bb, loop_outer (cloop));
+ cloop->header = NULL;
+ cloop->latch = NULL;
+ 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);
+ }
+ }
}
return new_bb;
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 160486f13b1..94ba874b101 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -1317,9 +1317,13 @@ verify_loop_structure (void)
unsigned num = number_of_loops ();
loop_iterator li;
struct loop_exit *exit, *mexit;
+ bool dom_available = dom_info_available_p (CDI_DOMINATORS);
- /* We need up-to-date dominators, verify them. */
- verify_dominators (CDI_DOMINATORS);
+ /* We need up-to-date dominators, compute or verify them. */
+ if (!dom_available)
+ calculate_dominance_info (CDI_DOMINATORS);
+ else
+ verify_dominators (CDI_DOMINATORS);
/* Check sizes. */
sizes = XCNEWVEC (unsigned, num);
@@ -1563,6 +1567,8 @@ verify_loop_structure (void)
gcc_assert (!err);
free (sizes);
+ if (!dom_available)
+ free_dominance_info (CDI_DOMINATORS);
}
/* Returns latch edge of LOOP. */
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 33bcf4b9872..5292ae536b5 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -1728,6 +1728,8 @@ fix_loop_structure (bitmap changed_bbs)
if (record_exits)
record_loop_exits ();
+ loops_state_clear (LOOPS_NEED_FIXUP);
+
#ifdef ENABLE_CHECKING
verify_loop_structure ();
#endif
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index b86cc74b6a4..ea293933704 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -727,6 +727,10 @@ rtl_can_merge_blocks (basic_block a, basic_block b)
if (BB_PARTITION (a) != BB_PARTITION (b))
return false;
+ /* Protect the loop latches. */
+ if (current_loops && b->loop_father->latch == b)
+ return false;
+
/* There must be exactly one edge in between the blocks. */
return (single_succ_p (a)
&& single_succ (a) == b
@@ -2786,6 +2790,10 @@ cfg_layout_can_merge_blocks_p (basic_block a, basic_block b)
if (BB_PARTITION (a) != BB_PARTITION (b))
return false;
+ /* Protect the loop latches. */
+ if (current_loops && b->loop_father->latch == b)
+ return false;
+
/* If we would end up moving B's instructions, make sure it doesn't fall
through into the exit block, since we cannot recover from a fallthrough
edge into the exit block occurring in the middle of a function. */
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 7c44c059245..e429a91d82e 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -99,6 +99,7 @@ The callgraph:
#include "ipa-utils.h"
#include "lto-streamer.h"
#include "ipa-inline.h"
+#include "cfgloop.h"
const char * const ld_plugin_symbol_resolution_names[]=
{
@@ -1363,6 +1364,12 @@ cgraph_release_function_body (struct cgraph_node *node)
{
tree old_decl = current_function_decl;
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
+ if (cfun->cfg
+ && current_loops)
+ {
+ cfun->curr_properties &= ~PROP_loops;
+ loop_optimizer_finalize ();
+ }
if (cfun->gimple_df)
{
current_function_decl = node->decl;
@@ -1379,7 +1386,6 @@ cgraph_release_function_body (struct cgraph_node *node)
}
if (cfun->value_histograms)
free_histograms ();
- gcc_assert (!current_loops);
pop_cfun();
gimple_set_body (node->decl, NULL);
VEC_free (ipa_opt_pass, heap,
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 b44224ac6d2..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
@@ -898,13 +920,13 @@ arm*-wince-pe*)
extra_objs="pe.o"
;;
avr-*-rtems*)
- tm_file="elfos.h avr/elf.h avr/avr.h avr/multilib.h dbxelf.h avr/rtems.h rtems.h newlib-stdint.h"
+ tm_file="elfos.h avr/elf.h avr/avr.h dbxelf.h avr/rtems.h rtems.h newlib-stdint.h"
tmake_file="avr/t-avr avr/t-multilib t-rtems avr/t-rtems"
extra_gcc_objs="driver-avr.o avr-devices.o"
extra_objs="avr-devices.o avr-log.o"
;;
avr-*-*)
- tm_file="elfos.h avr/elf.h avr/avr.h avr/multilib.h dbxelf.h newlib-stdint.h"
+ tm_file="elfos.h avr/elf.h avr/avr.h dbxelf.h newlib-stdint.h"
tmake_file="avr/t-avr avr/t-multilib"
use_gcc_stdint=wrap
extra_gcc_objs="driver-avr.o avr-devices.o"
@@ -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/arm/arm.opt b/gcc/config/arm/arm.opt
index 934aa35775e..e03a1633767 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -59,7 +59,7 @@ Target Report Mask(ABORT_NORETURN)
Generate a call to abort if a noreturn function returns
mapcs
-Target RejectNegative Mask(APCS_FRAME) MaskExists Undocumented
+Target RejectNegative Mask(APCS_FRAME) Undocumented
mapcs-float
Target Report Mask(APCS_FLOAT)
diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c
index 1babb5372c2..d689fa02380 100644
--- a/gcc/config/avr/avr-c.c
+++ b/gcc/config/avr/avr-c.c
@@ -128,6 +128,12 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
else
cpp_define (pfile, "__AVR_HAVE_16BIT_SP__");
+ if (avr_sp8)
+ cpp_define (pfile, "__AVR_SP8__");
+
+ if (AVR_HAVE_SPH)
+ cpp_define (pfile, "__AVR_HAVE_SPH__");
+
if (TARGET_NO_INTERRUPTS)
cpp_define (pfile, "__NO_INTERRUPTS__");
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 341fe9b2f85..c25f8983a79 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -963,7 +963,7 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
{
/* Don't error so that insane code from newlib still compiles
and does not break building newlib. As PR51345 is implemented
- now, there are multilib variants with -mtiny-stack.
+ now, there are multilib variants with -msp8.
If user wants sanity checks he can use -Wstack-usage=
or similar options.
@@ -2774,7 +2774,7 @@ output_movhi (rtx insn, rtx xop[], int *plen)
}
else if (test_hard_reg_class (STACK_REG, src))
{
- return AVR_HAVE_8BIT_SP
+ return !AVR_HAVE_SPH
? avr_asm_len ("in %A0,__SP_L__" CR_TAB
"clr %B0", xop, plen, -2)
@@ -7341,7 +7341,7 @@ avr_file_start (void)
/* Print I/O addresses of some SFRs used with IN and OUT. */
- if (!AVR_HAVE_8BIT_SP)
+ if (AVR_HAVE_SPH)
fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset);
fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
@@ -10285,6 +10285,42 @@ enum avr_builtin_id
AVR_BUILTIN_COUNT
};
+struct GTY(()) avr_builtin_description
+{
+ enum insn_code icode;
+ const char *name;
+ int n_args;
+ tree fndecl;
+};
+
+
+/* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
+ that a built-in's ID can be used to access the built-in by means of
+ avr_bdesc[ID] */
+
+static GTY(()) struct avr_builtin_description
+avr_bdesc[AVR_BUILTIN_COUNT] =
+ {
+
+#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, ICODE) \
+ { ICODE, NAME, N_ARGS, NULL_TREE },
+#include "builtins.def"
+#undef DEF_BUILTIN
+ };
+
+
+/* Implement `TARGET_BUILTIN_DECL'. */
+
+static tree
+avr_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
+{
+ if (id < AVR_BUILTIN_COUNT)
+ return avr_bdesc[id].fndecl;
+
+ return error_mark_node;
+}
+
+
static void
avr_init_builtin_int24 (void)
{
@@ -10295,6 +10331,7 @@ avr_init_builtin_int24 (void)
(*lang_hooks.types.register_builtin_type) (uint24_type, "__uint24");
}
+
/* Implement `TARGET_INIT_BUILTINS' */
/* Set up all builtin functions for this target. */
@@ -10348,7 +10385,9 @@ avr_init_builtins (void)
NULL);
#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, CODE) \
- add_builtin_function (NAME, TYPE, ID, BUILT_IN_MD, NULL, NULL_TREE);
+ gcc_assert (ID < AVR_BUILTIN_COUNT); \
+ avr_bdesc[ID].fndecl \
+ = add_builtin_function (NAME, TYPE, ID, BUILT_IN_MD, NULL, NULL_TREE);
#include "builtins.def"
#undef DEF_BUILTIN
@@ -10356,27 +10395,6 @@ avr_init_builtins (void)
}
-struct avr_builtin_description
-{
- enum insn_code icode;
- const char *name;
- enum avr_builtin_id id;
- int n_args;
-};
-
-static const struct avr_builtin_description
-avr_bdesc[] =
- {
-
-#define DEF_BUILTIN(NAME, N_ARGS, ID, TYPE, ICODE) \
- { ICODE, NAME, ID, N_ARGS },
-#include "builtins.def"
-#undef DEF_BUILTIN
-
- { CODE_FOR_nothing, NULL, 0, -1 }
- };
-
-
/* Subroutine of avr_expand_builtin to take care of unop insns. */
static rtx
@@ -10545,6 +10563,7 @@ avr_expand_triop_builtin (enum insn_code icode, tree exp, rtx target)
}
+/* Implement `TARGET_EXPAND_BUILTIN'. */
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
(and in mode MODE if that's convenient).
@@ -10557,13 +10576,15 @@ avr_expand_builtin (tree exp, rtx target,
enum machine_mode mode ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED)
{
- size_t i;
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
const char* bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
unsigned int id = DECL_FUNCTION_CODE (fndecl);
+ const struct avr_builtin_description *d = &avr_bdesc[id];
tree arg0;
rtx op0;
+ gcc_assert (id < AVR_BUILTIN_COUNT);
+
switch (id)
{
case AVR_BUILTIN_NOP:
@@ -10597,29 +10618,22 @@ avr_expand_builtin (tree exp, rtx target,
}
}
- for (i = 0; avr_bdesc[i].name; i++)
+ /* No special treatment needed: vanilla expand. */
+
+ switch (d->n_args)
{
- const struct avr_builtin_description *d = &avr_bdesc[i];
+ case 0:
+ emit_insn ((GEN_FCN (d->icode)) (target));
+ return 0;
- if (d->id == id)
- switch (d->n_args)
- {
- case 0:
- emit_insn ((GEN_FCN (d->icode)) (target));
- return 0;
-
- case 1:
- return avr_expand_unop_builtin (d->icode, exp, target);
-
- case 2:
- return avr_expand_binop_builtin (d->icode, exp, target);
-
- case 3:
- return avr_expand_triop_builtin (d->icode, exp, target);
-
- default:
- gcc_unreachable();
- }
+ case 1:
+ return avr_expand_unop_builtin (d->icode, exp, target);
+
+ case 2:
+ return avr_expand_binop_builtin (d->icode, exp, target);
+
+ case 3:
+ return avr_expand_triop_builtin (d->icode, exp, target);
}
gcc_unreachable ();
@@ -10878,6 +10892,9 @@ avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS avr_init_builtins
+#undef TARGET_BUILTIN_DECL
+#define TARGET_BUILTIN_DECL avr_builtin_decl
+
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN avr_expand_builtin
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 8488e15dcad..bd5241c9fad 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -188,7 +188,26 @@ enum
#define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm \
|| avr_current_arch->have_rampd)
#define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall)
-#define AVR_HAVE_8BIT_SP (avr_current_device->short_sp || TARGET_TINY_STACK)
+
+/* Handling of 8-bit SP versus 16-bit SP is as follows:
+
+ -msp8 is used internally to select the right multilib for targets with
+ 8-bit SP. -msp8 is set automatically by DRIVER_SELF_SPECS for devices
+ with 8-bit SP or by multilib generation machinery. If a frame pointer is
+ needed and SP is only 8 bits wide, SP is zero-extended to get FP.
+
+ TARGET_TINY_STACK is triggered by -mtiny-stack which is a user option.
+ This option has no effect on multilib selection. It serves to save some
+ bytes on 16-bit SP devices by only changing SP_L and leaving SP_H alone.
+
+ These two properties are reflected by built-in macros __AVR_SP8__ resp.
+ __AVR_HAVE_8BIT_SP__ and __AVR_HAVE_16BIT_SP__. During multilib generation
+ there is always __AVR_SP8__ == __AVR_HAVE_8BIT_SP__. */
+
+#define AVR_HAVE_8BIT_SP \
+ (avr_current_device->short_sp || TARGET_TINY_STACK || avr_sp8)
+
+#define AVR_HAVE_SPH (!avr_sp8)
#define AVR_2_BYTE_PC (!AVR_HAVE_EIJMP_EICALL)
#define AVR_3_BYTE_PC (AVR_HAVE_EIJMP_EICALL)
@@ -577,13 +596,16 @@ extern const char *avr_device_to_arch (int argc, const char **argv);
extern const char *avr_device_to_data_start (int argc, const char **argv);
extern const char *avr_device_to_startfiles (int argc, const char **argv);
extern const char *avr_device_to_devicelib (int argc, const char **argv);
+extern const char *avr_device_to_sp8 (int argc, const char **argv);
-#define EXTRA_SPEC_FUNCTIONS \
- { "device_to_arch", avr_device_to_arch }, \
+#define EXTRA_SPEC_FUNCTIONS \
+ { "device_to_arch", avr_device_to_arch }, \
{ "device_to_data_start", avr_device_to_data_start }, \
- { "device_to_startfile", avr_device_to_startfiles }, \
- { "device_to_devicelib", avr_device_to_devicelib },
+ { "device_to_startfile", avr_device_to_startfiles }, \
+ { "device_to_devicelib", avr_device_to_devicelib }, \
+ { "device_to_sp8", avr_device_to_sp8 },
+#define DRIVER_SELF_SPECS " %:device_to_sp8(%{mmcu=*:%*}) "
#define CPP_SPEC ""
#define CC1_SPEC ""
diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt
index d6e73ee0914..d4d6b7826d8 100644
--- a/gcc/config/avr/avr.opt
+++ b/gcc/config/avr/avr.opt
@@ -73,3 +73,7 @@ Accumulate outgoing function arguments and acquire/release the needed stack spac
mstrict-X
Target Report Var(avr_strict_X) Init(0)
When accessing RAM, use X as imposed by the hardware, i.e. just use pre-decrement, post-increment and indirect addressing with the X register. Without this option, the compiler may assume that there is an addressing mode X+const similar to Y+const and Z+const and emit instructions to emulate such an addressing mode for X.
+
+;; For rationale behind -msp8 see explanation in avr.h.
+msp8
+Target Report RejectNegative Undocumented Var(avr_sp8) Init(0)
diff --git a/gcc/config/avr/driver-avr.c b/gcc/config/avr/driver-avr.c
index 6ab0bb822ef..26c21412c3f 100644
--- a/gcc/config/avr/driver-avr.c
+++ b/gcc/config/avr/driver-avr.c
@@ -112,3 +112,24 @@ avr_device_to_devicelib (int argc, const char **argv)
return concat ("-l", avr_current_device->library_name, NULL);
}
+const char*
+avr_device_to_sp8 (int argc, const char **argv)
+{
+ if (0 == argc)
+ return NULL;
+
+ avr_set_current_device (argv[0]);
+
+ /* Leave "avr2" and "avr25" alone. These two architectures are
+ the only ones that mix devices with 8-bit SP and 16-bit SP.
+ -msp8 is set by mmultilib machinery. */
+
+ if (avr_current_device->macro == NULL
+ && (avr_current_device->arch == ARCH_AVR2
+ || avr_current_device->arch == ARCH_AVR25))
+ return "";
+
+ return avr_current_device->short_sp
+ ? "-msp8"
+ : "%<msp8";
+}
diff --git a/gcc/config/avr/genmultilib.awk b/gcc/config/avr/genmultilib.awk
index 7bc3b4af225..0aab49a407f 100644
--- a/gcc/config/avr/genmultilib.awk
+++ b/gcc/config/avr/genmultilib.awk
@@ -26,9 +26,6 @@
# FORMAT = "Makefile": Generate Makefile Snipet that sets some
# MULTILIB_* Variables as needed.
#
-# FORMAT = "multilib.h": Generate C Header intended to override
-# (parts of) multilib.h used in gcc.c.
-#
##################################################################
BEGIN {
@@ -41,7 +38,7 @@ BEGIN {
mtiny[0] = ""
mtiny[1] = "tiny-stack"
- option["tiny-stack"] = "mtiny-stack"
+ option["tiny-stack"] = "msp8"
}
##################################################################
@@ -54,18 +51,6 @@ BEGIN {
next
else if (comment == 1)
{
- if (FORMAT == "multilib.h")
- {
- print "/*"
- print " Auto-generated C header"
- print " Generated by : ./gcc/config/avr/genmultilib.awk"
- print " Generated from : ./gcc/config/avr/avr-mcus.def"
- print " Used by : ./gcc/gcc.c via tm.h"
- print " Purpose : Override multilib_raw[] from multilib.h"
- print "*/"
- print "/*"
- }
-
if (FORMAT == "Makefile")
{
print "# Auto-generated Makefile Snip"
@@ -78,15 +63,12 @@ BEGIN {
comment = 2;
- if (FORMAT == "multilib.h")
- gsub ("#", " ")
-
print
}
/^$/ {
- if (comment && FORMAT == "multilib.h")
- print "*/"
+ # The first empty line stops copy-pasting the GPL comments
+ # from this file to the generated file.
comment = 0
}
@@ -144,7 +126,6 @@ BEGIN {
# m_dirnames <-> MULTILIB_DIRNAMES "
# m_exceptions <-> MULTILIB_EXCEPTIONS "
# m_matches <-> MULTILIB_MATCHES "
-# m_raw <-> avr_multilib_raw multilib.h
#
##################################################################
@@ -154,11 +135,9 @@ END {
m_exceptions = "\nMULTILIB_EXCEPTIONS ="
m_matches = "\nMULTILIB_MATCHES ="
- m_raw = ""
-
##############################################################
# Compose MULTILIB_OPTIONS. This represents the Cross-Product
- # (avr2, avr25, ...) x mtiny-stack
+ # (avr2, avr25, ...) x msp8
sep = ""
for (c = 0; c < n_cores; c++)
@@ -167,54 +146,25 @@ END {
sep = "/"
}
- # The ... x mtiny-stack
+ # The ... x msp8
m_options = m_options " " option[mtiny[1]]
##############################################################
# Map Device to its multilib
- # All Mappings that cannot be represented by GCC's genmultilib
- # Machinery must be handcrafted.
-
- dot_excludes = ""
- m_raw_sp8 = ""
-
for (t = 0; t < n_mcu; t++)
{
core = toCore[mcu[t]]
- if (tiny_stack[mcu[t]] == 1)
- {
- if (core == "avr2")
- dir = mtiny[1]
- else
- dir = core "/" mtiny[1]
-
- m_raw_sp8 = m_raw_sp8 " \"" dir " " option[mcu[t]] ";\",\n"
- dot_excludes = dot_excludes " !" option[mcu[t]]
-
- line = option[mcu[t]] ":" option[mcu[t]]
- gsub ("=", "?", line)
- gsub (":", "=", line)
-
- m_matches = m_matches " \\\n\t" line
- }
+ line = option[core] ":" option[mcu[t]]
+ gsub ("=", "?", line)
+ gsub (":", "=", line)
- # The SP = 16 Devices are vanilla: Do the same as
- # MULTILIB_MATCHES would yield. Don't list avr2 (default)
-
- if (core != "avr2")
- {
- line = option[core] ":" option[mcu[t]]
- gsub ("=", "?", line)
- gsub (":", "=", line)
-
- m_matches = m_matches " \\\n\t" line
- }
+ m_matches = m_matches " \\\n\t" line
}
####################################################################
- # Compose MULTILIB_DIRNAMES, MULTILIB_EXEPTIONS and avr_multilib_raw
+ # Compose MULTILIB_DIRNAMES and MULTILIB_EXEPTIONS
n_mtiny = 2
for (t = 0; t < n_mtiny; t++)
@@ -248,38 +198,6 @@ END {
if (core != "avr2" || mtiny[t] == "")
m_dirnames = m_dirnames " " mdir
-
- # Remainder deals with avr_multilib_raw Entries.
- # Each Entry looks like
- # "multilib-dir option-to-match !option-to-avoid-match;"
- # for Example:
- # "avr25/tiny-stack !mmcu=avr2 mmcu=avr25 !mmcu=avr3 ... mtiny-stack;"
-
- if (mdir == "")
- mdir = "."
-
- line = mdir
-
- for (s = 0; s < n_cores; s++)
- {
- if (cores[s] == core)
- line = line " " option[cores[s]]
- else
- line = line " !" option[cores[s]]
- }
-
- if (tiny_stack[core] != 0)
- {
- if (mtiny[t] == "")
- line = line " !" option[mtiny[1]]
- else
- line = line " " option[mtiny[1]]
- }
-
- if (mdir == ".")
- line = line dot_excludes
-
- m_raw = m_raw " \"" line ";\",\n"
}
############################################################
@@ -295,21 +213,4 @@ END {
print m_exceptions
print m_matches
}
-
- if (FORMAT == "multilib.h")
- {
- # Intended Target: ./gcc/config/avr/multilib.h
-
- print "#if defined NULL && !defined AVR_MULTILIB_H"
- print "#define AVR_MULTILIB_H"
-
- print "static const char* const avr_multilib_raw[] = {"
- print m_raw_sp8
- print m_raw
- print " NULL\n};"
-
- print "#undef multilib_raw"
- print "#define multilib_raw avr_multilib_raw"
- print "#endif /* AVR_MULTILIB_H */"
- }
}
diff --git a/gcc/config/avr/multilib.h b/gcc/config/avr/multilib.h
deleted file mode 100644
index 582c6dae6f7..00000000000
--- a/gcc/config/avr/multilib.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- Auto-generated C header
- Generated by : ./gcc/config/avr/genmultilib.awk
- Generated from : ./gcc/config/avr/avr-mcus.def
- Used by : ./gcc/gcc.c via tm.h
- Purpose : Override multilib_raw[] from multilib.h
-*/
-/*
- Copyright (C) 2011 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/>.
-*/
-#if defined NULL && !defined AVR_MULTILIB_H
-#define AVR_MULTILIB_H
-static const char* const avr_multilib_raw[] = {
- "tiny-stack mmcu=at90s2313;",
- "tiny-stack mmcu=at90s2323;",
- "tiny-stack mmcu=at90s2333;",
- "tiny-stack mmcu=at90s2343;",
- "tiny-stack mmcu=attiny22;",
- "tiny-stack mmcu=attiny26;",
- "tiny-stack mmcu=at90s4433;",
- "avr25/tiny-stack mmcu=attiny13;",
- "avr25/tiny-stack mmcu=attiny13a;",
- "avr25/tiny-stack mmcu=attiny2313;",
- "avr25/tiny-stack mmcu=attiny2313a;",
- "avr25/tiny-stack mmcu=attiny24;",
- "avr25/tiny-stack mmcu=attiny24a;",
- "avr25/tiny-stack mmcu=attiny25;",
- "avr25/tiny-stack mmcu=attiny261;",
- "avr25/tiny-stack mmcu=attiny261a;",
-
- ". !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 !mtiny-stack !mmcu=at90s2313 !mmcu=at90s2323 !mmcu=at90s2333 !mmcu=at90s2343 !mmcu=attiny22 !mmcu=attiny26 !mmcu=at90s4433 !mmcu=attiny13 !mmcu=attiny13a !mmcu=attiny2313 !mmcu=attiny2313a !mmcu=attiny24 !mmcu=attiny24a !mmcu=attiny25 !mmcu=attiny261 !mmcu=attiny261a;",
- "avr2 mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 !mtiny-stack;",
- "avr25 !mmcu=avr2 mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 !mtiny-stack;",
- "avr3 !mmcu=avr2 !mmcu=avr25 mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avr31 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avr35 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avr4 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avr5 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avr51 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avr6 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avrxmega2 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avrxmega4 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avrxmega5 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avrxmega6 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 mmcu=avrxmega6 !mmcu=avrxmega7;",
- "avrxmega7 !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 mmcu=avrxmega7;",
- "tiny-stack !mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 mtiny-stack;",
- "avr2/tiny-stack mmcu=avr2 !mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 mtiny-stack;",
- "avr25/tiny-stack !mmcu=avr2 mmcu=avr25 !mmcu=avr3 !mmcu=avr31 !mmcu=avr35 !mmcu=avr4 !mmcu=avr5 !mmcu=avr51 !mmcu=avr6 !mmcu=avrxmega2 !mmcu=avrxmega4 !mmcu=avrxmega5 !mmcu=avrxmega6 !mmcu=avrxmega7 mtiny-stack;",
-
- NULL
-};
-#undef multilib_raw
-#define multilib_raw avr_multilib_raw
-#endif /* AVR_MULTILIB_H */
diff --git a/gcc/config/avr/t-avr b/gcc/config/avr/t-avr
index e6b4adee182..99638333204 100644
--- a/gcc/config/avr/t-avr
+++ b/gcc/config/avr/t-avr
@@ -49,16 +49,10 @@ $(srcdir)/config/avr/avr-tables.opt: $(srcdir)/config/avr/genopt.sh $(AVR_MCUS)
# MULTILIB_MATCHES
$(srcdir)/config/avr/t-multilib: s-avr-mlib; @true
-# Override multilib_raw[] from multilib.h
-$(srcdir)/config/avr/multilib.h: s-avr-mlib; @true
-
s-mlib: $(srcdir)/config/avr/t-multilib
s-avr-mlib: $(srcdir)/config/avr/genmultilib.awk $(AVR_MCUS)
$(AWK) -f $< -v FORMAT=Makefile $< $(AVR_MCUS) > tmp-avr-mlib
- $(AWK) -f $< -v FORMAT=multilib.h $< $(AVR_MCUS) > tmp-avr-mlib.h
- $(SHELL) $(srcdir)/../move-if-change \
- tmp-avr-mlib.h $(srcdir)/config/avr/multilib.h
$(SHELL) $(srcdir)/../move-if-change \
tmp-avr-mlib $(srcdir)/config/avr/t-multilib
$(STAMP) $@
diff --git a/gcc/config/avr/t-multilib b/gcc/config/avr/t-multilib
index 886d5507c5c..497f63b4ea8 100644
--- a/gcc/config/avr/t-multilib
+++ b/gcc/config/avr/t-multilib
@@ -21,57 +21,53 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7 mtiny-stack
+MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7 msp8
MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack avr25/tiny-stack
MULTILIB_EXCEPTIONS = \
- mmcu=avr3/mtiny-stack \
- mmcu=avr31/mtiny-stack \
- mmcu=avr35/mtiny-stack \
- mmcu=avr4/mtiny-stack \
- mmcu=avr5/mtiny-stack \
- mmcu=avr51/mtiny-stack \
- mmcu=avr6/mtiny-stack \
- mmcu=avrxmega2/mtiny-stack \
- mmcu=avrxmega4/mtiny-stack \
- mmcu=avrxmega5/mtiny-stack \
- mmcu=avrxmega6/mtiny-stack \
- mmcu=avrxmega7/mtiny-stack
+ mmcu=avr3/msp8 \
+ mmcu=avr31/msp8 \
+ mmcu=avr35/msp8 \
+ mmcu=avr4/msp8 \
+ mmcu=avr5/msp8 \
+ mmcu=avr51/msp8 \
+ mmcu=avr6/msp8 \
+ mmcu=avrxmega2/msp8 \
+ mmcu=avrxmega4/msp8 \
+ mmcu=avrxmega5/msp8 \
+ mmcu=avrxmega6/msp8 \
+ mmcu=avrxmega7/msp8
MULTILIB_MATCHES = \
- mmcu?at90s2313=mmcu?at90s2313 \
- mmcu?at90s2323=mmcu?at90s2323 \
- mmcu?at90s2333=mmcu?at90s2333 \
- mmcu?at90s2343=mmcu?at90s2343 \
- mmcu?attiny22=mmcu?attiny22 \
- mmcu?attiny26=mmcu?attiny26 \
- mmcu?at90s4433=mmcu?at90s4433 \
+ mmcu?avr2=mmcu?at90s2313 \
+ mmcu?avr2=mmcu?at90s2323 \
+ mmcu?avr2=mmcu?at90s2333 \
+ mmcu?avr2=mmcu?at90s2343 \
+ mmcu?avr2=mmcu?attiny22 \
+ mmcu?avr2=mmcu?attiny26 \
+ mmcu?avr2=mmcu?at90s4414 \
+ mmcu?avr2=mmcu?at90s4433 \
+ mmcu?avr2=mmcu?at90s4434 \
+ mmcu?avr2=mmcu?at90s8515 \
+ mmcu?avr2=mmcu?at90c8534 \
+ mmcu?avr2=mmcu?at90s8535 \
mmcu?avr25=mmcu?ata6289 \
- mmcu?attiny13=mmcu?attiny13 \
mmcu?avr25=mmcu?attiny13 \
- mmcu?attiny13a=mmcu?attiny13a \
mmcu?avr25=mmcu?attiny13a \
- mmcu?attiny2313=mmcu?attiny2313 \
mmcu?avr25=mmcu?attiny2313 \
- mmcu?attiny2313a=mmcu?attiny2313a \
mmcu?avr25=mmcu?attiny2313a \
- mmcu?attiny24=mmcu?attiny24 \
mmcu?avr25=mmcu?attiny24 \
- mmcu?attiny24a=mmcu?attiny24a \
mmcu?avr25=mmcu?attiny24a \
mmcu?avr25=mmcu?attiny4313 \
mmcu?avr25=mmcu?attiny44 \
mmcu?avr25=mmcu?attiny44a \
mmcu?avr25=mmcu?attiny84 \
mmcu?avr25=mmcu?attiny84a \
- mmcu?attiny25=mmcu?attiny25 \
mmcu?avr25=mmcu?attiny25 \
mmcu?avr25=mmcu?attiny45 \
mmcu?avr25=mmcu?attiny85 \
- mmcu?attiny261=mmcu?attiny261 \
mmcu?avr25=mmcu?attiny261 \
- mmcu?attiny261a=mmcu?attiny261a \
mmcu?avr25=mmcu?attiny261a \
mmcu?avr25=mmcu?attiny461 \
mmcu?avr25=mmcu?attiny461a \
diff --git a/gcc/config/cris/linux.opt b/gcc/config/cris/linux.opt
index a57c48d7ce8..e93bb53a6fd 100644
--- a/gcc/config/cris/linux.opt
+++ b/gcc/config/cris/linux.opt
@@ -23,7 +23,7 @@ mlinux
Target Report RejectNegative Undocumented
mno-gotplt
-Target Report RejectNegative Mask(AVOID_GOTPLT) MaskExists
+Target Report RejectNegative Mask(AVOID_GOTPLT)
Together with -fpic and -fPIC, do not use GOTPLT references
; There's a small added setup cost with using GOTPLT references
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index aeac904031c..428a86a316c 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -96,6 +96,7 @@ extern int h8300_can_use_return_insn_p (void);
extern void h8300_expand_prologue (void);
extern void h8300_expand_epilogue (void);
extern int h8300_current_function_interrupt_function_p (void);
+extern int h8300_current_function_monitor_function_p (void);
extern int h8300_initial_elimination_offset (int, int);
extern int h8300_regs_ok_for_stm (int, rtx[]);
extern int h8300_hard_regno_rename_ok (unsigned int, unsigned int);
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 3911cd4dda4..7eaaf202f00 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -316,6 +316,14 @@ h8300_option_override (void)
static const char *const h8_pop_ops[2] = { "pop" , "pop.l" };
static const char *const h8_mov_ops[2] = { "mov.w", "mov.l" };
+#ifndef OBJECT_FORMAT_ELF
+ if (TARGET_H8300SX)
+ {
+ error ("-msx is not supported in coff");
+ target_flags |= MASK_H8300S;
+ }
+#endif
+
if (TARGET_H8300)
{
cpu_type = (int) CPU_H8300;
@@ -339,10 +347,34 @@ h8300_option_override (void)
if (TARGET_H8300 && TARGET_NORMAL_MODE)
{
- error ("-mn is used without -mh or -ms");
+ error ("-mn is used without -mh or -ms or -msx");
target_flags ^= MASK_NORMAL_MODE;
}
+ if (! TARGET_H8300S && TARGET_EXR)
+ {
+ error ("-mexr is used without -ms");
+ target_flags |= MASK_H8300S_1;
+ }
+
+ if (TARGET_H8300 && TARGET_INT32)
+ {
+ error ("-mint32 is not supported for H8300 and H8300L targets");
+ target_flags ^= MASK_INT32;
+ }
+
+ if ((!TARGET_H8300S && TARGET_EXR) && (!TARGET_H8300SX && TARGET_EXR))
+ {
+ error ("-mexr is used without -ms or -msx");
+ target_flags |= MASK_H8300S_1;
+ }
+
+ if ((!TARGET_H8300S && TARGET_NEXR) && (!TARGET_H8300SX && TARGET_NEXR))
+ {
+ warning (OPT_mno_exr, "-mno-exr valid only with -ms or -msx \
+ - Option ignored!");
+ }
+
/* Some of the shifts are optimized for speed by default.
See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html
If optimizing for size, change shift_alg for those shift to
@@ -795,9 +827,9 @@ h8300_expand_prologue (void)
return;
if (h8300_monitor_function_p (current_function_decl))
- /* My understanding of monitor functions is they act just like
- interrupt functions, except the prologue must mask
- interrupts. */
+ /* The monitor function act as normal functions, which means it
+ can accept parameters and return values. In addition to this,
+ interrupts are masked in prologue and return with "rte" in epilogue. */
emit_insn (gen_monitor_prologue ());
if (frame_pointer_needed)
@@ -925,8 +957,13 @@ h8300_expand_epilogue (void)
int
h8300_current_function_interrupt_function_p (void)
{
- return (h8300_interrupt_function_p (current_function_decl)
- || h8300_monitor_function_p (current_function_decl));
+ return (h8300_interrupt_function_p (current_function_decl));
+}
+
+int
+h8300_current_function_monitor_function_p ()
+{
+ return (h8300_monitor_function_p (current_function_decl));
}
/* Output assembly code for the start of the file. */
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index bf41e6669a6..df983e13634 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -2609,7 +2609,8 @@
{
operands[3] = SET_DEST (XVECEXP (operands[0], 0,
XVECLEN (operands[0], 0) - 2));
- if (h8300_current_function_interrupt_function_p ())
+ if (h8300_current_function_interrupt_function_p ()
+ || h8300_current_function_monitor_function_p ())
return "rte/l\t%S1-%S3";
else
return "rts/l\t%S1-%S3";
@@ -2628,7 +2629,8 @@
"reload_completed"
"*
{
- if (h8300_current_function_interrupt_function_p ())
+ if (h8300_current_function_interrupt_function_p ()
+ || h8300_current_function_monitor_function_p ())
return \"rte\";
else
return \"rts\";
@@ -2654,8 +2656,16 @@
{
if (TARGET_H8300)
return \"subs\\t#2,r7\;mov.w\\tr0,@-r7\;stc\\tccr,r0l\;mov.b\tr0l,@(2,r7)\;mov.w\\t@r7+,r0\;orc\t#128,ccr\";
+ else if (TARGET_H8300H && TARGET_NORMAL_MODE)
+ return \"subs\\t#2,er7\;mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr\";
else if (TARGET_H8300H)
return \"mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr\";
+ else if (TARGET_H8300S && TARGET_NEXR )
+ return \"mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr\";
+ else if (TARGET_H8300S && TARGET_NEXR && TARGET_NORMAL_MODE)
+ return \"subs\\t#2,er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr\";
+ else if (TARGET_H8300S && TARGET_NORMAL_MODE)
+ return \"subs\\t#2,er7\;stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr\";
else if (TARGET_H8300S)
return \"stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr\";
gcc_unreachable ();
@@ -6199,3 +6209,5 @@
&& !reg_overlap_mentioned_p (operands[0], operands[2])"
[(set (match_dup 2)
(match_dup 1))])
+
+
diff --git a/gcc/config/h8300/h8300.opt b/gcc/config/h8300/h8300.opt
index 989375e152c..16c6ef5e029 100644
--- a/gcc/config/h8300/h8300.opt
+++ b/gcc/config/h8300/h8300.opt
@@ -60,3 +60,12 @@ Enable the normal mode
malign-300
Target RejectNegative Mask(ALIGN_300)
Use H8/300 alignment rules
+
+mexr
+Target Mask(EXR)
+Push extended registers on stack in monitor functions
+
+mno-exr
+Target Mask(NEXR)
+Do not push extended registers on stack in monitor functions
+
diff --git a/gcc/config/i386/biarch64.h b/gcc/config/i386/biarch64.h
index 629ec980d19..0c3811e3f33 100644
--- a/gcc/config/i386/biarch64.h
+++ b/gcc/config/i386/biarch64.h
@@ -25,5 +25,5 @@ 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
+#define TARGET_64BIT_DEFAULT (OPTION_MASK_ISA_64BIT | OPTION_MASK_ABI_64)
#define TARGET_BI_ARCH 1
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/gnu-user64.h b/gcc/config/i386/gnu-user64.h
index 954f3b2ff24..6f7b5de2ab8 100644
--- a/gcc/config/i386/gnu-user64.h
+++ b/gcc/config/i386/gnu-user64.h
@@ -58,8 +58,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if TARGET_64BIT_DEFAULT
#define SPEC_32 "m32"
+#if TARGET_BI_ARCH == 2
+#define SPEC_64 "m64"
+#define SPEC_X32 "m32|m64:;"
+#else
#define SPEC_64 "m32|mx32:;"
#define SPEC_X32 "mx32"
+#endif
#else
#define SPEC_32 "m64|mx32:;"
#define SPEC_64 "m64"
@@ -95,7 +100,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
#if TARGET_64BIT_DEFAULT
+#if TARGET_BI_ARCH == 2
+#define MULTILIB_DEFAULTS { "mx32" }
+#else
#define MULTILIB_DEFAULTS { "m64" }
+#endif
#else
#define MULTILIB_DEFAULTS { "m32" }
#endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index f37eb54a184..8384231e1d1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2657,7 +2657,6 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
preceding options while match those first. */
static struct ix86_target_opts isa_opts[] =
{
- { "-m64", OPTION_MASK_ISA_64BIT },
{ "-mfma4", OPTION_MASK_ISA_FMA4 },
{ "-mfma", OPTION_MASK_ISA_FMA },
{ "-mxop", OPTION_MASK_ISA_XOP },
@@ -2730,6 +2729,7 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
size_t len;
size_t line_len;
size_t sep_len;
+ const char *abi;
memset (opts, '\0', sizeof (opts));
@@ -2747,6 +2747,21 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
opts[num++][1] = tune;
}
+ /* Add -m32/-m64/-mx32. */
+ if ((isa & OPTION_MASK_ISA_64BIT) != 0)
+ {
+ if ((isa & OPTION_MASK_ABI_64) != 0)
+ abi = "-m64";
+ else
+ abi = "-mx32";
+ isa &= ~ (OPTION_MASK_ISA_64BIT
+ | OPTION_MASK_ABI_64
+ | OPTION_MASK_ABI_X32);
+ }
+ else
+ abi = "-m32";
+ opts[num++][0] = abi;
+
/* Pick out the options in isa options. */
for (i = 0; i < ARRAY_SIZE (isa_opts); i++)
{
@@ -3102,8 +3117,45 @@ ix86_option_override_internal (bool main_args_p)
SUBSUBTARGET_OVERRIDE_OPTIONS;
#endif
+ /* Turn off both OPTION_MASK_ABI_64 and OPTION_MASK_ABI_X32 if
+ 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
+ {
+#if TARGET_BI_ARCH == 1
+ /* When TARGET_BI_ARCH == 1, by default, OPTION_MASK_ABI_64
+ is on and OPTION_MASK_ABI_X32 is off. We turn off
+ OPTION_MASK_ABI_64 if OPTION_MASK_ABI_X32 is turned on by
+ -mx32. */
+ if (TARGET_X32)
+ ix86_isa_flags &= ~OPTION_MASK_ABI_64;
+#else
+ /* When TARGET_BI_ARCH == 2, by default, OPTION_MASK_ABI_X32 is
+ on and OPTION_MASK_ABI_64 is off. We turn off
+ OPTION_MASK_ABI_X32 if OPTION_MASK_ABI_64 is turned on by
+ -m64. */
+ if (TARGET_LP64)
+ ix86_isa_flags &= ~OPTION_MASK_ABI_X32;
+#endif
+ }
+#endif
+
if (TARGET_X32)
- ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
+ {
+ /* Always turn on OPTION_MASK_ISA_64BIT and turn off
+ OPTION_MASK_ABI_64 for TARGET_X32. */
+ ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
+ ix86_isa_flags &= ~OPTION_MASK_ABI_64;
+ }
+ else if (TARGET_LP64)
+ {
+ /* Always turn on OPTION_MASK_ISA_64BIT and turn off
+ OPTION_MASK_ABI_X32 for TARGET_LP64. */
+ ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
+ ix86_isa_flags &= ~OPTION_MASK_ABI_X32;
+ }
/* -fPIC is the default for x86_64. */
if (TARGET_MACHO && TARGET_64BIT)
@@ -15823,17 +15875,18 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
switch (GET_MODE_SIZE (mode))
{
case 16:
- /* If we're optimizing for size, movups is the smallest. */
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
{
op0 = gen_lowpart (V4SFmode, op0);
op1 = gen_lowpart (V4SFmode, op1);
emit_insn (gen_sse_movups (op0, op1));
- return;
}
- op0 = gen_lowpart (V16QImode, op0);
- op1 = gen_lowpart (V16QImode, op1);
- emit_insn (gen_sse2_movdqu (op0, op1));
+ else
+ {
+ op0 = gen_lowpart (V16QImode, op0);
+ op1 = gen_lowpart (V16QImode, op1);
+ emit_insn (gen_sse2_movdqu (op0, op1));
+ }
break;
case 32:
op0 = gen_lowpart (V32QImode, op0);
@@ -15845,27 +15898,22 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
}
break;
case MODE_VECTOR_FLOAT:
- op0 = gen_lowpart (mode, op0);
- op1 = gen_lowpart (mode, op1);
-
switch (mode)
{
case V4SFmode:
emit_insn (gen_sse_movups (op0, op1));
break;
- case V8SFmode:
- ix86_avx256_split_vector_move_misalign (op0, op1);
- break;
case V2DFmode:
if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
{
op0 = gen_lowpart (V4SFmode, op0);
op1 = gen_lowpart (V4SFmode, op1);
emit_insn (gen_sse_movups (op0, op1));
- return;
}
- emit_insn (gen_sse2_movupd (op0, op1));
+ else
+ emit_insn (gen_sse2_movupd (op0, op1));
break;
+ case V8SFmode:
case V4DFmode:
ix86_avx256_split_vector_move_misalign (op0, op1);
break;
@@ -15910,8 +15958,6 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
if (TARGET_SSE_UNALIGNED_LOAD_OPTIMAL)
{
- op0 = gen_lowpart (V2DFmode, op0);
- op1 = gen_lowpart (V2DFmode, op1);
emit_insn (gen_sse2_movupd (op0, op1));
return;
}
@@ -15976,8 +16022,8 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
return;
}
- /* ??? Similar to above, only less clear because of quote
- typeless stores unquote. */
+ /* ??? Similar to above, only less clear
+ because of typeless stores. */
if (TARGET_SSE2 && !TARGET_SSE_TYPELESS_STORES
&& GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
{
@@ -15990,11 +16036,7 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
if (TARGET_SSE2 && mode == V2DFmode)
{
if (TARGET_SSE_UNALIGNED_STORE_OPTIMAL)
- {
- op0 = gen_lowpart (V2DFmode, op0);
- op1 = gen_lowpart (V2DFmode, op1);
- emit_insn (gen_sse2_movupd (op0, op1));
- }
+ emit_insn (gen_sse2_movupd (op0, op1));
else
{
m = adjust_address (op0, DFmode, 0);
@@ -31391,6 +31433,10 @@ ix86_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
/* If MODE2 is only appropriate for an SSE register, then tie with
any other mode acceptable to SSE registers. */
+ if (GET_MODE_SIZE (mode2) == 32
+ && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
+ return (GET_MODE_SIZE (mode1) == 32
+ && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
if (GET_MODE_SIZE (mode2) == 16
&& ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
return (GET_MODE_SIZE (mode1) == 16
@@ -32884,6 +32930,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;
};
@@ -32984,6 +33031,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);
@@ -35681,7 +35729,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)
;
@@ -35868,7 +35916,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. */
@@ -35944,7 +35992,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)
{
@@ -36032,7 +36080,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;
@@ -36059,7 +36107,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));
@@ -36091,7 +36139,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;
@@ -36188,7 +36236,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)
{
@@ -36231,7 +36279,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. */
@@ -36303,6 +36351,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)
@@ -36342,14 +36391,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;
@@ -36474,11 +36523,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);
@@ -36517,7 +36566,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)
@@ -36574,6 +36623,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
@@ -36617,7 +36667,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;
@@ -36645,6 +36695,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;
@@ -36658,6 +36709,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)
@@ -36697,8 +36749,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
@@ -36767,10 +36818,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;
@@ -36791,9 +36839,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;
}
@@ -36810,7 +36857,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)
;
@@ -36893,7 +36940,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;
@@ -36931,6 +36978,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;
@@ -36955,7 +37003,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));
@@ -37010,7 +37058,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;
@@ -37078,7 +37126,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;
@@ -37437,7 +37485,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];
@@ -37460,7 +37508,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;
@@ -37661,6 +37709,7 @@ ix86_expand_vec_perm_const (rtx operands[4])
perm[i] = ei;
}
+ d.one_operand_p = true;
switch (which)
{
default:
@@ -37668,51 +37717,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;
@@ -37726,7 +37763,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);
@@ -37763,17 +37800,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 ();
@@ -37794,6 +37831,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/i386.h b/gcc/config/i386/i386.h
index a53c70a31dc..7ba90c764f9 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -42,7 +42,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* Redefines for option macros. */
#define TARGET_64BIT OPTION_ISA_64BIT
-#define TARGET_X32 OPTION_ISA_X32
#define TARGET_MMX OPTION_ISA_MMX
#define TARGET_3DNOW OPTION_ISA_3DNOW
#define TARGET_3DNOW_A OPTION_ISA_3DNOW_A
@@ -77,7 +76,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_F16C OPTION_ISA_F16C
#define TARGET_RTM OPTION_ISA_RTM
-#define TARGET_LP64 (TARGET_64BIT && !TARGET_X32)
+#define TARGET_LP64 OPTION_ABI_64
+#define TARGET_X32 OPTION_ABI_X32
/* SSE4.1 defines round instructions */
#define OPTION_MASK_ISA_ROUND OPTION_MASK_ISA_SSE4_1
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 29f1082b2d1..bf50aed47a8 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -218,7 +218,7 @@ EnumValue
Enum(fpmath_unit) String(both) Value({(enum fpmath_unit) (FPMATH_SSE | FPMATH_387)})
mhard-float
-Target RejectNegative Mask(80387) MaskExists Save
+Target RejectNegative Mask(80387) Save
Use hardware fp
mieee-fp
@@ -425,11 +425,11 @@ Target RejectNegative Negative(m64) Report InverseMask(ISA_64BIT) Var(ix86_isa_f
Generate 32bit i386 code
m64
-Target RejectNegative Negative(mx32) Report Mask(ISA_64BIT) Var(ix86_isa_flags) Save
+Target RejectNegative Negative(mx32) Report Mask(ABI_64) Var(ix86_isa_flags) Save
Generate 64bit x86-64 code
mx32
-Target RejectNegative Negative(m32) Report Mask(ISA_X32) Var(ix86_isa_flags) Save
+Target RejectNegative Negative(m32) Report Mask(ABI_X32) Var(ix86_isa_flags) Save
Generate 32bit x86-64 code
mmmx
@@ -469,11 +469,11 @@ Target Report Mask(ISA_SSE4_2) Var(ix86_isa_flags) Save
Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 built-in functions and code generation
msse4
-Target RejectNegative Report Mask(ISA_SSE4_2) MaskExists Var(ix86_isa_flags) Save
+Target RejectNegative Report Mask(ISA_SSE4_2) Var(ix86_isa_flags) Save
Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 built-in functions and code generation
mno-sse4
-Target RejectNegative Report InverseMask(ISA_SSE4_1) MaskExists Var(ix86_isa_flags) Save
+Target RejectNegative Report InverseMask(ISA_SSE4_1) Var(ix86_isa_flags) Save
Do not support SSE4.1 and SSE4.2 built-in functions and code generation
msse5
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 9a4728c0092..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)]))))))]
@@ -4901,7 +4901,7 @@
(vec_select:DF (match_dup 0) (parallel [(const_int 1)]))))]
"TARGET_SSE2 && reload_completed"
[(set (match_dup 0) (match_dup 1))]
- "operands[0] = adjust_address (operands[0], DFmode, 8);")
+ "operands[0] = adjust_address (operands[0], DFmode, 0);")
(define_insn "sse2_movsd"
[(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,x,m,x,x,x,o")
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/linux-android.h b/gcc/config/linux-android.h
index 94c52748fdb..acbc6627f95 100644
--- a/gcc/config/linux-android.h
+++ b/gcc/config/linux-android.h
@@ -53,8 +53,8 @@
"%{!static: -ldl}"
#define ANDROID_STARTFILE_SPEC \
- "%{!shared:" \
+ "%{shared: crtbegin_so%O%s;:" \
" %{static: crtbegin_static%O%s;: crtbegin_dynamic%O%s}}"
#define ANDROID_ENDFILE_SPEC \
- "%{!shared: crtend_android%O%s}"
+ "%{shared: crtend_so%O%s;: crtend_android%O%s}"
diff --git a/gcc/config/m68k/m68k.opt b/gcc/config/m68k/m68k.opt
index 14428fc4ccc..00bc2d541ef 100644
--- a/gcc/config/m68k/m68k.opt
+++ b/gcc/config/m68k/m68k.opt
@@ -136,7 +136,7 @@ Target RejectNegative
Generate code for a Fido A
mhard-float
-Target RejectNegative Mask(HARD_FLOAT) MaskExists
+Target RejectNegative Mask(HARD_FLOAT)
Generate code which uses hardware floating point instructions
mid-shared-library
diff --git a/gcc/config/mep/mep.opt b/gcc/config/mep/mep.opt
index 38b8f80527b..0ea19e6efaa 100644
--- a/gcc/config/mep/mep.opt
+++ b/gcc/config/mep/mep.opt
@@ -55,7 +55,7 @@ Target Mask(COP)
Enable MeP Coprocessor
mcop32
-Target Mask(COP) MaskExists RejectNegative
+Target Mask(COP) RejectNegative
Enable MeP Coprocessor with 32-bit registers
mcop64
diff --git a/gcc/config/pa/pa-hpux.opt b/gcc/config/pa/pa-hpux.opt
index ed5d6a4bd79..b709b83bf40 100644
--- a/gcc/config/pa/pa-hpux.opt
+++ b/gcc/config/pa/pa-hpux.opt
@@ -23,7 +23,7 @@ Variable
int flag_pa_unix = TARGET_HPUX_11_31 ? 2003 : TARGET_HPUX_11_11 ? 1998 : TARGET_HPUX_10_10 ? 1995 : 1993
msio
-Target RejectNegative Mask(SIO) MaskExists
+Target RejectNegative Mask(SIO)
Generate cpp defines for server IO
munix=93
diff --git a/gcc/config/pa/pa64-hpux.opt b/gcc/config/pa/pa64-hpux.opt
index 36b1c61ea88..56ca35ea9c6 100644
--- a/gcc/config/pa/pa64-hpux.opt
+++ b/gcc/config/pa/pa64-hpux.opt
@@ -19,7 +19,7 @@
; <http://www.gnu.org/licenses/>.
mgnu-ld
-Target RejectNegative Mask(GNU_LD) MaskExists
+Target RejectNegative Mask(GNU_LD)
Assume code will be linked by GNU ld
mhp-ld
diff --git a/gcc/config/picochip/picochip.opt b/gcc/config/picochip/picochip.opt
index 4726f499377..a4b25e52f50 100644
--- a/gcc/config/picochip/picochip.opt
+++ b/gcc/config/picochip/picochip.opt
@@ -43,4 +43,4 @@ Target Mask(INEFFICIENT_WARNINGS)
Generate warnings when inefficient code is known to be generated.
minefficient
-Target Mask(INEFFICIENT_WARNINGS) MaskExists Undocumented
+Target Mask(INEFFICIENT_WARNINGS) Undocumented
diff --git a/gcc/config/rs6000/sysv4.opt b/gcc/config/rs6000/sysv4.opt
index 0d8d955af12..474203d6adb 100644
--- a/gcc/config/rs6000/sysv4.opt
+++ b/gcc/config/rs6000/sysv4.opt
@@ -66,7 +66,7 @@ Target Report RejectNegative Mask(LITTLE_ENDIAN)
Produce little endian code
mlittle
-Target Report RejectNegative Mask(LITTLE_ENDIAN) MaskExists
+Target Report RejectNegative Mask(LITTLE_ENDIAN)
Produce little endian code
mbig-endian
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 68e6034203c..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);
@@ -9783,13 +9787,80 @@ legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
return orig;
}
-/* Try machine-dependent ways of modifying an illegitimate address
- to be legitimate. If we find one, return the new, valid address.
- Otherwise, return X.
+/* Given a (logical) mode size and an offset in bytes, try to find a the
+ appropriate displacement value for a mov insn. On SH the displacements
+ are limited to max. 60 bytes for SImode, max. 30 bytes in HImode and max.
+ 15 bytes in QImode. To compensate this we create a new base address by
+ adding an adjustment value to it.
+
+ If the originally requested offset is greater than 127 we prefer using
+ values 124..127 over 128..131 to increase opportunities to use the
+ add #imm, Rn insn.
+
+ In some cases it is possible that a requested offset might seem unaligned
+ or inappropriate for the mode size, like offset = 2 and mode size = 4.
+ This is compensated by adjusting the base address so that the effective
+ address of the displacement move insn will be aligned.
+
+ This is not the best possible way of rebasing the base address, as it
+ does not look at other present displacement addressings around it.
+ In some cases this can create more base address adjustments than would
+ actually be necessary. */
+
+struct disp_adjust
+{
+ rtx offset_adjust;
+ rtx mov_disp;
+ int max_mov_disp;
+};
+
+static struct disp_adjust
+sh_find_mov_disp_adjust (int mode_sz, HOST_WIDE_INT offset)
+{
+ struct disp_adjust res = { NULL_RTX, NULL_RTX, 0 };
+
+ /* The max. available mode for actual move insns is SImode.
+ Larger accesses will be split into multiple loads/stores. */
+ const int max_mov_sz = GET_MODE_SIZE (SImode);
+
+ const int mov_insn_size = mode_sz >= max_mov_sz ? max_mov_sz : mode_sz;
+ const HOST_WIDE_INT max_disp = 15 * mov_insn_size;
+ HOST_WIDE_INT align_modifier = offset > 127 ? mov_insn_size : 0;
+
+ HOST_WIDE_INT offset_adjust;
+
+ /* In some cases this actually does happen and we must check for it. */
+ if (mode_sz < 1 || mode_sz > 8)
+ return res;
+
+ /* FIXME: HImode with displacement addressing is not supported yet.
+ Make it purposefully fail for now. */
+ if (mov_insn_size == 2)
+ return res;
- For the SH, if X is almost suitable for indexing, but the offset is
- out of range, convert it into a normal form so that CSE has a chance
- of reducing the number of address registers used. */
+ /* Keeps the previous behavior for QImode displacement addressing.
+ This just decides how the offset is re-based. Removing this special
+ case will result in slightly bigger code on average, but it's not that
+ bad actually. */
+ if (mov_insn_size == 1)
+ align_modifier = 0;
+
+ res.max_mov_disp = max_disp + mov_insn_size;
+
+ offset_adjust = ((offset + align_modifier) & ~max_disp) - align_modifier;
+
+ if (mode_sz + offset - offset_adjust <= res.max_mov_disp)
+ {
+ res.offset_adjust = GEN_INT (offset_adjust);
+ res.mov_disp = GEN_INT (offset - offset_adjust);
+ }
+
+ return res;
+}
+
+/* Try to modify an illegitimate address and make it legitimate.
+ If we find one, return the new, valid address.
+ Otherwise, return the original address. */
static rtx
sh_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
@@ -9797,66 +9868,33 @@ sh_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
if (flag_pic)
x = legitimize_pic_address (oldx, mode, NULL_RTX);
- if (GET_CODE (x) == PLUS
- && (GET_MODE_SIZE (mode) == 4
- || GET_MODE_SIZE (mode) == 8)
- && CONST_INT_P (XEXP (x, 1))
- && BASE_REGISTER_RTX_P (XEXP (x, 0))
- && ! TARGET_SHMEDIA
- && ! ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && mode == DFmode)
- && ! (TARGET_SH2E && mode == SFmode))
- {
- rtx index_rtx = XEXP (x, 1);
- HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
- rtx sum;
-
- /* On rare occasions, we might get an unaligned pointer
- that is indexed in a way to give an aligned address.
- Therefore, keep the lower two bits in offset_base. */
- /* Instead of offset_base 128..131 use 124..127, so that
- simple add suffices. */
- if (offset > 127)
- offset_base = ((offset + 4) & ~60) - 4;
- else
- offset_base = offset & ~60;
-
- /* Sometimes the normal form does not suit DImode. We
- could avoid that by using smaller ranges, but that
- would give less optimized code when SImode is
- prevalent. */
- if (GET_MODE_SIZE (mode) + offset - offset_base <= 64)
- {
- sum = expand_binop (Pmode, add_optab, XEXP (x, 0),
- GEN_INT (offset_base), NULL_RTX, 0,
- OPTAB_LIB_WIDEN);
+ if (TARGET_SHMEDIA)
+ return x;
- return gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
- }
- }
+ if (((TARGET_SH4 || TARGET_SH2A_DOUBLE) && mode == DFmode)
+ || (TARGET_SH2E && mode == SFmode))
+ return x;
- /* This could be generalized for SImode, HImode, QImode displacement
- addressing. */
- if (mode == QImode && GET_CODE (x) == PLUS
- && BASE_REGISTER_RTX_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1)))
+ if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1))
+ && BASE_REGISTER_RTX_P (XEXP (x, 0)))
{
- rtx index_rtx = XEXP (x, 1);
- HOST_WIDE_INT offset = INTVAL (index_rtx);
- HOST_WIDE_INT offset_base = offset & ~15;
-
- if (offset - offset_base <= 16)
+ const int mode_sz = GET_MODE_SIZE (mode);
+ struct disp_adjust adj = sh_find_mov_disp_adjust (mode_sz,
+ INTVAL (XEXP (x, 1)));
+
+ if (adj.offset_adjust != NULL_RTX && adj.mov_disp != NULL_RTX)
{
rtx sum = expand_binop (Pmode, add_optab, XEXP (x, 0),
- GEN_INT (offset_base), NULL_RTX, 0,
- OPTAB_LIB_WIDEN);
-
- return gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
+ adj.offset_adjust, NULL_RTX, 0,
+ OPTAB_LIB_WIDEN);
+ return gen_rtx_PLUS (Pmode, sum, adj.mov_disp);
}
}
return x;
}
-/* Attempt to replace *P, which is an address that needs reloading, with
+/* Attempt to replace *p, which is an address that needs reloading, with
a valid memory address for an operand of mode MODE.
Like for sh_legitimize_address, for the SH we try to get a normal form
of the address. That will allow inheritance of the address reloads. */
@@ -9866,75 +9904,71 @@ sh_legitimize_reload_address (rtx *p, enum machine_mode mode, int opnum,
int itype)
{
enum reload_type type = (enum reload_type) itype;
+ const int mode_sz = GET_MODE_SIZE (mode);
- if (GET_CODE (*p) == PLUS
- && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
- && CONST_INT_P (XEXP (*p, 1))
+ if (TARGET_SHMEDIA)
+ return false;
+
+ if (GET_CODE (*p) == PLUS && CONST_INT_P (XEXP (*p, 1))
&& MAYBE_BASE_REGISTER_RTX_P (XEXP (*p, 0), true)
- && ! TARGET_SHMEDIA
- && ! (TARGET_SH4 && mode == DFmode)
&& ! (mode == PSImode && type == RELOAD_FOR_INPUT_ADDRESS)
&& (ALLOW_INDEXED_ADDRESS
|| XEXP (*p, 0) == stack_pointer_rtx
|| XEXP (*p, 0) == hard_frame_pointer_rtx))
{
- rtx index_rtx = XEXP (*p, 1);
- HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
- rtx sum;
+ const HOST_WIDE_INT offset = INTVAL (XEXP (*p, 1));
+ struct disp_adjust adj = sh_find_mov_disp_adjust (mode_sz, offset);
if (TARGET_SH2A && mode == DFmode && (offset & 0x7))
{
push_reload (*p, NULL_RTX, p, NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
- goto win;
+ return true;
}
+
if (TARGET_SH2E && mode == SFmode)
{
*p = copy_rtx (*p);
push_reload (*p, NULL_RTX, p, NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
- goto win;
+ return true;
}
- /* Instead of offset_base 128..131 use 124..127, so that
- simple add suffices. */
- if (offset > 127)
- offset_base = ((offset + 4) & ~60) - 4;
- else
- offset_base = offset & ~60;
- /* Sometimes the normal form does not suit DImode. We could avoid
- that by using smaller ranges, but that would give less optimized
- code when SImode is prevalent. */
- if (GET_MODE_SIZE (mode) + offset - offset_base <= 64)
- {
- sum = gen_rtx_PLUS (Pmode, XEXP (*p, 0), GEN_INT (offset_base));
- *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
+
+ /* FIXME: Do not allow to legitimize QImode and HImode displacement
+ moves because then reload has a problem figuring the constraint
+ that the move insn target/source reg must be R0.
+ Or maybe some handling is wrong in sh_secondary_reload for this
+ to work properly? */
+ if ((mode_sz == 4 || mode_sz == 8)
+ && ! (TARGET_SH4 && mode == DFmode)
+ && adj.offset_adjust != NULL_RTX && adj.mov_disp != NULL_RTX)
+ {
+ rtx sum = gen_rtx_PLUS (Pmode, XEXP (*p, 0), adj.offset_adjust);
+ *p = gen_rtx_PLUS (Pmode, sum, adj.mov_disp);
push_reload (sum, NULL_RTX, &XEXP (*p, 0), NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
- goto win;
+ return true;
}
}
+
/* We must re-recognize what we created before. */
- else if (GET_CODE (*p) == PLUS
- && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
- && GET_CODE (XEXP (*p, 0)) == PLUS
- && CONST_INT_P (XEXP (XEXP (*p, 0), 1))
- && MAYBE_BASE_REGISTER_RTX_P (XEXP (XEXP (*p, 0), 0), true)
- && CONST_INT_P (XEXP (*p, 1))
- && ! TARGET_SHMEDIA
- && ! (TARGET_SH2E && mode == SFmode))
+ if (GET_CODE (*p) == PLUS
+ && (mode_sz == 4 || mode_sz == 8)
+ && GET_CODE (XEXP (*p, 0)) == PLUS
+ && CONST_INT_P (XEXP (XEXP (*p, 0), 1))
+ && MAYBE_BASE_REGISTER_RTX_P (XEXP (XEXP (*p, 0), 0), true)
+ && CONST_INT_P (XEXP (*p, 1))
+ && ! (TARGET_SH2E && mode == SFmode))
{
/* Because this address is so complex, we know it must have
been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
it is already unshared, and needs no further unsharing. */
push_reload (XEXP (*p, 0), NULL_RTX, &XEXP (*p, 0), NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
- goto win;
+ return true;
}
return false;
-
- win:
- return true;
}
/* In the name of slightly smaller debug output, and to cater to
diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt
index 7f7af999299..3ab2c51be4a 100644
--- a/gcc/config/sh/sh.opt
+++ b/gcc/config/sh/sh.opt
@@ -316,7 +316,7 @@ Target Report RejectNegative Mask(RELAX)
Shorten address references during linking
mrenesas
-Target Mask(HITACHI) MaskExists
+Target Mask(HITACHI)
Follow Renesas (formerly Hitachi) / SuperH calling conventions
msoft-atomic
diff --git a/gcc/config/sparc/long-double-switch.opt b/gcc/config/sparc/long-double-switch.opt
index eb3c1a00f68..8ad32bd6fe1 100644
--- a/gcc/config/sparc/long-double-switch.opt
+++ b/gcc/config/sparc/long-double-switch.opt
@@ -19,7 +19,7 @@
; <http://www.gnu.org/licenses/>.
mlong-double-128
-Target Report RejectNegative Mask(LONG_DOUBLE_128) MaskExists
+Target Report RejectNegative Mask(LONG_DOUBLE_128)
Use 128-bit long double
mlong-double-64
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index 01f3d43b2ca..58ba6b79da1 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -30,7 +30,7 @@ Target Report Mask(FPU)
Use hardware FP
mhard-float
-Target RejectNegative Mask(FPU) MaskExists
+Target RejectNegative Mask(FPU)
Use hardware FP
msoft-float
diff --git a/gcc/config/v850/v850.opt b/gcc/config/v850/v850.opt
index 12b0937391d..8fe244b0312 100644
--- a/gcc/config/v850/v850.opt
+++ b/gcc/config/v850/v850.opt
@@ -102,7 +102,7 @@ Target RejectNegative Mask(V850E1)
Compile for the v850e1 processor
mv850es
-Target RejectNegative Mask(V850E1) MaskExists
+Target RejectNegative Mask(V850E1)
Compile for the v850es variant of the v850e1
mv850e2
diff --git a/gcc/config/vax/vax.opt b/gcc/config/vax/vax.opt
index 82d6dee6422..83527adfbea 100644
--- a/gcc/config/vax/vax.opt
+++ b/gcc/config/vax/vax.opt
@@ -31,7 +31,7 @@ Target RejectNegative Mask(G_FLOAT)
Generate GFLOAT double precision code
mg-float
-Target RejectNegative Mask(G_FLOAT) MaskExists
+Target RejectNegative Mask(G_FLOAT)
Generate GFLOAT double precision code
mgnu
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 0d9be4fa49d..89ea02d1935 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,48 @@
+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
+ * typeck.c (lookup_destructor): Clear BASELINK_QUALIFIED_P if
+ we didn't get an explicit scope.
+ * pt.c (tsubst_baselink): Likewise.
+
+2012-03-28 Richard Guenther <rguenther@suse.de>
+
+ * typeck2.c (process_init_constructor_array): Use the proper
+ type for computing the array length.
+
2012-03-27 Meador Inge <meadori@codesourcery.com>
PR c++/52672
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 f128947ead8..04ba37d25e7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11814,6 +11814,7 @@ tsubst_baselink (tree baselink, tree object_type,
tree optype;
tree template_args = 0;
bool template_id_p = false;
+ bool qualified = BASELINK_QUALIFIED_P (baselink);
/* A baselink indicates a function from a base class. Both the
BASELINK_ACCESS_BINFO and the base class referenced may
@@ -11862,9 +11863,12 @@ tsubst_baselink (tree baselink, tree object_type,
if (!object_type)
object_type = current_class_type;
- return adjust_result_of_qualified_name_lookup (baselink,
- qualifying_scope,
- object_type);
+
+ if (qualified)
+ baselink = adjust_result_of_qualified_name_lookup (baselink,
+ qualifying_scope,
+ object_type);
+ return baselink;
}
/* Like tsubst_expr for a SCOPE_REF, given by QUALIFIED_ID. DONE is
@@ -17128,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/cp/typeck.c b/gcc/cp/typeck.c
index b68de52a13e..d2ed940cbc0 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2415,6 +2415,11 @@ lookup_destructor (tree object, tree scope, tree dtor_name)
tf_warning_or_error);
expr = (adjust_result_of_qualified_name_lookup
(expr, dtor_type, object_type));
+ if (scope == NULL_TREE)
+ /* We need to call adjust_result_of_qualified_name_lookup in case the
+ destructor names a base class, but we unset BASELINK_QUALIFIED_P so
+ that we still get virtual function binding. */
+ BASELINK_QUALIFIED_P (expr) = false;
return expr;
}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 80a1d0462ce..f9b525cba40 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1054,9 +1054,14 @@ process_init_constructor_array (tree type, tree init,
{
tree domain = TYPE_DOMAIN (type);
if (domain)
- len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain))
- - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain))
- + 1);
+ len = double_int_ext
+ (double_int_add
+ (double_int_sub
+ (tree_to_double_int (TYPE_MAX_VALUE (domain)),
+ tree_to_double_int (TYPE_MIN_VALUE (domain))),
+ double_int_one),
+ TYPE_PRECISION (TREE_TYPE (domain)),
+ TYPE_UNSIGNED (TREE_TYPE (domain))).low;
else
unbounded = true; /* Take as many as there are. */
}
diff --git a/gcc/cprop.c b/gcc/cprop.c
index 01f40f0bc72..ea6909195ac 100644
--- a/gcc/cprop.c
+++ b/gcc/cprop.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "df.h"
#include "dbgcnt.h"
#include "target.h"
+#include "cfgloop.h"
/* An obstack for our working variables. */
@@ -1610,6 +1611,17 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
&& dest != old_dest
&& dest != EXIT_BLOCK_PTR)
{
+ if (current_loops != NULL
+ && e->src->loop_father->latch == e->src)
+ {
+ /* ??? Now we are creating (or may create) a loop
+ with multiple entries. Simply mark it for
+ removal. Alternatively we could not do this
+ threading. */
+ e->src->loop_father->header = NULL;
+ e->src->loop_father->latch = NULL;
+ }
+
redirect_edge_and_branch_force (e, dest);
/* Copy the register setter to the redirected edge.
@@ -1904,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 a4145907183..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;
@@ -7451,7 +7451,7 @@ rest_of_handle_cse (void)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (get_insns ());
- cleanup_cfg (0);
+ cleanup_cfg (CLEANUP_CFG_CHANGED);
timevar_pop (TV_JUMP);
}
else if (tem == 1 || optimize > 1)
@@ -7511,7 +7511,7 @@ rest_of_handle_cse2 (void)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (get_insns ());
- cleanup_cfg (0);
+ cleanup_cfg (CLEANUP_CFG_CHANGED);
timevar_pop (TV_JUMP);
}
else if (tem == 1)
@@ -7572,7 +7572,7 @@ rest_of_handle_cse_after_global_opts (void)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (get_insns ());
- cleanup_cfg (0);
+ cleanup_cfg (CLEANUP_CFG_CHANGED);
timevar_pop (TV_JUMP);
}
else if (tem == 1)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b321dd82de4..36d09cde9d3 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -596,7 +596,7 @@ Objective-C and Objective-C++ Dialects}.
-tno-android-cc -tno-android-ld}
@emph{H8/300 Options}
-@gccoptlist{-mrelax -mh -ms -mn -mint32 -malign-300}
+@gccoptlist{-mrelax -mh -ms -mn -mexr -mno-exr -mint32 -malign-300}
@emph{HPPA Options}
@gccoptlist{-march=@var{architecture-type} @gol
@@ -11131,8 +11131,7 @@ sbiw r26, const ; X -= const
@item -mtiny-stack
@opindex mtiny-stack
-Only use the lower 8@tie{}bits of the stack pointer and assume that the high
-byte of SP is always zero.
+Only change the lower 8@tie{}bits of the stack pointer.
@end table
@subsubsection @code{EIND} and Devices with more than 128 Ki Bytes of Flash
@@ -12816,6 +12815,18 @@ must be used either with @option{-mh} or @option{-ms}.
@opindex ms2600
Generate code for the H8S/2600. This switch must be used with @option{-ms}.
+@item -mexr
+@opindex mexr
+Extended registers are stored on stack before execution of function
+with monitor attribute. Default option is @option{-mexr}.
+This option is valid only for H8S targets.
+
+@item -mno-exr
+@opindex mno-exr
+Extended registers are not stored on stack before execution of function
+with monitor attribute. Default option is @option{-mno-exr}.
+This option is valid only for H8S targets.
+
@item -mint32
@opindex mint32
Make @code{int} data 32 bits by default.
diff --git a/gcc/double-int.c b/gcc/double-int.c
index 834eaf9d6c2..d0fde0ed89f 100644
--- a/gcc/double-int.c
+++ b/gcc/double-int.c
@@ -186,24 +186,22 @@ mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0;
}
-/* Shift the doubleword integer in L1, H1 left by COUNT places
- keeping only PREC bits of result.
- Shift right if COUNT is negative.
- ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
+/* Shift the doubleword integer in L1, H1 right by COUNT places
+ keeping only PREC bits of result. ARITH nonzero specifies
+ arithmetic shifting; otherwise use logical shift.
Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
-void
-lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
- HOST_WIDE_INT count, unsigned int prec,
- unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, bool arith)
+static void
+rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
+ unsigned HOST_WIDE_INT count, unsigned int prec,
+ unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
+ bool arith)
{
unsigned HOST_WIDE_INT signmask;
- if (count < 0)
- {
- rshift_double (l1, h1, -count, prec, lv, hv, arith);
- return;
- }
+ signmask = (arith
+ ? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
+ : 0);
if (SHIFT_COUNT_TRUNCATED)
count %= prec;
@@ -217,61 +215,58 @@ lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
}
else if (count >= HOST_BITS_PER_WIDE_INT)
{
- *hv = l1 << (count - HOST_BITS_PER_WIDE_INT);
- *lv = 0;
+ *hv = 0;
+ *lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
}
else
{
- *hv = (((unsigned HOST_WIDE_INT) h1 << count)
- | (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
- *lv = l1 << count;
+ *hv = (unsigned HOST_WIDE_INT) h1 >> count;
+ *lv = ((l1 >> count)
+ | ((unsigned HOST_WIDE_INT) h1
+ << (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
}
- /* Sign extend all bits that are beyond the precision. */
-
- signmask = -((prec > HOST_BITS_PER_WIDE_INT
- ? ((unsigned HOST_WIDE_INT) *hv
- >> (prec - HOST_BITS_PER_WIDE_INT - 1))
- : (*lv >> (prec - 1))) & 1);
+ /* Zero / sign extend all bits that are beyond the precision. */
- if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
+ if (count >= prec)
+ {
+ *hv = signmask;
+ *lv = signmask;
+ }
+ else if ((prec - count) >= 2 * HOST_BITS_PER_WIDE_INT)
;
- else if (prec >= HOST_BITS_PER_WIDE_INT)
+ else if ((prec - count) >= HOST_BITS_PER_WIDE_INT)
{
- *hv &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
- *hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT);
+ *hv &= ~((HOST_WIDE_INT) (-1) << (prec - count - HOST_BITS_PER_WIDE_INT));
+ *hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT);
}
else
{
*hv = signmask;
- *lv &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
- *lv |= signmask << prec;
+ *lv &= ~((unsigned HOST_WIDE_INT) (-1) << (prec - count));
+ *lv |= signmask << (prec - count);
}
}
-/* Shift the doubleword integer in L1, H1 right by COUNT places
- keeping only PREC bits of result. Shift left if COUNT is negative.
+/* Shift the doubleword integer in L1, H1 left by COUNT places
+ keeping only PREC bits of result.
+ Shift right if COUNT is negative.
ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
void
-rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
+lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
HOST_WIDE_INT count, unsigned int prec,
- unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
- bool arith)
+ unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, bool arith)
{
unsigned HOST_WIDE_INT signmask;
if (count < 0)
{
- lshift_double (l1, h1, -count, prec, lv, hv, arith);
+ rshift_double (l1, h1, absu_hwi (count), prec, lv, hv, arith);
return;
}
- signmask = (arith
- ? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
- : 0);
-
if (SHIFT_COUNT_TRUNCATED)
count %= prec;
@@ -284,36 +279,35 @@ rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
}
else if (count >= HOST_BITS_PER_WIDE_INT)
{
- *hv = 0;
- *lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
+ *hv = l1 << (count - HOST_BITS_PER_WIDE_INT);
+ *lv = 0;
}
else
{
- *hv = (unsigned HOST_WIDE_INT) h1 >> count;
- *lv = ((l1 >> count)
- | ((unsigned HOST_WIDE_INT) h1
- << (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
+ *hv = (((unsigned HOST_WIDE_INT) h1 << count)
+ | (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
+ *lv = l1 << count;
}
- /* Zero / sign extend all bits that are beyond the precision. */
+ /* Sign extend all bits that are beyond the precision. */
- if (count >= (HOST_WIDE_INT)prec)
- {
- *hv = signmask;
- *lv = signmask;
- }
- else if ((prec - count) >= 2 * HOST_BITS_PER_WIDE_INT)
+ signmask = -((prec > HOST_BITS_PER_WIDE_INT
+ ? ((unsigned HOST_WIDE_INT) *hv
+ >> (prec - HOST_BITS_PER_WIDE_INT - 1))
+ : (*lv >> (prec - 1))) & 1);
+
+ if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
;
- else if ((prec - count) >= HOST_BITS_PER_WIDE_INT)
+ else if (prec >= HOST_BITS_PER_WIDE_INT)
{
- *hv &= ~((HOST_WIDE_INT) (-1) << (prec - count - HOST_BITS_PER_WIDE_INT));
- *hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT);
+ *hv &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
+ *hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT);
}
else
{
*hv = signmask;
- *lv &= ~((unsigned HOST_WIDE_INT) (-1) << (prec - count));
- *lv |= signmask << (prec - count);
+ *lv &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
+ *lv |= signmask << prec;
}
}
@@ -895,7 +889,7 @@ double_int
double_int_rshift (double_int a, HOST_WIDE_INT count, unsigned int prec, bool arith)
{
double_int ret;
- rshift_double (a.low, a.high, count, prec, &ret.low, &ret.high, arith);
+ lshift_double (a.low, a.high, -count, prec, &ret.low, &ret.high, arith);
return ret;
}
diff --git a/gcc/double-int.h b/gcc/double-int.h
index 6d1555111d3..408ed92b8a1 100644
--- a/gcc/double-int.h
+++ b/gcc/double-int.h
@@ -300,9 +300,6 @@ extern int mul_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
extern void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT, unsigned int,
unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
-extern void rshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned int,
- unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
extern int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT,
HOST_WIDE_INT, unsigned HOST_WIDE_INT,
HOST_WIDE_INT, unsigned HOST_WIDE_INT *,
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 eb27648786c..e3a9ef07422 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -144,6 +144,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "timevar.h"
#include "tree-flow.h"
+#include "cfgloop.h"
/* Provide defaults for stuff that may not be defined when using
sjlj exceptions. */
@@ -898,7 +899,7 @@ static basic_block
emit_to_new_bb_before (rtx seq, rtx insn)
{
rtx last;
- basic_block bb;
+ basic_block bb, prev_bb;
edge e;
edge_iterator ei;
@@ -913,7 +914,8 @@ emit_to_new_bb_before (rtx seq, rtx insn)
last = emit_insn_before (seq, insn);
if (BARRIER_P (last))
last = PREV_INSN (last);
- bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb);
+ prev_bb = BLOCK_FOR_INSN (insn)->prev_bb;
+ bb = create_basic_block (seq, last, prev_bb);
update_bb_for_insn (bb);
bb->flags |= BB_SUPERBLOCK;
return bb;
@@ -987,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/expmed.c b/gcc/expmed.c
index 54e51dca02d..5eea2ab8b51 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -550,7 +550,10 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
{
/* If I is 0, use the low-order word in both field and target;
if I is 1, use the next to lowest word; and so on. */
- unsigned int wordnum = (backwards ? nwords - i - 1 : i);
+ unsigned int wordnum = (backwards
+ ? GET_MODE_SIZE (fieldmode) / UNITS_PER_WORD
+ - i - 1
+ : i);
unsigned int bit_offset = (backwards
? MAX ((int) bitsize - ((int) i + 1)
* BITS_PER_WORD,
diff --git a/gcc/expr.c b/gcc/expr.c
index 56ec3fa8e2a..6caee3be7ac 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -4431,19 +4431,22 @@ optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize,
/* In the C++ memory model, consecutive bit fields in a structure are
considered one memory location.
- Given a COMPONENT_REF EXP at bit position BITPOS, this function
+ Given a COMPONENT_REF EXP at position (BITPOS, OFFSET), this function
returns the bit range of consecutive bits in which this COMPONENT_REF
- belongs in. The values are returned in *BITSTART and *BITEND.
- If the access does not need to be restricted 0 is returned in
+ belongs. The values are returned in *BITSTART and *BITEND. *BITPOS
+ and *OFFSET may be adjusted in the process.
+
+ If the access does not need to be restricted, 0 is returned in both
*BITSTART and *BITEND. */
static void
get_bit_range (unsigned HOST_WIDE_INT *bitstart,
unsigned HOST_WIDE_INT *bitend,
tree exp,
- HOST_WIDE_INT bitpos)
+ HOST_WIDE_INT *bitpos,
+ tree *offset)
{
- unsigned HOST_WIDE_INT bitoffset;
+ HOST_WIDE_INT bitoffset;
tree field, repr;
gcc_assert (TREE_CODE (exp) == COMPONENT_REF);
@@ -4490,7 +4493,25 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
bitoffset += (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
- tree_low_cst (DECL_FIELD_BIT_OFFSET (repr), 1));
- *bitstart = bitpos - bitoffset;
+ /* If the adjustment is larger than bitpos, we would have a negative bit
+ position for the lower bound and this may wreak havoc later. This can
+ occur only if we have a non-null offset, so adjust offset and bitpos
+ to make the lower bound non-negative. */
+ if (bitoffset > *bitpos)
+ {
+ HOST_WIDE_INT adjust = bitoffset - *bitpos;
+
+ gcc_assert ((adjust % BITS_PER_UNIT) == 0);
+ gcc_assert (*offset != NULL_TREE);
+
+ *bitpos += adjust;
+ *offset
+ = size_binop (MINUS_EXPR, *offset, size_int (adjust / BITS_PER_UNIT));
+ *bitstart = 0;
+ }
+ else
+ *bitstart = *bitpos - bitoffset;
+
*bitend = *bitstart + tree_low_cst (DECL_SIZE (repr), 1) - 1;
}
@@ -4595,7 +4616,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
if (TREE_CODE (to) == COMPONENT_REF
&& DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
- get_bit_range (&bitregion_start, &bitregion_end, to, bitpos);
+ get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);
/* If we are going to use store_bit_field and extract_bit_field,
make sure to_rtx will be safe for multiple use. */
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index db6f87d2071..4a79df8d1ef 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,12 @@
+2012-03-28 Paul Thomas <pault@gcc.gnu.org>
+ Tobias Burnus <burnus@gcc.gnu.org>
+
+ PR fortran/52652
+ * match.c (gfc_match_allocate, gfc_match_deallocate): Change
+ "not.. or" to "neither.. nor".
+ * parse.c (decode_specification_statement): Correct error in
+ chpice of matching function for "allocatable".
+
2012-03-23 Janne Blomqvist <jb@gcc.gnu.org>
* gfortran.h (GFC_MAX_LINE): Remove unused macro.
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 14381608c90..15edfc36db1 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -3572,8 +3572,8 @@ gfc_match_allocate (void)
|| sym->ns->proc_name->attr.proc_pointer);
if (b1 && b2 && !b3)
{
- gfc_error ("Allocate-object at %L is not a nonprocedure pointer "
- "or an allocatable variable", &tail->expr->where);
+ gfc_error ("Allocate-object at %L is neither a nonprocedure pointer "
+ "nor an allocatable variable", &tail->expr->where);
goto cleanup;
}
@@ -3904,7 +3904,7 @@ gfc_match_deallocate (void)
if (b1 && b2)
{
gfc_error ("Allocate-object at %C is not a nonprocedure pointer "
- "or an allocatable variable");
+ "nor an allocatable variable");
goto cleanup;
}
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 317fb845479..4e7f691e630 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -161,7 +161,7 @@ decode_specification_statement (void)
case 'a':
match ("abstract% interface", gfc_match_abstract_interface,
ST_INTERFACE);
- match ("allocatable", gfc_match_asynchronous, ST_ATTR_DECL);
+ match ("allocatable", gfc_match_allocatable, ST_ATTR_DECL);
match ("asynchronous", gfc_match_asynchronous, ST_ATTR_DECL);
break;
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/gimple-fold.c b/gcc/gimple-fold.c
index a1eba65e042..6ad81ddad4e 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -978,29 +978,6 @@ gimple_fold_builtin (gimple stmt)
return result;
}
-/* Generate code adjusting the first parameter of a call statement determined
- by GSI by DELTA. */
-
-void
-gimple_adjust_this_by_delta (gimple_stmt_iterator *gsi, tree delta)
-{
- gimple call_stmt = gsi_stmt (*gsi);
- tree parm, tmp;
- gimple new_stmt;
-
- delta = convert_to_ptrofftype (delta);
- gcc_assert (gimple_call_num_args (call_stmt) >= 1);
- parm = gimple_call_arg (call_stmt, 0);
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (parm)));
- tmp = create_tmp_var (TREE_TYPE (parm), NULL);
- add_referenced_var (tmp);
-
- tmp = make_ssa_name (tmp, NULL);
- new_stmt = gimple_build_assign_with_ops (POINTER_PLUS_EXPR, tmp, parm, delta);
- SSA_NAME_DEF_STMT (tmp) = new_stmt;
- gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
- gimple_call_set_arg (call_stmt, 0, tmp);
-}
/* Return a binfo to be used for devirtualization of calls based on an object
represented by a declaration (i.e. a global or automatically allocated one)
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 92edd181059..167bc738a40 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -960,7 +960,6 @@ unsigned get_gimple_rhs_num_ops (enum tree_code);
gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
const char *gimple_decl_printable_name (tree, int);
tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree);
-void gimple_adjust_this_by_delta (gimple_stmt_iterator *, tree);
tree gimple_extract_devirt_binfo_from_cst (tree);
/* Returns true iff T is a valid GIMPLE statement. */
extern bool is_gimple_stmt (tree);
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 90cf6f32dab..baff0c9a5d9 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -50,57 +50,6 @@ Expression::~Expression()
{
}
-// If this expression has a constant integer value, return it.
-
-bool
-Expression::integer_constant_value(bool iota_is_constant, mpz_t val,
- Type** ptype) const
-{
- *ptype = NULL;
- return this->do_integer_constant_value(iota_is_constant, val, ptype);
-}
-
-// If this expression has a constant floating point value, return it.
-
-bool
-Expression::float_constant_value(mpfr_t val, Type** ptype) const
-{
- *ptype = NULL;
- if (this->do_float_constant_value(val, ptype))
- return true;
- mpz_t ival;
- mpz_init(ival);
- Type* t;
- bool ret;
- if (!this->do_integer_constant_value(false, ival, &t))
- ret = false;
- else
- {
- mpfr_set_z(val, ival, GMP_RNDN);
- ret = true;
- }
- mpz_clear(ival);
- return ret;
-}
-
-// If this expression has a constant complex value, return it.
-
-bool
-Expression::complex_constant_value(mpfr_t real, mpfr_t imag,
- Type** ptype) const
-{
- *ptype = NULL;
- if (this->do_complex_constant_value(real, imag, ptype))
- return true;
- Type *t;
- if (this->float_constant_value(real, &t))
- {
- mpfr_set_ui(imag, 0, GMP_RNDN);
- return true;
- }
- return false;
-}
-
// Traverse the expressions.
int
@@ -824,24 +773,9 @@ class Error_expression : public Expression
{ return true; }
bool
- do_integer_constant_value(bool, mpz_t val, Type**) const
+ do_numeric_constant_value(Numeric_constant* nc) const
{
- mpz_set_ui(val, 0);
- return true;
- }
-
- bool
- do_float_constant_value(mpfr_t val, Type**) const
- {
- mpfr_set_ui(val, 0, GMP_RNDN);
- return true;
- }
-
- bool
- do_complex_constant_value(mpfr_t real, mpfr_t imag, Type**) const
- {
- mpfr_set_ui(real, 0, GMP_RNDN);
- mpfr_set_ui(imag, 0, GMP_RNDN);
+ nc->set_unsigned_long(NULL, 0);
return true;
}
@@ -1759,10 +1693,6 @@ class Integer_expression : public Expression
static Expression*
do_import(Import*);
- // Return whether VAL fits in the type.
- static bool
- check_constant(mpz_t val, Type*, Location);
-
// Write VAL to string dump.
static void
export_integer(String_dump* exp, const mpz_t val);
@@ -1777,7 +1707,7 @@ class Integer_expression : public Expression
{ return true; }
bool
- do_integer_constant_value(bool, mpz_t val, Type** ptype) const;
+ do_numeric_constant_value(Numeric_constant* nc) const;
Type*
do_type();
@@ -1817,15 +1747,16 @@ class Integer_expression : public Expression
bool is_character_constant_;
};
-// Return an integer constant value.
+// Return a numeric constant for this expression. We have to mark
+// this as a character when appropriate.
bool
-Integer_expression::do_integer_constant_value(bool, mpz_t val,
- Type** ptype) const
+Integer_expression::do_numeric_constant_value(Numeric_constant* nc) const
{
- if (this->type_ != NULL)
- *ptype = this->type_;
- mpz_set(val, this->val_);
+ if (this->is_character_constant_)
+ nc->set_rune(this->type_, this->val_);
+ else
+ nc->set_int(this->type_, this->val_);
return true;
}
@@ -1853,10 +1784,7 @@ Integer_expression::do_determine_type(const Type_context* context)
{
if (this->type_ != NULL && !this->type_->is_abstract())
;
- else if (context->type != NULL
- && (context->type->integer_type() != NULL
- || context->type->float_type() != NULL
- || context->type->complex_type() != NULL))
+ else if (context->type != NULL && context->type->is_numeric_type())
this->type_ = context->type;
else if (!context->may_be_abstract)
{
@@ -1867,55 +1795,20 @@ Integer_expression::do_determine_type(const Type_context* context)
}
}
-// Return true if the integer VAL fits in the range of the type TYPE.
-// Otherwise give an error and return false. TYPE may be NULL.
-
-bool
-Integer_expression::check_constant(mpz_t val, Type* type,
- Location location)
-{
- if (type == NULL)
- return true;
- Integer_type* itype = type->integer_type();
- if (itype == NULL || itype->is_abstract())
- return true;
-
- int bits = mpz_sizeinbase(val, 2);
-
- if (itype->is_unsigned())
- {
- // For an unsigned type we can only accept a nonnegative number,
- // and we must be able to represent at least BITS.
- if (mpz_sgn(val) >= 0
- && bits <= itype->bits())
- return true;
- }
- else
- {
- // For a signed type we need an extra bit to indicate the sign.
- // We have to handle the most negative integer specially.
- if (bits + 1 <= itype->bits()
- || (bits <= itype->bits()
- && mpz_sgn(val) < 0
- && (mpz_scan1(val, 0)
- == static_cast<unsigned long>(itype->bits() - 1))
- && mpz_scan0(val, itype->bits()) == ULONG_MAX))
- return true;
- }
-
- error_at(location, "integer constant overflow");
- return false;
-}
-
// Check the type of an integer constant.
void
Integer_expression::do_check_types(Gogo*)
{
- if (this->type_ == NULL)
+ Type* type = this->type_;
+ if (type == NULL)
return;
- if (!Integer_expression::check_constant(this->val_, this->type_,
- this->location()))
+ Numeric_constant nc;
+ if (this->is_character_constant_)
+ nc.set_rune(NULL, this->val_);
+ else
+ nc.set_int(NULL, this->val_);
+ if (!nc.set_type(type, true, this->location()))
this->set_is_error();
}
@@ -2117,14 +2010,6 @@ class Float_expression : public Expression
mpfr_init_set(this->val_, *val, GMP_RNDN);
}
- // Constrain VAL to fit into TYPE.
- static void
- constrain_float(mpfr_t val, Type* type);
-
- // Return whether VAL fits in the type.
- static bool
- check_constant(mpfr_t val, Type*, Location);
-
// Write VAL to export data.
static void
export_float(String_dump* exp, const mpfr_t val);
@@ -2139,7 +2024,11 @@ class Float_expression : public Expression
{ return true; }
bool
- do_float_constant_value(mpfr_t val, Type**) const;
+ do_numeric_constant_value(Numeric_constant* nc) const
+ {
+ nc->set_float(this->type_, this->val_);
+ return true;
+ }
Type*
do_type();
@@ -2171,27 +2060,6 @@ class Float_expression : public Expression
Type* type_;
};
-// Constrain VAL to fit into TYPE.
-
-void
-Float_expression::constrain_float(mpfr_t val, Type* type)
-{
- Float_type* ftype = type->float_type();
- if (ftype != NULL && !ftype->is_abstract())
- mpfr_prec_round(val, ftype->bits(), GMP_RNDN);
-}
-
-// Return a floating point constant value.
-
-bool
-Float_expression::do_float_constant_value(mpfr_t val, Type** ptype) const
-{
- if (this->type_ != NULL)
- *ptype = this->type_;
- mpfr_set(val, this->val_, GMP_RNDN);
- return true;
-}
-
// Return the current type. If we haven't set the type yet, we return
// an abstract float type.
@@ -2220,73 +2088,18 @@ Float_expression::do_determine_type(const Type_context* context)
this->type_ = Type::lookup_float_type("float64");
}
-// Return true if the floating point value VAL fits in the range of
-// the type TYPE. Otherwise give an error and return false. TYPE may
-// be NULL.
-
-bool
-Float_expression::check_constant(mpfr_t val, Type* type,
- Location location)
-{
- if (type == NULL)
- return true;
- Float_type* ftype = type->float_type();
- if (ftype == NULL || ftype->is_abstract())
- return true;
-
- // A NaN or Infinity always fits in the range of the type.
- if (mpfr_nan_p(val) || mpfr_inf_p(val) || mpfr_zero_p(val))
- return true;
-
- mp_exp_t exp = mpfr_get_exp(val);
- mp_exp_t max_exp;
- switch (ftype->bits())
- {
- case 32:
- max_exp = 128;
- break;
- case 64:
- max_exp = 1024;
- break;
- default:
- go_unreachable();
- }
- if (exp > max_exp)
- {
- error_at(location, "floating point constant overflow");
- return false;
- }
- return true;
-}
-
// Check the type of a float value.
void
Float_expression::do_check_types(Gogo*)
{
- if (this->type_ == NULL)
+ Type* type = this->type_;
+ if (type == NULL)
return;
-
- if (!Float_expression::check_constant(this->val_, this->type_,
- this->location()))
+ Numeric_constant nc;
+ nc.set_float(NULL, this->val_);
+ if (!nc.set_type(this->type_, true, this->location()))
this->set_is_error();
-
- Integer_type* integer_type = this->type_->integer_type();
- if (integer_type != NULL)
- {
- if (!mpfr_integer_p(this->val_))
- this->report_error(_("floating point constant truncated to integer"));
- else
- {
- go_assert(!integer_type->is_abstract());
- mpz_t ival;
- mpz_init(ival);
- mpfr_get_z(ival, this->val_, GMP_RNDN);
- Integer_expression::check_constant(ival, integer_type,
- this->location());
- mpz_clear(ival);
- }
- }
}
// Get a tree for a float constant.
@@ -2371,14 +2184,6 @@ class Complex_expression : public Expression
mpfr_init_set(this->imag_, *imag, GMP_RNDN);
}
- // Constrain REAL/IMAG to fit into TYPE.
- static void
- constrain_complex(mpfr_t real, mpfr_t imag, Type* type);
-
- // Return whether REAL/IMAG fits in the type.
- static bool
- check_constant(mpfr_t real, mpfr_t imag, Type*, Location);
-
// Write REAL/IMAG to string dump.
static void
export_complex(String_dump* exp, const mpfr_t real, const mpfr_t val);
@@ -2394,7 +2199,11 @@ class Complex_expression : public Expression
{ return true; }
bool
- do_complex_constant_value(mpfr_t real, mpfr_t imag, Type**) const;
+ do_numeric_constant_value(Numeric_constant* nc) const
+ {
+ nc->set_complex(this->type_, this->real_, this->imag_);
+ return true;
+ }
Type*
do_type();
@@ -2430,32 +2239,6 @@ class Complex_expression : public Expression
Type* type_;
};
-// Constrain REAL/IMAG to fit into TYPE.
-
-void
-Complex_expression::constrain_complex(mpfr_t real, mpfr_t imag, Type* type)
-{
- Complex_type* ctype = type->complex_type();
- if (ctype != NULL && !ctype->is_abstract())
- {
- mpfr_prec_round(real, ctype->bits() / 2, GMP_RNDN);
- mpfr_prec_round(imag, ctype->bits() / 2, GMP_RNDN);
- }
-}
-
-// Return a complex constant value.
-
-bool
-Complex_expression::do_complex_constant_value(mpfr_t real, mpfr_t imag,
- Type** ptype) const
-{
- if (this->type_ != NULL)
- *ptype = this->type_;
- mpfr_set(real, this->real_, GMP_RNDN);
- mpfr_set(imag, this->imag_, GMP_RNDN);
- return true;
-}
-
// Return the current type. If we haven't set the type yet, we return
// an abstract complex type.
@@ -2482,65 +2265,17 @@ Complex_expression::do_determine_type(const Type_context* context)
this->type_ = Type::lookup_complex_type("complex128");
}
-// Return true if the complex value REAL/IMAG fits in the range of the
-// type TYPE. Otherwise give an error and return false. TYPE may be
-// NULL.
-
-bool
-Complex_expression::check_constant(mpfr_t real, mpfr_t imag, Type* type,
- Location location)
-{
- if (type == NULL)
- return true;
- Complex_type* ctype = type->complex_type();
- if (ctype == NULL || ctype->is_abstract())
- return true;
-
- mp_exp_t max_exp;
- switch (ctype->bits())
- {
- case 64:
- max_exp = 128;
- break;
- case 128:
- max_exp = 1024;
- break;
- default:
- go_unreachable();
- }
-
- // A NaN or Infinity always fits in the range of the type.
- if (!mpfr_nan_p(real) && !mpfr_inf_p(real) && !mpfr_zero_p(real))
- {
- if (mpfr_get_exp(real) > max_exp)
- {
- error_at(location, "complex real part constant overflow");
- return false;
- }
- }
-
- if (!mpfr_nan_p(imag) && !mpfr_inf_p(imag) && !mpfr_zero_p(imag))
- {
- if (mpfr_get_exp(imag) > max_exp)
- {
- error_at(location, "complex imaginary part constant overflow");
- return false;
- }
- }
-
- return true;
-}
-
// Check the type of a complex value.
void
Complex_expression::do_check_types(Gogo*)
{
- if (this->type_ == NULL)
+ Type* type = this->type_;
+ if (type == NULL)
return;
-
- if (!Complex_expression::check_constant(this->real_, this->imag_,
- this->type_, this->location()))
+ Numeric_constant nc;
+ nc.set_complex(NULL, this->real_, this->imag_);
+ if (!nc.set_type(this->type_, true, this->location()))
this->set_is_error();
}
@@ -2665,13 +2400,7 @@ class Const_expression : public Expression
{ return true; }
bool
- do_integer_constant_value(bool, mpz_t val, Type**) const;
-
- bool
- do_float_constant_value(mpfr_t val, Type**) const;
-
- bool
- do_complex_constant_value(mpfr_t real, mpfr_t imag, Type**) const;
+ do_numeric_constant_value(Numeric_constant* nc) const;
bool
do_string_constant_value(std::string* val) const
@@ -2755,109 +2484,33 @@ Const_expression::do_lower(Gogo* gogo, Named_object*,
return this;
}
-// Return an integer constant value.
+// Return a numeric constant value.
bool
-Const_expression::do_integer_constant_value(bool iota_is_constant, mpz_t val,
- Type** ptype) const
+Const_expression::do_numeric_constant_value(Numeric_constant* nc) const
{
if (this->seen_)
return false;
- Type* ctype;
- if (this->type_ != NULL)
- ctype = this->type_;
- else
- ctype = this->constant_->const_value()->type();
- if (ctype != NULL && ctype->integer_type() == NULL)
- return false;
-
Expression* e = this->constant_->const_value()->expr();
-
+
this->seen_ = true;
- Type* t;
- bool r = e->integer_constant_value(iota_is_constant, val, &t);
+ bool r = e->numeric_constant_value(nc);
this->seen_ = false;
- if (r
- && ctype != NULL
- && !Integer_expression::check_constant(val, ctype, this->location()))
- return false;
-
- *ptype = ctype != NULL ? ctype : t;
- return r;
-}
-
-// Return a floating point constant value.
-
-bool
-Const_expression::do_float_constant_value(mpfr_t val, Type** ptype) const
-{
- if (this->seen_)
- return false;
-
Type* ctype;
if (this->type_ != NULL)
ctype = this->type_;
else
ctype = this->constant_->const_value()->type();
- if (ctype != NULL && ctype->float_type() == NULL)
- return false;
-
- this->seen_ = true;
-
- Type* t;
- bool r = this->constant_->const_value()->expr()->float_constant_value(val,
- &t);
-
- this->seen_ = false;
-
if (r && ctype != NULL)
{
- if (!Float_expression::check_constant(val, ctype, this->location()))
+ if (!nc->set_type(ctype, false, this->location()))
return false;
- Float_expression::constrain_float(val, ctype);
}
- *ptype = ctype != NULL ? ctype : t;
- return r;
-}
-
-// Return a complex constant value.
-
-bool
-Const_expression::do_complex_constant_value(mpfr_t real, mpfr_t imag,
- Type **ptype) const
-{
- if (this->seen_)
- return false;
-
- Type* ctype;
- if (this->type_ != NULL)
- ctype = this->type_;
- else
- ctype = this->constant_->const_value()->type();
- if (ctype != NULL && ctype->complex_type() == NULL)
- return false;
-
- this->seen_ = true;
-
- Type *t;
- bool r = this->constant_->const_value()->expr()->complex_constant_value(real,
- imag,
- &t);
-
- this->seen_ = false;
- if (r && ctype != NULL)
- {
- if (!Complex_expression::check_constant(real, imag, ctype,
- this->location()))
- return false;
- Complex_expression::constrain_complex(real, imag, ctype);
- }
- *ptype = ctype != NULL ? ctype : t;
return r;
}
@@ -2909,12 +2562,8 @@ Const_expression::do_determine_type(const Type_context* context)
if (ctype != NULL && !ctype->is_abstract())
;
else if (context->type != NULL
- && (context->type->integer_type() != NULL
- || context->type->float_type() != NULL
- || context->type->complex_type() != NULL)
- && (cetype->integer_type() != NULL
- || cetype->float_type() != NULL
- || cetype->complex_type() != NULL))
+ && context->type->is_numeric_type()
+ && cetype->is_numeric_type())
this->type_ = context->type;
else if (context->type != NULL
&& context->type->is_string_type()
@@ -2976,35 +2625,15 @@ Const_expression::do_check_types(Gogo*)
this->check_for_init_loop();
- if (this->type_ == NULL || this->type_->is_abstract())
- return;
-
- // Check for integer overflow.
- if (this->type_->integer_type() != NULL)
+ // Check that numeric constant fits in type.
+ if (this->type_ != NULL && this->type_->is_numeric_type())
{
- mpz_t ival;
- mpz_init(ival);
- Type* dummy;
- if (!this->integer_constant_value(true, ival, &dummy))
+ Numeric_constant nc;
+ if (this->constant_->const_value()->expr()->numeric_constant_value(&nc))
{
- mpfr_t fval;
- mpfr_init(fval);
- Expression* cexpr = this->constant_->const_value()->expr();
- if (cexpr->float_constant_value(fval, &dummy))
- {
- if (!mpfr_integer_p(fval))
- this->report_error(_("floating point constant "
- "truncated to integer"));
- else
- {
- mpfr_get_z(ival, fval, GMP_RNDN);
- Integer_expression::check_constant(ival, this->type_,
- this->location());
- }
- }
- mpfr_clear(fval);
+ if (!nc.set_type(this->type_, true, this->location()))
+ this->set_is_error();
}
- mpz_clear(ival);
}
}
@@ -3028,41 +2657,18 @@ Const_expression::do_get_tree(Translate_context* context)
// object is an abstract int or float, we try to get the abstract
// value. Otherwise we may lose something in the conversion.
if (this->type_ != NULL
+ && this->type_->is_numeric_type()
&& (this->constant_->const_value()->type() == NULL
|| this->constant_->const_value()->type()->is_abstract()))
{
Expression* expr = this->constant_->const_value()->expr();
- mpz_t ival;
- mpz_init(ival);
- Type* t;
- if (expr->integer_constant_value(true, ival, &t))
- {
- tree ret = Expression::integer_constant_tree(ival, type_tree);
- mpz_clear(ival);
- return ret;
- }
- mpz_clear(ival);
-
- mpfr_t fval;
- mpfr_init(fval);
- if (expr->float_constant_value(fval, &t))
- {
- tree ret = Expression::float_constant_tree(fval, type_tree);
- mpfr_clear(fval);
- return ret;
- }
-
- mpfr_t imag;
- mpfr_init(imag);
- if (expr->complex_constant_value(fval, imag, &t))
+ Numeric_constant nc;
+ if (expr->numeric_constant_value(&nc)
+ && nc.set_type(this->type_, false, this->location()))
{
- tree ret = Expression::complex_constant_tree(fval, imag, type_tree);
- mpfr_clear(fval);
- mpfr_clear(imag);
- return ret;
+ Expression* e = nc.expression(this->location());
+ return e->get_tree(context);
}
- mpfr_clear(imag);
- mpfr_clear(fval);
}
tree const_tree = this->constant_->get_tree(gogo, context->function());
@@ -3279,13 +2885,7 @@ class Type_conversion_expression : public Expression
{ return this->expr_->is_constant(); }
bool
- do_integer_constant_value(bool, mpz_t, Type**) const;
-
- bool
- do_float_constant_value(mpfr_t, Type**) const;
-
- bool
- do_complex_constant_value(mpfr_t, mpfr_t, Type**) const;
+ do_numeric_constant_value(Numeric_constant*) const;
bool
do_string_constant_value(std::string*) const;
@@ -3351,82 +2951,15 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*,
Expression* val = this->expr_;
Location location = this->location();
- if (type->integer_type() != NULL)
+ if (type->is_numeric_type())
{
- mpz_t ival;
- mpz_init(ival);
- Type* dummy;
- if (val->integer_constant_value(false, ival, &dummy))
+ Numeric_constant nc;
+ if (val->numeric_constant_value(&nc))
{
- if (!Integer_expression::check_constant(ival, type, location))
- mpz_set_ui(ival, 0);
- Expression* ret = Expression::make_integer(&ival, type, location);
- mpz_clear(ival);
- return ret;
+ if (!nc.set_type(type, true, location))
+ return Expression::make_error(location);
+ return nc.expression(location);
}
-
- mpfr_t fval;
- mpfr_init(fval);
- if (val->float_constant_value(fval, &dummy))
- {
- if (!mpfr_integer_p(fval))
- {
- error_at(location,
- "floating point constant truncated to integer");
- return Expression::make_error(location);
- }
- mpfr_get_z(ival, fval, GMP_RNDN);
- if (!Integer_expression::check_constant(ival, type, location))
- mpz_set_ui(ival, 0);
- Expression* ret = Expression::make_integer(&ival, type, location);
- mpfr_clear(fval);
- mpz_clear(ival);
- return ret;
- }
- mpfr_clear(fval);
- mpz_clear(ival);
- }
-
- if (type->float_type() != NULL)
- {
- mpfr_t fval;
- mpfr_init(fval);
- Type* dummy;
- if (val->float_constant_value(fval, &dummy))
- {
- if (!Float_expression::check_constant(fval, type, location))
- mpfr_set_ui(fval, 0, GMP_RNDN);
- Float_expression::constrain_float(fval, type);
- Expression *ret = Expression::make_float(&fval, type, location);
- mpfr_clear(fval);
- return ret;
- }
- mpfr_clear(fval);
- }
-
- if (type->complex_type() != NULL)
- {
- mpfr_t real;
- mpfr_t imag;
- mpfr_init(real);
- mpfr_init(imag);
- Type* dummy;
- if (val->complex_constant_value(real, imag, &dummy))
- {
- if (!Complex_expression::check_constant(real, imag, type, location))
- {
- mpfr_set_ui(real, 0, GMP_RNDN);
- mpfr_set_ui(imag, 0, GMP_RNDN);
- }
- Complex_expression::constrain_complex(real, imag, type);
- Expression* ret = Expression::make_complex(&real, &imag, type,
- location);
- mpfr_clear(real);
- mpfr_clear(imag);
- return ret;
- }
- mpfr_clear(real);
- mpfr_clear(imag);
}
if (type->is_slice_type())
@@ -3491,118 +3024,17 @@ Type_conversion_expression::do_lower(Gogo*, Named_object*,
return this;
}
-// Return the constant integer value if there is one.
-
-bool
-Type_conversion_expression::do_integer_constant_value(bool iota_is_constant,
- mpz_t val,
- Type** ptype) const
-{
- if (this->type_->integer_type() == NULL)
- return false;
-
- mpz_t ival;
- mpz_init(ival);
- Type* dummy;
- if (this->expr_->integer_constant_value(iota_is_constant, ival, &dummy))
- {
- if (!Integer_expression::check_constant(ival, this->type_,
- this->location()))
- {
- mpz_clear(ival);
- return false;
- }
- mpz_set(val, ival);
- mpz_clear(ival);
- *ptype = this->type_;
- return true;
- }
- mpz_clear(ival);
-
- mpfr_t fval;
- mpfr_init(fval);
- if (this->expr_->float_constant_value(fval, &dummy))
- {
- mpfr_get_z(val, fval, GMP_RNDN);
- mpfr_clear(fval);
- if (!Integer_expression::check_constant(val, this->type_,
- this->location()))
- return false;
- *ptype = this->type_;
- return true;
- }
- mpfr_clear(fval);
-
- return false;
-}
-
-// Return the constant floating point value if there is one.
+// Return the constant numeric value if there is one.
bool
-Type_conversion_expression::do_float_constant_value(mpfr_t val,
- Type** ptype) const
+Type_conversion_expression::do_numeric_constant_value(
+ Numeric_constant* nc) const
{
- if (this->type_->float_type() == NULL)
+ if (!this->type_->is_numeric_type())
return false;
-
- mpfr_t fval;
- mpfr_init(fval);
- Type* dummy;
- if (this->expr_->float_constant_value(fval, &dummy))
- {
- if (!Float_expression::check_constant(fval, this->type_,
- this->location()))
- {
- mpfr_clear(fval);
- return false;
- }
- mpfr_set(val, fval, GMP_RNDN);
- mpfr_clear(fval);
- Float_expression::constrain_float(val, this->type_);
- *ptype = this->type_;
- return true;
- }
- mpfr_clear(fval);
-
- return false;
-}
-
-// Return the constant complex value if there is one.
-
-bool
-Type_conversion_expression::do_complex_constant_value(mpfr_t real,
- mpfr_t imag,
- Type **ptype) const
-{
- if (this->type_->complex_type() == NULL)
+ if (!this->expr_->numeric_constant_value(nc))
return false;
-
- mpfr_t rval;
- mpfr_t ival;
- mpfr_init(rval);
- mpfr_init(ival);
- Type* dummy;
- if (this->expr_->complex_constant_value(rval, ival, &dummy))
- {
- if (!Complex_expression::check_constant(rval, ival, this->type_,
- this->location()))
- {
- mpfr_clear(rval);
- mpfr_clear(ival);
- return false;
- }
- mpfr_set(real, rval, GMP_RNDN);
- mpfr_set(imag, ival, GMP_RNDN);
- mpfr_clear(rval);
- mpfr_clear(ival);
- Complex_expression::constrain_complex(real, imag, this->type_);
- *ptype = this->type_;
- return true;
- }
- mpfr_clear(rval);
- mpfr_clear(ival);
-
- return false;
+ return nc->set_type(this->type_, false, this->location());
}
// Return the constant string value if there is one.
@@ -3613,20 +3045,17 @@ Type_conversion_expression::do_string_constant_value(std::string* val) const
if (this->type_->is_string_type()
&& this->expr_->type()->integer_type() != NULL)
{
- mpz_t ival;
- mpz_init(ival);
- Type* dummy;
- if (this->expr_->integer_constant_value(false, ival, &dummy))
+ Numeric_constant nc;
+ if (this->expr_->numeric_constant_value(&nc))
{
- unsigned long ulval = mpz_get_ui(ival);
- if (mpz_cmp_ui(ival, ulval) == 0)
+ unsigned long ival;
+ if (nc.to_unsigned_long(&ival) == Numeric_constant::NC_UL_VALID)
{
- Lex::append_char(ulval, true, val, this->location());
- mpz_clear(ival);
+ val->clear();
+ Lex::append_char(ival, true, val, this->location());
return true;
}
}
- mpz_clear(ival);
}
// FIXME: Could handle conversion from const []int here.
@@ -4041,22 +3470,11 @@ class Unary_expression : public Expression
this->create_temp_ = true;
}
- // Apply unary opcode OP to UVAL, setting VAL. Return true if this
- // could be done, false if not.
+ // Apply unary opcode OP to UNC, setting NC. Return true if this
+ // could be done, false if not. Issue errors for overflow.
static bool
- eval_integer(Operator op, Type* utype, mpz_t uval, mpz_t val,
- Location);
-
- // Apply unary opcode OP to UVAL, setting VAL. Return true if this
- // could be done, false if not.
- static bool
- eval_float(Operator op, mpfr_t uval, mpfr_t val);
-
- // Apply unary opcode OP to UREAL/UIMAG, setting REAL/IMAG. Return
- // true if this could be done, false if not.
- static bool
- eval_complex(Operator op, mpfr_t ureal, mpfr_t uimag, mpfr_t real,
- mpfr_t imag);
+ eval_constant(Operator op, const Numeric_constant* unc,
+ Location, Numeric_constant* nc);
static Expression*
do_import(Import*);
@@ -4073,13 +3491,7 @@ class Unary_expression : public Expression
do_is_constant() const;
bool
- do_integer_constant_value(bool, mpz_t, Type**) const;
-
- bool
- do_float_constant_value(mpfr_t, Type**) const;
-
- bool
- do_complex_constant_value(mpfr_t, mpfr_t, Type**) const;
+ do_numeric_constant_value(Numeric_constant*) const;
Type*
do_type();
@@ -4181,59 +3593,12 @@ Unary_expression::do_lower(Gogo*, Named_object*, Statement_inserter*, int)
if (op == OPERATOR_PLUS || op == OPERATOR_MINUS
|| op == OPERATOR_NOT || op == OPERATOR_XOR)
{
- Expression* ret = NULL;
-
- mpz_t eval;
- mpz_init(eval);
- Type* etype;
- if (expr->integer_constant_value(false, eval, &etype))
- {
- mpz_t val;
- mpz_init(val);
- if (Unary_expression::eval_integer(op, etype, eval, val, loc))
- ret = Expression::make_integer(&val, etype, loc);
- mpz_clear(val);
- }
- mpz_clear(eval);
- if (ret != NULL)
- return ret;
-
- if (op == OPERATOR_PLUS || op == OPERATOR_MINUS)
+ Numeric_constant nc;
+ if (expr->numeric_constant_value(&nc))
{
- mpfr_t fval;
- mpfr_init(fval);
- Type* ftype;
- if (expr->float_constant_value(fval, &ftype))
- {
- mpfr_t val;
- mpfr_init(val);
- if (Unary_expression::eval_float(op, fval, val))
- ret = Expression::make_float(&val, ftype, loc);
- mpfr_clear(val);
- }
- if (ret != NULL)
- {
- mpfr_clear(fval);
- return ret;
- }
-
- mpfr_t ival;
- mpfr_init(ival);
- if (expr->complex_constant_value(fval, ival, &ftype))
- {
- mpfr_t real;
- mpfr_t imag;
- mpfr_init(real);
- mpfr_init(imag);
- if (Unary_expression::eval_complex(op, fval, ival, real, imag))
- ret = Expression::make_complex(&real, &imag, ftype, loc);
- mpfr_clear(real);
- mpfr_clear(imag);
- }
- mpfr_clear(ival);
- mpfr_clear(fval);
- if (ret != NULL)
- return ret;
+ Numeric_constant result;
+ if (Unary_expression::eval_constant(op, &nc, loc, &result))
+ return result.expression(loc);
}
}
@@ -4269,199 +3634,171 @@ Unary_expression::do_is_constant() const
return this->expr_->is_constant();
}
-// Apply unary opcode OP to UVAL, setting VAL. UTYPE is the type of
-// UVAL, if known; it may be NULL. Return true if this could be done,
-// false if not.
+// Apply unary opcode OP to UNC, setting NC. Return true if this
+// could be done, false if not. Issue errors for overflow.
bool
-Unary_expression::eval_integer(Operator op, Type* utype, mpz_t uval, mpz_t val,
- Location location)
+Unary_expression::eval_constant(Operator op, const Numeric_constant* unc,
+ Location location, Numeric_constant* nc)
{
switch (op)
{
case OPERATOR_PLUS:
- mpz_set(val, uval);
+ *nc = *unc;
return true;
+
case OPERATOR_MINUS:
- mpz_neg(val, uval);
- return Integer_expression::check_constant(val, utype, location);
- case OPERATOR_NOT:
- mpz_set_ui(val, mpz_cmp_si(uval, 0) == 0 ? 1 : 0);
- return true;
- case OPERATOR_XOR:
- if (utype == NULL
- || utype->integer_type() == NULL
- || utype->integer_type()->is_abstract())
- mpz_com(val, uval);
+ if (unc->is_int() || unc->is_rune())
+ break;
+ else if (unc->is_float())
+ {
+ mpfr_t uval;
+ unc->get_float(&uval);
+ mpfr_t val;
+ mpfr_init(val);
+ mpfr_neg(val, uval, GMP_RNDN);
+ nc->set_float(unc->type(), val);
+ mpfr_clear(uval);
+ mpfr_clear(val);
+ return true;
+ }
+ else if (unc->is_complex())
+ {
+ mpfr_t ureal, uimag;
+ unc->get_complex(&ureal, &uimag);
+ mpfr_t real, imag;
+ mpfr_init(real);
+ mpfr_init(imag);
+ mpfr_neg(real, ureal, GMP_RNDN);
+ mpfr_neg(imag, uimag, GMP_RNDN);
+ nc->set_complex(unc->type(), real, imag);
+ mpfr_clear(ureal);
+ mpfr_clear(uimag);
+ mpfr_clear(real);
+ mpfr_clear(imag);
+ return true;
+ }
else
- {
- // The number of HOST_WIDE_INTs that it takes to represent
- // UVAL.
- size_t count = ((mpz_sizeinbase(uval, 2)
- + HOST_BITS_PER_WIDE_INT
- - 1)
- / HOST_BITS_PER_WIDE_INT);
-
- unsigned HOST_WIDE_INT* phwi = new unsigned HOST_WIDE_INT[count];
- memset(phwi, 0, count * sizeof(HOST_WIDE_INT));
-
- size_t obits = utype->integer_type()->bits();
-
- if (!utype->integer_type()->is_unsigned()
- && mpz_sgn(uval) < 0)
- {
- mpz_t adj;
- mpz_init_set_ui(adj, 1);
- mpz_mul_2exp(adj, adj, obits);
- mpz_add(uval, uval, adj);
- mpz_clear(adj);
- }
-
- size_t ecount;
- mpz_export(phwi, &ecount, -1, sizeof(HOST_WIDE_INT), 0, 0, uval);
- go_assert(ecount <= count);
-
- // Trim down to the number of words required by the type.
- size_t ocount = ((obits + HOST_BITS_PER_WIDE_INT - 1)
- / HOST_BITS_PER_WIDE_INT);
- go_assert(ocount <= count);
-
- for (size_t i = 0; i < ocount; ++i)
- phwi[i] = ~phwi[i];
-
- size_t clearbits = ocount * HOST_BITS_PER_WIDE_INT - obits;
- if (clearbits != 0)
- phwi[ocount - 1] &= (((unsigned HOST_WIDE_INT) (HOST_WIDE_INT) -1)
- >> clearbits);
-
- mpz_import(val, ocount, -1, sizeof(HOST_WIDE_INT), 0, 0, phwi);
+ go_unreachable();
- if (!utype->integer_type()->is_unsigned()
- && mpz_tstbit(val, obits - 1))
- {
- mpz_t adj;
- mpz_init_set_ui(adj, 1);
- mpz_mul_2exp(adj, adj, obits);
- mpz_sub(val, val, adj);
- mpz_clear(adj);
- }
+ case OPERATOR_NOT:
+ case OPERATOR_XOR:
+ break;
- delete[] phwi;
- }
- return Integer_expression::check_constant(val, utype, location);
case OPERATOR_AND:
case OPERATOR_MULT:
return false;
+
default:
go_unreachable();
}
-}
-// Apply unary opcode OP to UVAL, setting VAL. Return true if this
-// could be done, false if not.
+ if (!unc->is_int() && !unc->is_rune())
+ return false;
+
+ mpz_t uval;
+ unc->get_int(&uval);
+ mpz_t val;
+ mpz_init(val);
-bool
-Unary_expression::eval_float(Operator op, mpfr_t uval, mpfr_t val)
-{
switch (op)
{
- case OPERATOR_PLUS:
- mpfr_set(val, uval, GMP_RNDN);
- return true;
case OPERATOR_MINUS:
- mpfr_neg(val, uval, GMP_RNDN);
- return true;
+ mpz_neg(val, uval);
+ break;
+
case OPERATOR_NOT:
+ mpz_set_ui(val, mpz_cmp_si(uval, 0) == 0 ? 1 : 0);
+ break;
+
case OPERATOR_XOR:
- case OPERATOR_AND:
- case OPERATOR_MULT:
- return false;
- default:
- go_unreachable();
- }
-}
+ {
+ Type* utype = unc->type();
+ if (utype->integer_type() == NULL
+ || utype->integer_type()->is_abstract())
+ mpz_com(val, uval);
+ else
+ {
+ // The number of HOST_WIDE_INTs that it takes to represent
+ // UVAL.
+ size_t count = ((mpz_sizeinbase(uval, 2)
+ + HOST_BITS_PER_WIDE_INT
+ - 1)
+ / HOST_BITS_PER_WIDE_INT);
-// Apply unary opcode OP to RVAL/IVAL, setting REAL/IMAG. Return true
-// if this could be done, false if not.
+ unsigned HOST_WIDE_INT* phwi = new unsigned HOST_WIDE_INT[count];
+ memset(phwi, 0, count * sizeof(HOST_WIDE_INT));
+
+ size_t obits = utype->integer_type()->bits();
+
+ if (!utype->integer_type()->is_unsigned() && mpz_sgn(uval) < 0)
+ {
+ mpz_t adj;
+ mpz_init_set_ui(adj, 1);
+ mpz_mul_2exp(adj, adj, obits);
+ mpz_add(uval, uval, adj);
+ mpz_clear(adj);
+ }
+
+ size_t ecount;
+ mpz_export(phwi, &ecount, -1, sizeof(HOST_WIDE_INT), 0, 0, uval);
+ go_assert(ecount <= count);
+
+ // Trim down to the number of words required by the type.
+ size_t ocount = ((obits + HOST_BITS_PER_WIDE_INT - 1)
+ / HOST_BITS_PER_WIDE_INT);
+ go_assert(ocount <= count);
+
+ for (size_t i = 0; i < ocount; ++i)
+ phwi[i] = ~phwi[i];
+
+ size_t clearbits = ocount * HOST_BITS_PER_WIDE_INT - obits;
+ if (clearbits != 0)
+ phwi[ocount - 1] &= (((unsigned HOST_WIDE_INT) (HOST_WIDE_INT) -1)
+ >> clearbits);
+
+ mpz_import(val, ocount, -1, sizeof(HOST_WIDE_INT), 0, 0, phwi);
+
+ if (!utype->integer_type()->is_unsigned()
+ && mpz_tstbit(val, obits - 1))
+ {
+ mpz_t adj;
+ mpz_init_set_ui(adj, 1);
+ mpz_mul_2exp(adj, adj, obits);
+ mpz_sub(val, val, adj);
+ mpz_clear(adj);
+ }
+
+ delete[] phwi;
+ }
+ }
+ break;
-bool
-Unary_expression::eval_complex(Operator op, mpfr_t rval, mpfr_t ival,
- mpfr_t real, mpfr_t imag)
-{
- switch (op)
- {
- case OPERATOR_PLUS:
- mpfr_set(real, rval, GMP_RNDN);
- mpfr_set(imag, ival, GMP_RNDN);
- return true;
- case OPERATOR_MINUS:
- mpfr_neg(real, rval, GMP_RNDN);
- mpfr_neg(imag, ival, GMP_RNDN);
- return true;
- case OPERATOR_NOT:
- case OPERATOR_XOR:
- case OPERATOR_AND:
- case OPERATOR_MULT:
- return false;
default:
go_unreachable();
}
-}
-// Return the integral constant value of a unary expression, if it has one.
-
-bool
-Unary_expression::do_integer_constant_value(bool iota_is_constant, mpz_t val,
- Type** ptype) const
-{
- mpz_t uval;
- mpz_init(uval);
- bool ret;
- if (!this->expr_->integer_constant_value(iota_is_constant, uval, ptype))
- ret = false;
+ if (unc->is_rune())
+ nc->set_rune(NULL, val);
else
- ret = Unary_expression::eval_integer(this->op_, *ptype, uval, val,
- this->location());
- mpz_clear(uval);
- return ret;
-}
+ nc->set_int(NULL, val);
-// Return the floating point constant value of a unary expression, if
-// it has one.
+ mpz_clear(uval);
+ mpz_clear(val);
-bool
-Unary_expression::do_float_constant_value(mpfr_t val, Type** ptype) const
-{
- mpfr_t uval;
- mpfr_init(uval);
- bool ret;
- if (!this->expr_->float_constant_value(uval, ptype))
- ret = false;
- else
- ret = Unary_expression::eval_float(this->op_, uval, val);
- mpfr_clear(uval);
- return ret;
+ return nc->set_type(unc->type(), true, location);
}
-// Return the complex constant value of a unary expression, if it has
-// one.
+// Return the integral constant value of a unary expression, if it has one.
bool
-Unary_expression::do_complex_constant_value(mpfr_t real, mpfr_t imag,
- Type** ptype) const
+Unary_expression::do_numeric_constant_value(Numeric_constant* nc) const
{
- mpfr_t rval;
- mpfr_t ival;
- mpfr_init(rval);
- mpfr_init(ival);
- bool ret;
- if (!this->expr_->complex_constant_value(rval, ival, ptype))
- ret = false;
- else
- ret = Unary_expression::eval_complex(this->op_, rval, ival, real, imag);
- mpfr_clear(rval);
- mpfr_clear(ival);
- return ret;
+ Numeric_constant unc;
+ if (!this->expr_->numeric_constant_value(&unc))
+ return false;
+ return Unary_expression::eval_constant(this->op_, &unc, this->location(),
+ nc);
}
// Return the type of a unary expression.
@@ -4854,124 +4191,239 @@ Binary_expression::do_traverse(Traverse* traverse)
return Expression::traverse(&this->right_, traverse);
}
-// Compare integer constants according to OP.
+// Return the type to use for a binary operation on operands of
+// LEFT_TYPE and RIGHT_TYPE. These are the types of constants and as
+// such may be NULL or abstract.
bool
-Binary_expression::compare_integer(Operator op, mpz_t left_val,
- mpz_t right_val)
+Binary_expression::operation_type(Operator op, Type* left_type,
+ Type* right_type, Type** result_type)
+{
+ if (left_type != right_type
+ && !left_type->is_abstract()
+ && !right_type->is_abstract()
+ && left_type->base() != right_type->base()
+ && op != OPERATOR_LSHIFT
+ && op != OPERATOR_RSHIFT)
+ {
+ // May be a type error--let it be diagnosed elsewhere.
+ return false;
+ }
+
+ if (op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT)
+ {
+ if (left_type->integer_type() != NULL)
+ *result_type = left_type;
+ else
+ *result_type = Type::make_abstract_integer_type();
+ }
+ else if (!left_type->is_abstract() && left_type->named_type() != NULL)
+ *result_type = left_type;
+ else if (!right_type->is_abstract() && right_type->named_type() != NULL)
+ *result_type = right_type;
+ else if (!left_type->is_abstract())
+ *result_type = left_type;
+ else if (!right_type->is_abstract())
+ *result_type = right_type;
+ else if (left_type->complex_type() != NULL)
+ *result_type = left_type;
+ else if (right_type->complex_type() != NULL)
+ *result_type = right_type;
+ else if (left_type->float_type() != NULL)
+ *result_type = left_type;
+ else if (right_type->float_type() != NULL)
+ *result_type = right_type;
+ else if (left_type->integer_type() != NULL
+ && left_type->integer_type()->is_rune())
+ *result_type = left_type;
+ else if (right_type->integer_type() != NULL
+ && right_type->integer_type()->is_rune())
+ *result_type = right_type;
+ else
+ *result_type = left_type;
+
+ return true;
+}
+
+// Convert an integer comparison code and an operator to a boolean
+// value.
+
+bool
+Binary_expression::cmp_to_bool(Operator op, int cmp)
{
- int i = mpz_cmp(left_val, right_val);
switch (op)
{
case OPERATOR_EQEQ:
- return i == 0;
+ return cmp == 0;
+ break;
case OPERATOR_NOTEQ:
- return i != 0;
+ return cmp != 0;
+ break;
case OPERATOR_LT:
- return i < 0;
+ return cmp < 0;
+ break;
case OPERATOR_LE:
- return i <= 0;
+ return cmp <= 0;
case OPERATOR_GT:
- return i > 0;
+ return cmp > 0;
case OPERATOR_GE:
- return i >= 0;
+ return cmp >= 0;
default:
go_unreachable();
}
}
-// Compare floating point constants according to OP.
+// Compare constants according to OP.
bool
-Binary_expression::compare_float(Operator op, Type* type, mpfr_t left_val,
- mpfr_t right_val)
+Binary_expression::compare_constant(Operator op, Numeric_constant* left_nc,
+ Numeric_constant* right_nc,
+ Location location, bool* result)
{
- int i;
- if (type == NULL)
- i = mpfr_cmp(left_val, right_val);
+ Type* left_type = left_nc->type();
+ Type* right_type = right_nc->type();
+
+ Type* type;
+ if (!Binary_expression::operation_type(op, left_type, right_type, &type))
+ return false;
+
+ // When comparing an untyped operand to a typed operand, we are
+ // effectively coercing the untyped operand to the other operand's
+ // type, so make sure that is valid.
+ if (!left_nc->set_type(type, true, location)
+ || !right_nc->set_type(type, true, location))
+ return false;
+
+ bool ret;
+ int cmp;
+ if (type->complex_type() != NULL)
+ {
+ if (op != OPERATOR_EQEQ && op != OPERATOR_NOTEQ)
+ return false;
+ ret = Binary_expression::compare_complex(left_nc, right_nc, &cmp);
+ }
+ else if (type->float_type() != NULL)
+ ret = Binary_expression::compare_float(left_nc, right_nc, &cmp);
else
+ ret = Binary_expression::compare_integer(left_nc, right_nc, &cmp);
+
+ if (ret)
+ *result = Binary_expression::cmp_to_bool(op, cmp);
+
+ return ret;
+}
+
+// Compare integer constants.
+
+bool
+Binary_expression::compare_integer(const Numeric_constant* left_nc,
+ const Numeric_constant* right_nc,
+ int* cmp)
+{
+ mpz_t left_val;
+ if (!left_nc->to_int(&left_val))
+ return false;
+ mpz_t right_val;
+ if (!right_nc->to_int(&right_val))
{
- mpfr_t lv;
- mpfr_init_set(lv, left_val, GMP_RNDN);
- mpfr_t rv;
- mpfr_init_set(rv, right_val, GMP_RNDN);
- Float_expression::constrain_float(lv, type);
- Float_expression::constrain_float(rv, type);
- i = mpfr_cmp(lv, rv);
- mpfr_clear(lv);
- mpfr_clear(rv);
+ mpz_clear(left_val);
+ return false;
}
- switch (op)
+
+ *cmp = mpz_cmp(left_val, right_val);
+
+ mpz_clear(left_val);
+ mpz_clear(right_val);
+
+ return true;
+}
+
+// Compare floating point constants.
+
+bool
+Binary_expression::compare_float(const Numeric_constant* left_nc,
+ const Numeric_constant* right_nc,
+ int* cmp)
+{
+ mpfr_t left_val;
+ if (!left_nc->to_float(&left_val))
+ return false;
+ mpfr_t right_val;
+ if (!right_nc->to_float(&right_val))
{
- case OPERATOR_EQEQ:
- return i == 0;
- case OPERATOR_NOTEQ:
- return i != 0;
- case OPERATOR_LT:
- return i < 0;
- case OPERATOR_LE:
- return i <= 0;
- case OPERATOR_GT:
- return i > 0;
- case OPERATOR_GE:
- return i >= 0;
- default:
- go_unreachable();
+ mpfr_clear(left_val);
+ return false;
+ }
+
+ // We already coerced both operands to the same type. If that type
+ // is not an abstract type, we need to round the values accordingly.
+ Type* type = left_nc->type();
+ if (!type->is_abstract() && type->float_type() != NULL)
+ {
+ int bits = type->float_type()->bits();
+ mpfr_prec_round(left_val, bits, GMP_RNDN);
+ mpfr_prec_round(right_val, bits, GMP_RNDN);
}
+
+ *cmp = mpfr_cmp(left_val, right_val);
+
+ mpfr_clear(left_val);
+ mpfr_clear(right_val);
+
+ return true;
}
-// Compare complex constants according to OP. Complex numbers may
-// only be compared for equality.
+// Compare complex constants. Complex numbers may only be compared
+// for equality.
bool
-Binary_expression::compare_complex(Operator op, Type* type,
- mpfr_t left_real, mpfr_t left_imag,
- mpfr_t right_real, mpfr_t right_imag)
+Binary_expression::compare_complex(const Numeric_constant* left_nc,
+ const Numeric_constant* right_nc,
+ int* cmp)
{
- bool is_equal;
- if (type == NULL)
- is_equal = (mpfr_cmp(left_real, right_real) == 0
- && mpfr_cmp(left_imag, right_imag) == 0);
- else
+ mpfr_t left_real, left_imag;
+ if (!left_nc->to_complex(&left_real, &left_imag))
+ return false;
+ mpfr_t right_real, right_imag;
+ if (!right_nc->to_complex(&right_real, &right_imag))
{
- mpfr_t lr;
- mpfr_t li;
- mpfr_init_set(lr, left_real, GMP_RNDN);
- mpfr_init_set(li, left_imag, GMP_RNDN);
- mpfr_t rr;
- mpfr_t ri;
- mpfr_init_set(rr, right_real, GMP_RNDN);
- mpfr_init_set(ri, right_imag, GMP_RNDN);
- Complex_expression::constrain_complex(lr, li, type);
- Complex_expression::constrain_complex(rr, ri, type);
- is_equal = mpfr_cmp(lr, rr) == 0 && mpfr_cmp(li, ri) == 0;
- mpfr_clear(lr);
- mpfr_clear(li);
- mpfr_clear(rr);
- mpfr_clear(ri);
+ mpfr_clear(left_real);
+ mpfr_clear(left_imag);
+ return false;
}
- switch (op)
+
+ // We already coerced both operands to the same type. If that type
+ // is not an abstract type, we need to round the values accordingly.
+ Type* type = left_nc->type();
+ if (!type->is_abstract() && type->complex_type() != NULL)
{
- case OPERATOR_EQEQ:
- return is_equal;
- case OPERATOR_NOTEQ:
- return !is_equal;
- default:
- go_unreachable();
+ int bits = type->complex_type()->bits();
+ mpfr_prec_round(left_real, bits / 2, GMP_RNDN);
+ mpfr_prec_round(left_imag, bits / 2, GMP_RNDN);
+ mpfr_prec_round(right_real, bits / 2, GMP_RNDN);
+ mpfr_prec_round(right_imag, bits / 2, GMP_RNDN);
}
+
+ *cmp = (mpfr_cmp(left_real, right_real) != 0
+ || mpfr_cmp(left_imag, right_imag) != 0);
+
+ mpfr_clear(left_real);
+ mpfr_clear(left_imag);
+ mpfr_clear(right_real);
+ mpfr_clear(right_imag);
+
+ return true;
}
-// Apply binary opcode OP to LEFT_VAL and RIGHT_VAL, setting VAL.
-// LEFT_TYPE is the type of LEFT_VAL, RIGHT_TYPE is the type of
-// RIGHT_VAL; LEFT_TYPE and/or RIGHT_TYPE may be NULL. Return true if
-// this could be done, false if not.
+// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC. Return
+// true if this could be done, false if not. Issue errors at LOCATION
+// as appropriate.
bool
-Binary_expression::eval_integer(Operator op, Type* left_type, mpz_t left_val,
- Type* right_type, mpz_t right_val,
- Location location, mpz_t val)
+Binary_expression::eval_constant(Operator op, Numeric_constant* left_nc,
+ Numeric_constant* right_nc,
+ Location location, Numeric_constant* nc)
{
- bool is_shift_op = false;
switch (op)
{
case OPERATOR_OROR:
@@ -4982,9 +4434,68 @@ Binary_expression::eval_integer(Operator op, Type* left_type, mpz_t left_val,
case OPERATOR_LE:
case OPERATOR_GT:
case OPERATOR_GE:
- // These return boolean values. We should probably handle them
- // anyhow in case a type conversion is used on the result.
+ // These return boolean values and as such must be handled
+ // elsewhere.
+ go_unreachable();
+ default:
+ break;
+ }
+
+ Type* left_type = left_nc->type();
+ Type* right_type = right_nc->type();
+
+ Type* type;
+ if (!Binary_expression::operation_type(op, left_type, right_type, &type))
+ return false;
+
+ bool is_shift = op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT;
+
+ // When combining an untyped operand with a typed operand, we are
+ // effectively coercing the untyped operand to the other operand's
+ // type, so make sure that is valid.
+ if (!left_nc->set_type(type, true, location))
+ return false;
+ if (!is_shift && !right_nc->set_type(type, true, location))
+ return false;
+
+ bool r;
+ if (type->complex_type() != NULL)
+ r = Binary_expression::eval_complex(op, left_nc, right_nc, location, nc);
+ else if (type->float_type() != NULL)
+ r = Binary_expression::eval_float(op, left_nc, right_nc, location, nc);
+ else
+ r = Binary_expression::eval_integer(op, left_nc, right_nc, location, nc);
+
+ if (r)
+ r = nc->set_type(type, true, location);
+
+ return r;
+}
+
+// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
+// integer operations. Return true if this could be done, false if
+// not.
+
+bool
+Binary_expression::eval_integer(Operator op, const Numeric_constant* left_nc,
+ const Numeric_constant* right_nc,
+ Location location, Numeric_constant* nc)
+{
+ mpz_t left_val;
+ if (!left_nc->to_int(&left_val))
+ return false;
+ mpz_t right_val;
+ if (!right_nc->to_int(&right_val))
+ {
+ mpz_clear(left_val);
return false;
+ }
+
+ mpz_t val;
+ mpz_init(val);
+
+ switch (op)
+ {
case OPERATOR_PLUS:
mpz_add(val, left_val, right_val);
break;
@@ -5007,7 +4518,6 @@ Binary_expression::eval_integer(Operator op, Type* left_type, mpz_t left_val,
{
error_at(location, "division by zero");
mpz_set_ui(val, 0);
- return true;
}
break;
case OPERATOR_MOD:
@@ -5017,20 +4527,18 @@ Binary_expression::eval_integer(Operator op, Type* left_type, mpz_t left_val,
{
error_at(location, "division by zero");
mpz_set_ui(val, 0);
- return true;
}
break;
case OPERATOR_LSHIFT:
{
unsigned long shift = mpz_get_ui(right_val);
- if (mpz_cmp_ui(right_val, shift) != 0 || shift > 0x100000)
+ if (mpz_cmp_ui(right_val, shift) == 0 && shift <= 0x100000)
+ mpz_mul_2exp(val, left_val, shift);
+ else
{
error_at(location, "shift count overflow");
mpz_set_ui(val, 0);
- return true;
}
- mpz_mul_2exp(val, left_val, shift);
- is_shift_op = true;
break;
}
break;
@@ -5041,13 +4549,14 @@ Binary_expression::eval_integer(Operator op, Type* left_type, mpz_t left_val,
{
error_at(location, "shift count overflow");
mpz_set_ui(val, 0);
- return true;
}
- if (mpz_cmp_ui(left_val, 0) >= 0)
- mpz_tdiv_q_2exp(val, left_val, shift);
else
- mpz_fdiv_q_2exp(val, left_val, shift);
- is_shift_op = true;
+ {
+ if (mpz_cmp_ui(left_val, 0) >= 0)
+ mpz_tdiv_q_2exp(val, left_val, shift);
+ else
+ mpz_fdiv_q_2exp(val, left_val, shift);
+ }
break;
}
break;
@@ -5067,63 +4576,47 @@ Binary_expression::eval_integer(Operator op, Type* left_type, mpz_t left_val,
go_unreachable();
}
- Type* type = left_type;
- if (!is_shift_op)
- {
- if (type == NULL)
- type = right_type;
- else if (type != right_type && right_type != NULL)
- {
- if (type->is_abstract())
- type = right_type;
- else if (!right_type->is_abstract())
- {
- // This look like a type error which should be diagnosed
- // elsewhere. Don't do anything here, to avoid an
- // unhelpful chain of error messages.
- return true;
- }
- }
- }
+ mpz_clear(left_val);
+ mpz_clear(right_val);
- if (type != NULL && !type->is_abstract())
- {
- // We have to check the operands too, as we have implicitly
- // coerced them to TYPE.
- if ((type != left_type
- && !Integer_expression::check_constant(left_val, type, location))
- || (!is_shift_op
- && type != right_type
- && !Integer_expression::check_constant(right_val, type,
- location))
- || !Integer_expression::check_constant(val, type, location))
- mpz_set_ui(val, 0);
- }
+ if (left_nc->is_rune()
+ || (op != OPERATOR_LSHIFT
+ && op != OPERATOR_RSHIFT
+ && right_nc->is_rune()))
+ nc->set_rune(NULL, val);
+ else
+ nc->set_int(NULL, val);
+
+ mpz_clear(val);
return true;
}
-// Apply binary opcode OP to LEFT_VAL and RIGHT_VAL, setting VAL.
-// Return true if this could be done, false if not.
+// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
+// floating point operations. Return true if this could be done,
+// false if not.
bool
-Binary_expression::eval_float(Operator op, Type* left_type, mpfr_t left_val,
- Type* right_type, mpfr_t right_val,
- mpfr_t val, Location location)
+Binary_expression::eval_float(Operator op, const Numeric_constant* left_nc,
+ const Numeric_constant* right_nc,
+ Location location, Numeric_constant* nc)
{
- switch (op)
+ mpfr_t left_val;
+ if (!left_nc->to_float(&left_val))
+ return false;
+ mpfr_t right_val;
+ if (!right_nc->to_float(&right_val))
{
- case OPERATOR_OROR:
- case OPERATOR_ANDAND:
- case OPERATOR_EQEQ:
- case OPERATOR_NOTEQ:
- case OPERATOR_LT:
- case OPERATOR_LE:
- case OPERATOR_GT:
- case OPERATOR_GE:
- // These return boolean values. We should probably handle them
- // anyhow in case a type conversion is used on the result.
+ mpfr_clear(left_val);
return false;
+ }
+
+ mpfr_t val;
+ mpfr_init(val);
+
+ bool ret = true;
+ switch (op)
+ {
case OPERATOR_PLUS:
mpfr_add(val, left_val, right_val, GMP_RNDN);
break;
@@ -5134,78 +4627,64 @@ Binary_expression::eval_float(Operator op, Type* left_type, mpfr_t left_val,
case OPERATOR_XOR:
case OPERATOR_AND:
case OPERATOR_BITCLEAR:
- return false;
+ case OPERATOR_MOD:
+ case OPERATOR_LSHIFT:
+ case OPERATOR_RSHIFT:
+ mpfr_set_ui(val, 0, GMP_RNDN);
+ ret = false;
+ break;
case OPERATOR_MULT:
mpfr_mul(val, left_val, right_val, GMP_RNDN);
break;
case OPERATOR_DIV:
- if (mpfr_zero_p(right_val))
- error_at(location, "division by zero");
- mpfr_div(val, left_val, right_val, GMP_RNDN);
+ if (!mpfr_zero_p(right_val))
+ mpfr_div(val, left_val, right_val, GMP_RNDN);
+ else
+ {
+ error_at(location, "division by zero");
+ mpfr_set_ui(val, 0, GMP_RNDN);
+ }
break;
- case OPERATOR_MOD:
- return false;
- case OPERATOR_LSHIFT:
- case OPERATOR_RSHIFT:
- return false;
default:
go_unreachable();
}
- Type* type = left_type;
- if (type == NULL)
- type = right_type;
- else if (type != right_type && right_type != NULL)
- {
- if (type->is_abstract())
- type = right_type;
- else if (!right_type->is_abstract())
- {
- // This looks like a type error which should be diagnosed
- // elsewhere. Don't do anything here, to avoid an unhelpful
- // chain of error messages.
- return true;
- }
- }
+ mpfr_clear(left_val);
+ mpfr_clear(right_val);
- if (type != NULL && !type->is_abstract())
- {
- if ((type != left_type
- && !Float_expression::check_constant(left_val, type, location))
- || (type != right_type
- && !Float_expression::check_constant(right_val, type,
- location))
- || !Float_expression::check_constant(val, type, location))
- mpfr_set_ui(val, 0, GMP_RNDN);
- }
+ nc->set_float(NULL, val);
+ mpfr_clear(val);
- return true;
+ return ret;
}
-// Apply binary opcode OP to LEFT_REAL/LEFT_IMAG and
-// RIGHT_REAL/RIGHT_IMAG, setting REAL/IMAG. Return true if this
-// could be done, false if not.
+// Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC, using
+// complex operations. Return true if this could be done, false if
+// not.
bool
-Binary_expression::eval_complex(Operator op, Type* left_type,
- mpfr_t left_real, mpfr_t left_imag,
- Type *right_type,
- mpfr_t right_real, mpfr_t right_imag,
- mpfr_t real, mpfr_t imag,
- Location location)
+Binary_expression::eval_complex(Operator op, const Numeric_constant* left_nc,
+ const Numeric_constant* right_nc,
+ Location location, Numeric_constant* nc)
{
- switch (op)
+ mpfr_t left_real, left_imag;
+ if (!left_nc->to_complex(&left_real, &left_imag))
+ return false;
+ mpfr_t right_real, right_imag;
+ if (!right_nc->to_complex(&right_real, &right_imag))
{
- case OPERATOR_OROR:
- case OPERATOR_ANDAND:
- case OPERATOR_EQEQ:
- case OPERATOR_NOTEQ:
- case OPERATOR_LT:
- case OPERATOR_LE:
- case OPERATOR_GT:
- case OPERATOR_GE:
- // These return boolean values and must be handled differently.
+ mpfr_clear(left_real);
+ mpfr_clear(left_imag);
return false;
+ }
+
+ mpfr_t real, imag;
+ mpfr_init(real);
+ mpfr_init(imag);
+
+ bool ret = true;
+ switch (op)
+ {
case OPERATOR_PLUS:
mpfr_add(real, left_real, right_real, GMP_RNDN);
mpfr_add(imag, left_imag, right_imag, GMP_RNDN);
@@ -5218,7 +4697,13 @@ Binary_expression::eval_complex(Operator op, Type* left_type,
case OPERATOR_XOR:
case OPERATOR_AND:
case OPERATOR_BITCLEAR:
- return false;
+ case OPERATOR_MOD:
+ case OPERATOR_LSHIFT:
+ case OPERATOR_RSHIFT:
+ mpfr_set_ui(real, 0, GMP_RNDN);
+ mpfr_set_ui(imag, 0, GMP_RNDN);
+ ret = false;
+ break;
case OPERATOR_MULT:
{
// You might think that multiplying two complex numbers would
@@ -5371,7 +4856,12 @@ Binary_expression::eval_complex(Operator op, Type* left_type,
// scale the values to try to avoid this.
if (mpfr_zero_p(right_real) && mpfr_zero_p(right_imag))
- error_at(location, "division by zero");
+ {
+ error_at(location, "division by zero");
+ mpfr_set_ui(real, 0, GMP_RNDN);
+ mpfr_set_ui(imag, 0, GMP_RNDN);
+ break;
+ }
mpfr_t rra;
mpfr_t ria;
@@ -5502,48 +4992,20 @@ Binary_expression::eval_complex(Operator op, Type* left_type,
mpfr_clear(ria);
}
break;
- case OPERATOR_MOD:
- return false;
- case OPERATOR_LSHIFT:
- case OPERATOR_RSHIFT:
- return false;
default:
go_unreachable();
}
- Type* type = left_type;
- if (type == NULL)
- type = right_type;
- else if (type != right_type && right_type != NULL)
- {
- if (type->is_abstract())
- type = right_type;
- else if (!right_type->is_abstract())
- {
- // This looks like a type error which should be diagnosed
- // elsewhere. Don't do anything here, to avoid an unhelpful
- // chain of error messages.
- return true;
- }
- }
+ mpfr_clear(left_real);
+ mpfr_clear(left_imag);
+ mpfr_clear(right_real);
+ mpfr_clear(right_imag);
- if (type != NULL && !type->is_abstract())
- {
- if ((type != left_type
- && !Complex_expression::check_constant(left_real, left_imag,
- type, location))
- || (type != right_type
- && !Complex_expression::check_constant(right_real, right_imag,
- type, location))
- || !Complex_expression::check_constant(real, imag, type,
- location))
- {
- mpfr_set_ui(real, 0, GMP_RNDN);
- mpfr_set_ui(imag, 0, GMP_RNDN);
- }
- }
+ nc->set_complex(NULL, real, imag);
+ mpfr_clear(real);
+ mpfr_clear(imag);
- return true;
+ return ret;
}
// Lower a binary expression. We have to evaluate constant
@@ -5566,288 +5028,34 @@ Binary_expression::do_lower(Gogo* gogo, Named_object*,
|| op == OPERATOR_GT
|| op == OPERATOR_GE);
- // Integer constant expressions.
+ // Numeric constant expressions.
{
- mpz_t left_val;
- mpz_init(left_val);
- Type* left_type;
- mpz_t right_val;
- mpz_init(right_val);
- Type* right_type;
- if (left->integer_constant_value(false, left_val, &left_type)
- && right->integer_constant_value(false, right_val, &right_type))
+ Numeric_constant left_nc;
+ Numeric_constant right_nc;
+ if (left->numeric_constant_value(&left_nc)
+ && right->numeric_constant_value(&right_nc))
{
- Expression* ret = NULL;
- if (left_type != right_type
- && left_type != NULL
- && !left_type->is_abstract()
- && right_type != NULL
- && !right_type->is_abstract()
- && left_type->base() != right_type->base()
- && op != OPERATOR_LSHIFT
- && op != OPERATOR_RSHIFT)
+ if (is_comparison)
{
- // May be a type error--let it be diagnosed later.
- return this;
- }
- else if (is_comparison)
- {
- bool b = Binary_expression::compare_integer(op, left_val,
- right_val);
- ret = Expression::make_cast(Type::lookup_bool_type(),
- Expression::make_boolean(b, location),
- location);
+ bool result;
+ if (!Binary_expression::compare_constant(op, &left_nc,
+ &right_nc, location,
+ &result))
+ return this;
+ return Expression::make_cast(Type::lookup_bool_type(),
+ Expression::make_boolean(result,
+ location),
+ location);
}
else
{
- mpz_t val;
- mpz_init(val);
-
- if (Binary_expression::eval_integer(op, left_type, left_val,
- right_type, right_val,
- location, val))
- {
- go_assert(op != OPERATOR_OROR && op != OPERATOR_ANDAND);
- Type* type;
- if (op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT)
- type = left_type;
- else if (left_type == NULL)
- type = right_type;
- else if (right_type == NULL)
- type = left_type;
- else if (!left_type->is_abstract()
- && left_type->named_type() != NULL)
- type = left_type;
- else if (!right_type->is_abstract()
- && right_type->named_type() != NULL)
- type = right_type;
- else if (!left_type->is_abstract())
- type = left_type;
- else if (!right_type->is_abstract())
- type = right_type;
- else if (left_type->float_type() != NULL)
- type = left_type;
- else if (right_type->float_type() != NULL)
- type = right_type;
- else if (left_type->complex_type() != NULL)
- type = left_type;
- else if (right_type->complex_type() != NULL)
- type = right_type;
- else
- type = left_type;
-
- bool is_character = false;
- if (type == NULL)
- {
- Type* t = this->left_->type();
- if (t->integer_type() != NULL
- && t->integer_type()->is_rune())
- is_character = true;
- else if (op != OPERATOR_LSHIFT && op != OPERATOR_RSHIFT)
- {
- t = this->right_->type();
- if (t->integer_type() != NULL
- && t->integer_type()->is_rune())
- is_character = true;
- }
- }
-
- if (is_character)
- ret = Expression::make_character(&val, type, location);
- else
- ret = Expression::make_integer(&val, type, location);
- }
-
- mpz_clear(val);
- }
-
- if (ret != NULL)
- {
- mpz_clear(right_val);
- mpz_clear(left_val);
- return ret;
+ Numeric_constant nc;
+ if (!Binary_expression::eval_constant(op, &left_nc, &right_nc,
+ location, &nc))
+ return this;
+ return nc.expression(location);
}
}
- mpz_clear(right_val);
- mpz_clear(left_val);
- }
-
- // Floating point constant expressions.
- {
- mpfr_t left_val;
- mpfr_init(left_val);
- Type* left_type;
- mpfr_t right_val;
- mpfr_init(right_val);
- Type* right_type;
- if (left->float_constant_value(left_val, &left_type)
- && right->float_constant_value(right_val, &right_type))
- {
- Expression* ret = NULL;
- if (left_type != right_type
- && left_type != NULL
- && right_type != NULL
- && left_type->base() != right_type->base()
- && op != OPERATOR_LSHIFT
- && op != OPERATOR_RSHIFT)
- {
- // May be a type error--let it be diagnosed later.
- return this;
- }
- else if (is_comparison)
- {
- bool b = Binary_expression::compare_float(op,
- (left_type != NULL
- ? left_type
- : right_type),
- left_val, right_val);
- ret = Expression::make_boolean(b, location);
- }
- else
- {
- mpfr_t val;
- mpfr_init(val);
-
- if (Binary_expression::eval_float(op, left_type, left_val,
- right_type, right_val, val,
- location))
- {
- go_assert(op != OPERATOR_OROR && op != OPERATOR_ANDAND
- && op != OPERATOR_LSHIFT && op != OPERATOR_RSHIFT);
- Type* type;
- if (left_type == NULL)
- type = right_type;
- else if (right_type == NULL)
- type = left_type;
- else if (!left_type->is_abstract()
- && left_type->named_type() != NULL)
- type = left_type;
- else if (!right_type->is_abstract()
- && right_type->named_type() != NULL)
- type = right_type;
- else if (!left_type->is_abstract())
- type = left_type;
- else if (!right_type->is_abstract())
- type = right_type;
- else if (left_type->float_type() != NULL)
- type = left_type;
- else if (right_type->float_type() != NULL)
- type = right_type;
- else
- type = left_type;
- ret = Expression::make_float(&val, type, location);
- }
-
- mpfr_clear(val);
- }
-
- if (ret != NULL)
- {
- mpfr_clear(right_val);
- mpfr_clear(left_val);
- return ret;
- }
- }
- mpfr_clear(right_val);
- mpfr_clear(left_val);
- }
-
- // Complex constant expressions.
- {
- mpfr_t left_real;
- mpfr_t left_imag;
- mpfr_init(left_real);
- mpfr_init(left_imag);
- Type* left_type;
-
- mpfr_t right_real;
- mpfr_t right_imag;
- mpfr_init(right_real);
- mpfr_init(right_imag);
- Type* right_type;
-
- if (left->complex_constant_value(left_real, left_imag, &left_type)
- && right->complex_constant_value(right_real, right_imag, &right_type))
- {
- Expression* ret = NULL;
- if (left_type != right_type
- && left_type != NULL
- && right_type != NULL
- && left_type->base() != right_type->base())
- {
- // May be a type error--let it be diagnosed later.
- return this;
- }
- else if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
- {
- bool b = Binary_expression::compare_complex(op,
- (left_type != NULL
- ? left_type
- : right_type),
- left_real,
- left_imag,
- right_real,
- right_imag);
- ret = Expression::make_boolean(b, location);
- }
- else
- {
- mpfr_t real;
- mpfr_t imag;
- mpfr_init(real);
- mpfr_init(imag);
-
- if (Binary_expression::eval_complex(op, left_type,
- left_real, left_imag,
- right_type,
- right_real, right_imag,
- real, imag,
- location))
- {
- go_assert(op != OPERATOR_OROR && op != OPERATOR_ANDAND
- && op != OPERATOR_LSHIFT && op != OPERATOR_RSHIFT);
- Type* type;
- if (left_type == NULL)
- type = right_type;
- else if (right_type == NULL)
- type = left_type;
- else if (!left_type->is_abstract()
- && left_type->named_type() != NULL)
- type = left_type;
- else if (!right_type->is_abstract()
- && right_type->named_type() != NULL)
- type = right_type;
- else if (!left_type->is_abstract())
- type = left_type;
- else if (!right_type->is_abstract())
- type = right_type;
- else if (left_type->complex_type() != NULL)
- type = left_type;
- else if (right_type->complex_type() != NULL)
- type = right_type;
- else
- type = left_type;
- ret = Expression::make_complex(&real, &imag, type,
- location);
- }
- mpfr_clear(real);
- mpfr_clear(imag);
- }
-
- if (ret != NULL)
- {
- mpfr_clear(left_real);
- mpfr_clear(left_imag);
- mpfr_clear(right_real);
- mpfr_clear(right_imag);
- return ret;
- }
- }
-
- mpfr_clear(left_real);
- mpfr_clear(left_imag);
- mpfr_clear(right_real);
- mpfr_clear(right_imag);
}
// String constant expressions.
@@ -5864,77 +5072,13 @@ Binary_expression::do_lower(Gogo* gogo, Named_object*,
else if (is_comparison)
{
int cmp = left_string.compare(right_string);
- bool r;
- switch (op)
- {
- case OPERATOR_EQEQ:
- r = cmp == 0;
- break;
- case OPERATOR_NOTEQ:
- r = cmp != 0;
- break;
- case OPERATOR_LT:
- r = cmp < 0;
- break;
- case OPERATOR_LE:
- r = cmp <= 0;
- break;
- case OPERATOR_GT:
- r = cmp > 0;
- break;
- case OPERATOR_GE:
- r = cmp >= 0;
- break;
- default:
- go_unreachable();
- }
- return Expression::make_boolean(r, location);
- }
- }
- }
-
- // Special case for shift of a floating point constant.
- if (op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT)
- {
- mpfr_t left_val;
- mpfr_init(left_val);
- Type* left_type;
- mpz_t right_val;
- mpz_init(right_val);
- Type* right_type;
- if (left->float_constant_value(left_val, &left_type)
- && right->integer_constant_value(false, right_val, &right_type)
- && mpfr_integer_p(left_val)
- && (left_type == NULL
- || left_type->is_abstract()
- || left_type->integer_type() != NULL))
- {
- mpz_t left_int;
- mpz_init(left_int);
- mpfr_get_z(left_int, left_val, GMP_RNDN);
-
- mpz_t val;
- mpz_init(val);
-
- Expression* ret = NULL;
- if (Binary_expression::eval_integer(op, left_type, left_int,
- right_type, right_val,
- location, val))
- ret = Expression::make_integer(&val, left_type, location);
-
- mpz_clear(left_int);
- mpz_clear(val);
-
- if (ret != NULL)
- {
- mpfr_clear(left_val);
- mpz_clear(right_val);
- return ret;
+ bool r = Binary_expression::cmp_to_bool(op, cmp);
+ return Expression::make_cast(Type::lookup_bool_type(),
+ Expression::make_boolean(r,
+ location),
+ location);
}
}
-
- mpfr_clear(left_val);
- mpz_clear(right_val);
}
// Lower struct and array comparisons.
@@ -6114,154 +5258,30 @@ Binary_expression::operand_address(Statement_inserter* inserter,
return Expression::make_cast(unsafe_pointer_type, expr, loc);
}
-// Return the integer constant value, if it has one.
-
-bool
-Binary_expression::do_integer_constant_value(bool iota_is_constant, mpz_t val,
- Type** ptype) const
-{
- mpz_t left_val;
- mpz_init(left_val);
- Type* left_type;
- if (!this->left_->integer_constant_value(iota_is_constant, left_val,
- &left_type))
- {
- mpz_clear(left_val);
- return false;
- }
-
- mpz_t right_val;
- mpz_init(right_val);
- Type* right_type;
- if (!this->right_->integer_constant_value(iota_is_constant, right_val,
- &right_type))
- {
- mpz_clear(right_val);
- mpz_clear(left_val);
- return false;
- }
-
- bool ret;
- if (left_type != right_type
- && left_type != NULL
- && right_type != NULL
- && left_type->base() != right_type->base()
- && this->op_ != OPERATOR_RSHIFT
- && this->op_ != OPERATOR_LSHIFT)
- ret = false;
- else
- ret = Binary_expression::eval_integer(this->op_, left_type, left_val,
- right_type, right_val,
- this->location(), val);
-
- mpz_clear(right_val);
- mpz_clear(left_val);
-
- if (ret)
- *ptype = left_type;
-
- return ret;
-}
-
-// Return the floating point constant value, if it has one.
+// Return the numeric constant value, if it has one.
bool
-Binary_expression::do_float_constant_value(mpfr_t val, Type** ptype) const
+Binary_expression::do_numeric_constant_value(Numeric_constant* nc) const
{
- mpfr_t left_val;
- mpfr_init(left_val);
- Type* left_type;
- if (!this->left_->float_constant_value(left_val, &left_type))
- {
- mpfr_clear(left_val);
- return false;
- }
-
- mpfr_t right_val;
- mpfr_init(right_val);
- Type* right_type;
- if (!this->right_->float_constant_value(right_val, &right_type))
- {
- mpfr_clear(right_val);
- mpfr_clear(left_val);
- return false;
- }
-
- bool ret;
- if (left_type != right_type
- && left_type != NULL
- && right_type != NULL
- && left_type->base() != right_type->base())
- ret = false;
- else
- ret = Binary_expression::eval_float(this->op_, left_type, left_val,
- right_type, right_val,
- val, this->location());
+ Operator op = this->op_;
- mpfr_clear(left_val);
- mpfr_clear(right_val);
+ if (op == OPERATOR_EQEQ
+ || op == OPERATOR_NOTEQ
+ || op == OPERATOR_LT
+ || op == OPERATOR_LE
+ || op == OPERATOR_GT
+ || op == OPERATOR_GE)
+ return false;
- if (ret)
- *ptype = left_type;
+ Numeric_constant left_nc;
+ if (!this->left_->numeric_constant_value(&left_nc))
+ return false;
+ Numeric_constant right_nc;
+ if (!this->right_->numeric_constant_value(&right_nc))
+ return false;
- return ret;
-}
-
-// Return the complex constant value, if it has one.
-
-bool
-Binary_expression::do_complex_constant_value(mpfr_t real, mpfr_t imag,
- Type** ptype) const
-{
- mpfr_t left_real;
- mpfr_t left_imag;
- mpfr_init(left_real);
- mpfr_init(left_imag);
- Type* left_type;
- if (!this->left_->complex_constant_value(left_real, left_imag, &left_type))
- {
- mpfr_clear(left_real);
- mpfr_clear(left_imag);
- return false;
- }
-
- mpfr_t right_real;
- mpfr_t right_imag;
- mpfr_init(right_real);
- mpfr_init(right_imag);
- Type* right_type;
- if (!this->right_->complex_constant_value(right_real, right_imag,
- &right_type))
- {
- mpfr_clear(left_real);
- mpfr_clear(left_imag);
- mpfr_clear(right_real);
- mpfr_clear(right_imag);
- return false;
- }
-
- bool ret;
- if (left_type != right_type
- && left_type != NULL
- && right_type != NULL
- && left_type->base() != right_type->base())
- ret = false;
- else
- ret = Binary_expression::eval_complex(this->op_, left_type,
- left_real, left_imag,
- right_type,
- right_real, right_imag,
- real, imag,
- this->location());
- mpfr_clear(left_real);
- mpfr_clear(left_imag);
- mpfr_clear(right_real);
- mpfr_clear(right_imag);
-
- if (ret)
- *ptype = left_type;
-
- return ret;
+ return Binary_expression::eval_constant(op, &left_nc, &right_nc,
+ this->location(), nc);
}
// Note that the value is being discarded.
@@ -6305,41 +5325,13 @@ Binary_expression::do_type()
case OPERATOR_AND:
case OPERATOR_BITCLEAR:
{
- Type* left_type = this->left_->type();
- Type* right_type = this->right_->type();
- if (left_type->is_error())
- return left_type;
- else if (right_type->is_error())
- return right_type;
- else if (!Type::are_compatible_for_binop(left_type, right_type))
- {
- this->report_error(_("incompatible types in binary expression"));
- return Type::make_error_type();
- }
- else if (!left_type->is_abstract() && left_type->named_type() != NULL)
- return left_type;
- else if (!right_type->is_abstract() && right_type->named_type() != NULL)
- return right_type;
- else if (!left_type->is_abstract())
- return left_type;
- else if (!right_type->is_abstract())
- return right_type;
- else if (left_type->complex_type() != NULL)
- return left_type;
- else if (right_type->complex_type() != NULL)
- return right_type;
- else if (left_type->float_type() != NULL)
- return left_type;
- else if (right_type->float_type() != NULL)
- return right_type;
- else if (left_type->integer_type() != NULL
- && left_type->integer_type()->is_rune())
- return left_type;
- else if (right_type->integer_type() != NULL
- && right_type->integer_type()->is_rune())
- return right_type;
- else
- return left_type;
+ Type* type;
+ if (!Binary_expression::operation_type(this->op_,
+ this->left_->type(),
+ this->right_->type(),
+ &type))
+ return Type::make_error_type();
+ return type;
}
case OPERATOR_LSHIFT:
@@ -6604,21 +5596,25 @@ Binary_expression::do_check_types(Gogo*)
this->report_error(_("shift count not unsigned integer"));
else
{
- mpz_t val;
- mpz_init(val);
- Type* type;
- if (this->right_->integer_constant_value(true, val, &type))
+ Numeric_constant nc;
+ if (this->right_->numeric_constant_value(&nc))
{
- if (mpz_sgn(val) < 0)
+ mpz_t val;
+ if (!nc.to_int(&val))
+ this->report_error(_("shift count not unsigned integer"));
+ else
{
- this->report_error(_("negative shift count"));
- mpz_set_ui(val, 0);
- Location rloc = this->right_->location();
- this->right_ = Expression::make_integer(&val, right_type,
- rloc);
+ if (mpz_sgn(val) < 0)
+ {
+ this->report_error(_("negative shift count"));
+ mpz_set_ui(val, 0);
+ Location rloc = this->right_->location();
+ this->right_ = Expression::make_integer(&val, right_type,
+ rloc);
+ }
+ mpz_clear(val);
}
}
- mpz_clear(val);
}
}
}
@@ -7390,13 +6386,7 @@ class Builtin_call_expression : public Call_expression
do_is_constant() const;
bool
- do_integer_constant_value(bool, mpz_t, Type**) const;
-
- bool
- do_float_constant_value(mpfr_t, Type**) const;
-
- bool
- do_complex_constant_value(mpfr_t, mpfr_t, Type**) const;
+ do_numeric_constant_value(Numeric_constant*) const;
void
do_discarding_value();
@@ -7619,7 +6609,7 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
if (this->code_ == BUILTIN_LEN || this->code_ == BUILTIN_CAP)
{
Expression* arg = this->one_arg();
- if (!arg->is_constant())
+ if (arg != NULL && !arg->is_constant())
{
Find_call_expression find_call;
Expression::traverse(&arg, &find_call);
@@ -7628,37 +6618,9 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
}
}
- mpz_t ival;
- mpz_init(ival);
- Type* type;
- if (this->integer_constant_value(true, ival, &type))
- {
- Expression* ret = Expression::make_integer(&ival, type, loc);
- mpz_clear(ival);
- return ret;
- }
- mpz_clear(ival);
-
- mpfr_t rval;
- mpfr_init(rval);
- if (this->float_constant_value(rval, &type))
- {
- Expression* ret = Expression::make_float(&rval, type, loc);
- mpfr_clear(rval);
- return ret;
- }
-
- mpfr_t imag;
- mpfr_init(imag);
- if (this->complex_constant_value(rval, imag, &type))
- {
- Expression* ret = Expression::make_complex(&rval, &imag, type, loc);
- mpfr_clear(rval);
- mpfr_clear(imag);
- return ret;
- }
- mpfr_clear(rval);
- mpfr_clear(imag);
+ Numeric_constant nc;
+ if (this->numeric_constant_value(&nc))
+ return nc.expression(loc);
}
switch (this->code_)
@@ -7906,43 +6868,14 @@ Builtin_call_expression::check_int_value(Expression* e)
return true;
// Check for a floating point constant with integer value.
- mpfr_t fval;
- mpfr_init(fval);
-
- Type* dummy;
- if (e->float_constant_value(fval, &dummy) && mpfr_integer_p(fval))
+ Numeric_constant nc;
+ mpz_t ival;
+ if (e->numeric_constant_value(&nc) && nc.to_int(&ival))
{
- mpz_t ival;
- mpz_init(ival);
-
- bool ok = false;
-
- mpfr_clear_overflow();
- mpfr_clear_erangeflag();
- mpfr_get_z(ival, fval, GMP_RNDN);
- if (!mpfr_overflow_p()
- && !mpfr_erangeflag_p()
- && mpz_sgn(ival) >= 0)
- {
- Named_type* ntype = Type::lookup_integer_type("int");
- Integer_type* inttype = ntype->integer_type();
- mpz_t max;
- mpz_init_set_ui(max, 1);
- mpz_mul_2exp(max, max, inttype->bits() - 1);
- ok = mpz_cmp(ival, max) < 0;
- mpz_clear(max);
- }
mpz_clear(ival);
-
- if (ok)
- {
- mpfr_clear(fval);
- return true;
- }
+ return true;
}
- mpfr_clear(fval);
-
return false;
}
@@ -7996,7 +6929,7 @@ Expression*
Builtin_call_expression::one_arg() const
{
const Expression_list* args = this->args();
- if (args->size() != 1)
+ if (args == NULL || args->size() != 1)
return NULL;
return args->front();
}
@@ -8073,12 +7006,10 @@ Builtin_call_expression::do_is_constant() const
return false;
}
-// Return an integer constant value if possible.
+// Return a numeric constant if possible.
bool
-Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
- mpz_t val,
- Type** ptype) const
+Builtin_call_expression::do_numeric_constant_value(Numeric_constant* nc) const
{
if (this->code_ == BUILTIN_LEN
|| this->code_ == BUILTIN_CAP)
@@ -8093,8 +7024,8 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
std::string sval;
if (arg->string_constant_value(&sval))
{
- mpz_set_ui(val, sval.length());
- *ptype = Type::lookup_integer_type("int");
+ nc->set_unsigned_long(Type::lookup_integer_type("int"),
+ sval.length());
return true;
}
}
@@ -8111,13 +7042,15 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
return false;
Expression* e = arg_type->array_type()->length();
this->seen_ = true;
- bool r = e->integer_constant_value(iota_is_constant, val, ptype);
+ bool r = e->numeric_constant_value(nc);
this->seen_ = false;
if (r)
{
- *ptype = Type::lookup_integer_type("int");
- return true;
+ if (!nc->set_type(Type::lookup_integer_type("int"), false,
+ this->location()))
+ r = false;
}
+ return r;
}
}
else if (this->code_ == BUILTIN_SIZEOF
@@ -8158,8 +7091,8 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
else
go_unreachable();
- mpz_set_ui(val, ret);
- *ptype = NULL;
+ nc->set_unsigned_long(Type::lookup_integer_type("uintptr"),
+ static_cast<unsigned long>(ret));
return true;
}
else if (this->code_ == BUILTIN_OFFSETOF)
@@ -8181,88 +7114,73 @@ Builtin_call_expression::do_integer_constant_value(bool iota_is_constant,
farg->field_index(),
&offset))
return false;
- mpz_set_ui(val, offset);
+ nc->set_unsigned_long(Type::lookup_integer_type("uintptr"),
+ static_cast<unsigned long>(offset));
return true;
}
- return false;
-}
-
-// Return a floating point constant value if possible.
-
-bool
-Builtin_call_expression::do_float_constant_value(mpfr_t val,
- Type** ptype) const
-{
- if (this->code_ == BUILTIN_REAL || this->code_ == BUILTIN_IMAG)
+ else if (this->code_ == BUILTIN_REAL || this->code_ == BUILTIN_IMAG)
{
Expression* arg = this->one_arg();
if (arg == NULL)
return false;
+ Numeric_constant argnc;
+ if (!arg->numeric_constant_value(&argnc))
+ return false;
+
mpfr_t real;
mpfr_t imag;
- mpfr_init(real);
- mpfr_init(imag);
-
- bool ret = false;
- Type* type;
- if (arg->complex_constant_value(real, imag, &type))
- {
- if (this->code_ == BUILTIN_REAL)
- mpfr_set(val, real, GMP_RNDN);
- else
- mpfr_set(val, imag, GMP_RNDN);
- *ptype = Builtin_call_expression::real_imag_type(type);
- ret = true;
- }
+ if (!argnc.to_complex(&real, &imag))
+ return false;
- mpfr_clear(real);
- mpfr_clear(imag);
- return ret;
+ Type* type = Builtin_call_expression::real_imag_type(argnc.type());
+ if (this->code_ == BUILTIN_REAL)
+ nc->set_float(type, real);
+ else
+ nc->set_float(type, imag);
+ return true;
}
-
- return false;
-}
-
-// Return a complex constant value if possible.
-
-bool
-Builtin_call_expression::do_complex_constant_value(mpfr_t real, mpfr_t imag,
- Type** ptype) const
-{
- if (this->code_ == BUILTIN_COMPLEX)
+ else if (this->code_ == BUILTIN_COMPLEX)
{
const Expression_list* args = this->args();
if (args == NULL || args->size() != 2)
return false;
+ Numeric_constant rnc;
+ if (!args->front()->numeric_constant_value(&rnc))
+ return false;
+ Numeric_constant inc;
+ if (!args->back()->numeric_constant_value(&inc))
+ return false;
+
+ if (rnc.type() != NULL
+ && !rnc.type()->is_abstract()
+ && inc.type() != NULL
+ && !inc.type()->is_abstract()
+ && !Type::are_identical(rnc.type(), inc.type(), false, NULL))
+ return false;
+
mpfr_t r;
- mpfr_init(r);
- Type* rtype;
- if (!args->front()->float_constant_value(r, &rtype))
+ if (!rnc.to_float(&r))
+ return false;
+ mpfr_t i;
+ if (!inc.to_float(&i))
{
mpfr_clear(r);
return false;
}
- mpfr_t i;
- mpfr_init(i);
+ Type* arg_type = rnc.type();
+ if (arg_type == NULL || arg_type->is_abstract())
+ arg_type = inc.type();
- bool ret = false;
- Type* itype;
- if (args->back()->float_constant_value(i, &itype)
- && Type::are_identical(rtype, itype, false, NULL))
- {
- mpfr_set(real, r, GMP_RNDN);
- mpfr_set(imag, i, GMP_RNDN);
- *ptype = Builtin_call_expression::complex_type(rtype);
- ret = true;
- }
+ Type* type = Builtin_call_expression::complex_type(arg_type);
+ nc->set_complex(type, r, i);
mpfr_clear(r);
mpfr_clear(i);
- return ret;
+ return true;
}
return false;
@@ -8330,10 +7248,12 @@ Builtin_call_expression::do_type()
case BUILTIN_CAP:
case BUILTIN_COPY:
case BUILTIN_LEN:
+ return Type::lookup_integer_type("int");
+
case BUILTIN_ALIGNOF:
case BUILTIN_OFFSETOF:
case BUILTIN_SIZEOF:
- return Type::lookup_integer_type("int");
+ return Type::lookup_integer_type("uintptr");
case BUILTIN_CLOSE:
case BUILTIN_DELETE:
@@ -8461,15 +7381,19 @@ Builtin_call_expression::do_determine_type(const Type_context* context)
{
if (atype->integer_type() != NULL)
{
- mpz_t val;
- mpz_init(val);
- Type* dummy;
- if (this->integer_constant_value(true, val, &dummy)
- && mpz_sgn(val) >= 0)
- want_type = Type::lookup_integer_type("uint64");
- else
+ Numeric_constant nc;
+ if (this->numeric_constant_value(&nc))
+ {
+ mpz_t val;
+ if (nc.to_int(&val))
+ {
+ if (mpz_sgn(val) >= 0)
+ want_type = Type::lookup_integer_type("uint64");
+ mpz_clear(val);
+ }
+ }
+ if (want_type == NULL)
want_type = Type::lookup_integer_type("int64");
- mpz_clear(val);
}
else if (atype->float_type() != NULL)
want_type = Type::lookup_float_type("float64");
@@ -8521,6 +7445,8 @@ Builtin_call_expression::check_one_arg()
void
Builtin_call_expression::do_check_types(Gogo*)
{
+ if (this->is_error_expression())
+ return;
switch (this->code_)
{
case BUILTIN_INVALID:
@@ -9148,20 +8074,17 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
case BUILTIN_OFFSETOF:
case BUILTIN_ALIGNOF:
{
- mpz_t val;
- mpz_init(val);
- Type* dummy;
- bool b = this->integer_constant_value(true, val, &dummy);
- if (!b)
+ Numeric_constant nc;
+ unsigned long val;
+ if (!this->numeric_constant_value(&nc)
+ || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
{
go_assert(saw_errors());
return error_mark_node;
}
- Type* int_type = Type::lookup_integer_type("int");
- tree type = type_to_tree(int_type->get_backend(gogo));
- tree ret = Expression::integer_constant_tree(val, type);
- mpz_clear(val);
- return ret;
+ Type* uintptr_type = Type::lookup_integer_type("uintptr");
+ tree type = type_to_tree(uintptr_type->get_backend(gogo));
+ return build_int_cst(type, val);
}
case BUILTIN_COPY:
@@ -9376,50 +8299,37 @@ Builtin_call_expression::do_get_tree(Translate_context* context)
void
Builtin_call_expression::do_export(Export* exp) const
{
- bool ok = false;
+ Numeric_constant nc;
+ if (!this->numeric_constant_value(&nc))
+ {
+ error_at(this->location(), "value is not constant");
+ return;
+ }
- mpz_t val;
- mpz_init(val);
- Type* dummy;
- if (this->integer_constant_value(true, val, &dummy))
+ if (nc.is_int())
{
+ mpz_t val;
+ nc.get_int(&val);
Integer_expression::export_integer(exp, val);
- ok = true;
+ mpz_clear(val);
}
- mpz_clear(val);
-
- if (!ok)
+ else if (nc.is_float())
{
mpfr_t fval;
- mpfr_init(fval);
- if (this->float_constant_value(fval, &dummy))
- {
- Float_expression::export_float(exp, fval);
- ok = true;
- }
+ nc.get_float(&fval);
+ Float_expression::export_float(exp, fval);
mpfr_clear(fval);
}
-
- if (!ok)
+ else if (nc.is_complex())
{
mpfr_t real;
mpfr_t imag;
- mpfr_init(real);
- mpfr_init(imag);
- if (this->complex_constant_value(real, imag, &dummy))
- {
- Complex_expression::export_complex(exp, real, imag);
- ok = true;
- }
+ Complex_expression::export_complex(exp, real, imag);
mpfr_clear(real);
mpfr_clear(imag);
}
-
- if (!ok)
- {
- error_at(this->location(), "value is not constant");
- return;
- }
+ else
+ go_unreachable();
// A trailing space lets us reliably identify the end of the number.
exp->write_c_string(" ");
@@ -10660,16 +9570,14 @@ Array_index_expression::do_check_types(Gogo*)
unsigned int int_bits =
Type::lookup_integer_type("int")->integer_type()->bits();
- Type* dummy;
+ Numeric_constant lvalnc;
mpz_t lval;
- mpz_init(lval);
bool lval_valid = (array_type->length() != NULL
- && array_type->length()->integer_constant_value(true,
- lval,
- &dummy));
+ && array_type->length()->numeric_constant_value(&lvalnc)
+ && lvalnc.to_int(&lval));
+ Numeric_constant inc;
mpz_t ival;
- mpz_init(ival);
- if (this->start_->integer_constant_value(true, ival, &dummy))
+ if (this->start_->numeric_constant_value(&inc) && inc.to_int(&ival))
{
if (mpz_sgn(ival) < 0
|| mpz_sizeinbase(ival, 2) >= int_bits
@@ -10681,22 +9589,26 @@ Array_index_expression::do_check_types(Gogo*)
error_at(this->start_->location(), "array index out of bounds");
this->set_is_error();
}
+ mpz_clear(ival);
}
if (this->end_ != NULL && !this->end_->is_nil_expression())
{
- if (this->end_->integer_constant_value(true, ival, &dummy))
+ Numeric_constant enc;
+ mpz_t eval;
+ if (this->end_->numeric_constant_value(&enc) && enc.to_int(&eval))
{
- if (mpz_sgn(ival) < 0
- || mpz_sizeinbase(ival, 2) >= int_bits
- || (lval_valid && mpz_cmp(ival, lval) > 0))
+ if (mpz_sgn(eval) < 0
+ || mpz_sizeinbase(eval, 2) >= int_bits
+ || (lval_valid && mpz_cmp(eval, lval) > 0))
{
error_at(this->end_->location(), "array index out of bounds");
this->set_is_error();
}
+ mpz_clear(eval);
}
}
- mpz_clear(ival);
- mpz_clear(lval);
+ if (lval_valid)
+ mpz_clear(lval);
// A slice of an array requires an addressable array. A slice of a
// slice is always possible.
@@ -11071,10 +9983,9 @@ String_index_expression::do_check_types(Gogo*)
std::string sval;
bool sval_valid = this->string_->string_constant_value(&sval);
+ Numeric_constant inc;
mpz_t ival;
- mpz_init(ival);
- Type* dummy;
- if (this->start_->integer_constant_value(true, ival, &dummy))
+ if (this->start_->numeric_constant_value(&inc) && inc.to_int(&ival))
{
if (mpz_sgn(ival) < 0
|| (sval_valid && mpz_cmp_ui(ival, sval.length()) >= 0))
@@ -11082,20 +9993,23 @@ String_index_expression::do_check_types(Gogo*)
error_at(this->start_->location(), "string index out of bounds");
this->set_is_error();
}
+ mpz_clear(ival);
}
if (this->end_ != NULL && !this->end_->is_nil_expression())
{
- if (this->end_->integer_constant_value(true, ival, &dummy))
+ Numeric_constant enc;
+ mpz_t eval;
+ if (this->end_->numeric_constant_value(&enc) && enc.to_int(&eval))
{
- if (mpz_sgn(ival) < 0
- || (sval_valid && mpz_cmp_ui(ival, sval.length()) > 0))
+ if (mpz_sgn(eval) < 0
+ || (sval_valid && mpz_cmp_ui(eval, sval.length()) > 0))
{
error_at(this->end_->location(), "string index out of bounds");
this->set_is_error();
}
+ mpz_clear(eval);
}
}
- mpz_clear(ival);
}
// Get a tree for a string index.
@@ -11667,7 +10581,8 @@ Interface_field_reference_expression::do_check_types(Gogo*)
tree
Interface_field_reference_expression::do_get_tree(Translate_context*)
{
- go_unreachable();
+ error_at(this->location(), "reference to method other than calling it");
+ return error_mark_node;
}
// Dump ast representation for an interface field reference.
@@ -12052,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;
@@ -12076,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
@@ -12095,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.
@@ -12102,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;
@@ -12464,17 +11409,15 @@ Array_construction_expression::do_check_types(Gogo*)
}
Expression* length = at->length();
- if (length != NULL && !length->is_error_expression())
+ Numeric_constant nc;
+ unsigned long val;
+ if (length != NULL
+ && !length->is_error_expression()
+ && length->numeric_constant_value(&nc)
+ && nc.to_unsigned_long(&val) == Numeric_constant::NC_UL_VALID)
{
- mpz_t val;
- mpz_init(val);
- Type* type;
- if (at->length()->integer_constant_value(true, val, &type))
- {
- if (this->vals_->size() > mpz_get_ui(val))
- this->report_error(_("too many elements in composite literal"));
- }
- mpz_clear(val);
+ if (this->vals_->size() > val)
+ this->report_error(_("too many elements in composite literal"));
}
}
@@ -13285,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())
{
@@ -13437,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;
@@ -13444,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.
@@ -13472,49 +12420,41 @@ Composite_literal_expression::lower_array(Type* type)
if (index_expr != NULL)
{
- mpz_t ival;
- mpz_init(ival);
-
- Type* dummy;
- if (!index_expr->integer_constant_value(true, ival, &dummy))
+ Numeric_constant nc;
+ if (!index_expr->numeric_constant_value(&nc))
{
- mpz_clear(ival);
error_at(index_expr->location(),
"index expression is not integer constant");
return Expression::make_error(location);
}
- if (mpz_sgn(ival) < 0)
+ switch (nc.to_unsigned_long(&index))
{
- mpz_clear(ival);
+ case Numeric_constant::NC_UL_VALID:
+ break;
+ case Numeric_constant::NC_UL_NOTINT:
+ error_at(index_expr->location(),
+ "index expression is not integer constant");
+ return Expression::make_error(location);
+ case Numeric_constant::NC_UL_NEGATIVE:
error_at(index_expr->location(), "index expression is negative");
return Expression::make_error(location);
- }
-
- index = mpz_get_ui(ival);
- if (mpz_cmp_ui(ival, index) != 0)
- {
- mpz_clear(ival);
+ case Numeric_constant::NC_UL_BIG:
error_at(index_expr->location(), "index value overflow");
return Expression::make_error(location);
+ default:
+ go_unreachable();
}
Named_type* ntype = Type::lookup_integer_type("int");
Integer_type* inttype = ntype->integer_type();
- mpz_t max;
- mpz_init_set_ui(max, 1);
- mpz_mul_2exp(max, max, inttype->bits() - 1);
- bool ok = mpz_cmp(ival, max) < 0;
- mpz_clear(max);
- if (!ok)
+ if (sizeof(index) <= static_cast<size_t>(inttype->bits() * 8)
+ && index >> (inttype->bits() - 1) != 0)
{
- mpz_clear(ival);
error_at(index_expr->location(), "index value overflow");
return Expression::make_error(location);
}
- mpz_clear(ival);
-
// FIXME: Our representation isn't very good; this avoids
// thrashing.
if (index > 0x1000000)
@@ -14449,3 +13389,594 @@ Expression_list::contains_error() const
return true;
return false;
}
+
+// Class Numeric_constant.
+
+// Destructor.
+
+Numeric_constant::~Numeric_constant()
+{
+ this->clear();
+}
+
+// Copy constructor.
+
+Numeric_constant::Numeric_constant(const Numeric_constant& a)
+ : classification_(a.classification_), type_(a.type_)
+{
+ switch (a.classification_)
+ {
+ case NC_INVALID:
+ break;
+ case NC_INT:
+ case NC_RUNE:
+ mpz_init_set(this->u_.int_val, a.u_.int_val);
+ break;
+ case NC_FLOAT:
+ mpfr_init_set(this->u_.float_val, a.u_.float_val, GMP_RNDN);
+ break;
+ case NC_COMPLEX:
+ mpfr_init_set(this->u_.complex_val.real, a.u_.complex_val.real,
+ GMP_RNDN);
+ mpfr_init_set(this->u_.complex_val.imag, a.u_.complex_val.imag,
+ GMP_RNDN);
+ break;
+ default:
+ go_unreachable();
+ }
+}
+
+// Assignment operator.
+
+Numeric_constant&
+Numeric_constant::operator=(const Numeric_constant& a)
+{
+ this->clear();
+ this->classification_ = a.classification_;
+ this->type_ = a.type_;
+ switch (a.classification_)
+ {
+ case NC_INVALID:
+ break;
+ case NC_INT:
+ case NC_RUNE:
+ mpz_init_set(this->u_.int_val, a.u_.int_val);
+ break;
+ case NC_FLOAT:
+ mpfr_init_set(this->u_.float_val, a.u_.float_val, GMP_RNDN);
+ break;
+ case NC_COMPLEX:
+ mpfr_init_set(this->u_.complex_val.real, a.u_.complex_val.real,
+ GMP_RNDN);
+ mpfr_init_set(this->u_.complex_val.imag, a.u_.complex_val.imag,
+ GMP_RNDN);
+ break;
+ default:
+ go_unreachable();
+ }
+ return *this;
+}
+
+// Clear the contents.
+
+void
+Numeric_constant::clear()
+{
+ switch (this->classification_)
+ {
+ case NC_INVALID:
+ break;
+ case NC_INT:
+ case NC_RUNE:
+ mpz_clear(this->u_.int_val);
+ break;
+ case NC_FLOAT:
+ mpfr_clear(this->u_.float_val);
+ break;
+ case NC_COMPLEX:
+ mpfr_clear(this->u_.complex_val.real);
+ mpfr_clear(this->u_.complex_val.imag);
+ break;
+ default:
+ go_unreachable();
+ }
+ this->classification_ = NC_INVALID;
+}
+
+// Set to an unsigned long value.
+
+void
+Numeric_constant::set_unsigned_long(Type* type, unsigned long val)
+{
+ this->clear();
+ this->classification_ = NC_INT;
+ this->type_ = type;
+ mpz_init_set_ui(this->u_.int_val, val);
+}
+
+// Set to an integer value.
+
+void
+Numeric_constant::set_int(Type* type, const mpz_t val)
+{
+ this->clear();
+ this->classification_ = NC_INT;
+ this->type_ = type;
+ mpz_init_set(this->u_.int_val, val);
+}
+
+// Set to a rune value.
+
+void
+Numeric_constant::set_rune(Type* type, const mpz_t val)
+{
+ this->clear();
+ this->classification_ = NC_RUNE;
+ this->type_ = type;
+ mpz_init_set(this->u_.int_val, val);
+}
+
+// Set to a floating point value.
+
+void
+Numeric_constant::set_float(Type* type, const mpfr_t val)
+{
+ this->clear();
+ this->classification_ = NC_FLOAT;
+ this->type_ = type;
+ mpfr_init_set(this->u_.float_val, val, GMP_RNDN);
+}
+
+// Set to a complex value.
+
+void
+Numeric_constant::set_complex(Type* type, const mpfr_t real, const mpfr_t imag)
+{
+ this->clear();
+ this->classification_ = NC_COMPLEX;
+ this->type_ = type;
+ mpfr_init_set(this->u_.complex_val.real, real, GMP_RNDN);
+ mpfr_init_set(this->u_.complex_val.imag, imag, GMP_RNDN);
+}
+
+// Get an int value.
+
+void
+Numeric_constant::get_int(mpz_t* val) const
+{
+ go_assert(this->is_int());
+ mpz_init_set(*val, this->u_.int_val);
+}
+
+// Get a rune value.
+
+void
+Numeric_constant::get_rune(mpz_t* val) const
+{
+ go_assert(this->is_rune());
+ mpz_init_set(*val, this->u_.int_val);
+}
+
+// Get a floating point value.
+
+void
+Numeric_constant::get_float(mpfr_t* val) const
+{
+ go_assert(this->is_float());
+ mpfr_init_set(*val, this->u_.float_val, GMP_RNDN);
+}
+
+// Get a complex value.
+
+void
+Numeric_constant::get_complex(mpfr_t* real, mpfr_t* imag) const
+{
+ go_assert(this->is_complex());
+ mpfr_init_set(*real, this->u_.complex_val.real, GMP_RNDN);
+ mpfr_init_set(*imag, this->u_.complex_val.imag, GMP_RNDN);
+}
+
+// Express value as unsigned long if possible.
+
+Numeric_constant::To_unsigned_long
+Numeric_constant::to_unsigned_long(unsigned long* val) const
+{
+ switch (this->classification_)
+ {
+ case NC_INT:
+ case NC_RUNE:
+ return this->mpz_to_unsigned_long(this->u_.int_val, val);
+ case NC_FLOAT:
+ return this->mpfr_to_unsigned_long(this->u_.float_val, val);
+ case NC_COMPLEX:
+ if (!mpfr_zero_p(this->u_.complex_val.imag))
+ return NC_UL_NOTINT;
+ return this->mpfr_to_unsigned_long(this->u_.complex_val.real, val);
+ default:
+ go_unreachable();
+ }
+}
+
+// Express integer value as unsigned long if possible.
+
+Numeric_constant::To_unsigned_long
+Numeric_constant::mpz_to_unsigned_long(const mpz_t ival,
+ unsigned long *val) const
+{
+ if (mpz_sgn(ival) < 0)
+ return NC_UL_NEGATIVE;
+ unsigned long ui = mpz_get_ui(ival);
+ if (mpz_cmp_ui(ival, ui) != 0)
+ return NC_UL_BIG;
+ *val = ui;
+ return NC_UL_VALID;
+}
+
+// Express floating point value as unsigned long if possible.
+
+Numeric_constant::To_unsigned_long
+Numeric_constant::mpfr_to_unsigned_long(const mpfr_t fval,
+ unsigned long *val) const
+{
+ if (!mpfr_integer_p(fval))
+ return NC_UL_NOTINT;
+ mpz_t ival;
+ mpz_init(ival);
+ mpfr_get_z(ival, fval, GMP_RNDN);
+ To_unsigned_long ret = this->mpz_to_unsigned_long(ival, val);
+ mpz_clear(ival);
+ return ret;
+}
+
+// Convert value to integer if possible.
+
+bool
+Numeric_constant::to_int(mpz_t* val) const
+{
+ switch (this->classification_)
+ {
+ case NC_INT:
+ case NC_RUNE:
+ mpz_init_set(*val, this->u_.int_val);
+ return true;
+ case NC_FLOAT:
+ if (!mpfr_integer_p(this->u_.float_val))
+ return false;
+ mpz_init(*val);
+ mpfr_get_z(*val, this->u_.float_val, GMP_RNDN);
+ return true;
+ case NC_COMPLEX:
+ if (!mpfr_zero_p(this->u_.complex_val.imag)
+ || !mpfr_integer_p(this->u_.complex_val.real))
+ return false;
+ mpz_init(*val);
+ mpfr_get_z(*val, this->u_.complex_val.real, GMP_RNDN);
+ return true;
+ default:
+ go_unreachable();
+ }
+}
+
+// Convert value to floating point if possible.
+
+bool
+Numeric_constant::to_float(mpfr_t* val) const
+{
+ switch (this->classification_)
+ {
+ case NC_INT:
+ case NC_RUNE:
+ mpfr_init_set_z(*val, this->u_.int_val, GMP_RNDN);
+ return true;
+ case NC_FLOAT:
+ mpfr_init_set(*val, this->u_.float_val, GMP_RNDN);
+ return true;
+ case NC_COMPLEX:
+ if (!mpfr_zero_p(this->u_.complex_val.imag))
+ return false;
+ mpfr_init_set(*val, this->u_.complex_val.real, GMP_RNDN);
+ return true;
+ default:
+ go_unreachable();
+ }
+}
+
+// Convert value to complex.
+
+bool
+Numeric_constant::to_complex(mpfr_t* vr, mpfr_t* vi) const
+{
+ switch (this->classification_)
+ {
+ case NC_INT:
+ case NC_RUNE:
+ mpfr_init_set_z(*vr, this->u_.int_val, GMP_RNDN);
+ mpfr_init_set_ui(*vi, 0, GMP_RNDN);
+ return true;
+ case NC_FLOAT:
+ mpfr_init_set(*vr, this->u_.float_val, GMP_RNDN);
+ mpfr_init_set_ui(*vi, 0, GMP_RNDN);
+ return true;
+ case NC_COMPLEX:
+ mpfr_init_set(*vr, this->u_.complex_val.real, GMP_RNDN);
+ mpfr_init_set(*vi, this->u_.complex_val.imag, GMP_RNDN);
+ return true;
+ default:
+ go_unreachable();
+ }
+}
+
+// Get the type.
+
+Type*
+Numeric_constant::type() const
+{
+ if (this->type_ != NULL)
+ return this->type_;
+ switch (this->classification_)
+ {
+ case NC_INT:
+ return Type::make_abstract_integer_type();
+ case NC_RUNE:
+ return Type::make_abstract_character_type();
+ case NC_FLOAT:
+ return Type::make_abstract_float_type();
+ case NC_COMPLEX:
+ return Type::make_abstract_complex_type();
+ default:
+ go_unreachable();
+ }
+}
+
+// If the constant can be expressed in TYPE, then set the type of the
+// constant to TYPE and return true. Otherwise return false, and, if
+// ISSUE_ERROR is true, report an appropriate error message.
+
+bool
+Numeric_constant::set_type(Type* type, bool issue_error, Location loc)
+{
+ bool ret;
+ if (type == NULL)
+ ret = true;
+ else if (type->integer_type() != NULL)
+ ret = this->check_int_type(type->integer_type(), issue_error, loc);
+ else if (type->float_type() != NULL)
+ ret = this->check_float_type(type->float_type(), issue_error, loc);
+ else if (type->complex_type() != NULL)
+ ret = this->check_complex_type(type->complex_type(), issue_error, loc);
+ else
+ go_unreachable();
+ if (ret)
+ this->type_ = type;
+ return ret;
+}
+
+// Check whether the constant can be expressed in an integer type.
+
+bool
+Numeric_constant::check_int_type(Integer_type* type, bool issue_error,
+ Location location) const
+{
+ mpz_t val;
+ switch (this->classification_)
+ {
+ case NC_INT:
+ case NC_RUNE:
+ mpz_init_set(val, this->u_.int_val);
+ break;
+
+ case NC_FLOAT:
+ if (!mpfr_integer_p(this->u_.float_val))
+ {
+ if (issue_error)
+ error_at(location, "floating point constant truncated to integer");
+ return false;
+ }
+ mpz_init(val);
+ mpfr_get_z(val, this->u_.float_val, GMP_RNDN);
+ break;
+
+ case NC_COMPLEX:
+ if (!mpfr_integer_p(this->u_.complex_val.real)
+ || !mpfr_zero_p(this->u_.complex_val.imag))
+ {
+ if (issue_error)
+ error_at(location, "complex constant truncated to integer");
+ return false;
+ }
+ mpz_init(val);
+ mpfr_get_z(val, this->u_.complex_val.real, GMP_RNDN);
+ break;
+
+ default:
+ go_unreachable();
+ }
+
+ bool ret;
+ if (type->is_abstract())
+ ret = true;
+ else
+ {
+ int bits = mpz_sizeinbase(val, 2);
+ if (type->is_unsigned())
+ {
+ // For an unsigned type we can only accept a nonnegative
+ // number, and we must be able to represents at least BITS.
+ ret = mpz_sgn(val) >= 0 && bits <= type->bits();
+ }
+ else
+ {
+ // For a signed type we need an extra bit to indicate the
+ // sign. We have to handle the most negative integer
+ // specially.
+ ret = (bits + 1 <= type->bits()
+ || (bits <= type->bits()
+ && mpz_sgn(val) < 0
+ && (mpz_scan1(val, 0)
+ == static_cast<unsigned long>(type->bits() - 1))
+ && mpz_scan0(val, type->bits()) == ULONG_MAX));
+ }
+ }
+
+ if (!ret && issue_error)
+ error_at(location, "integer constant overflow");
+
+ return ret;
+}
+
+// Check whether the constant can be expressed in a floating point
+// type.
+
+bool
+Numeric_constant::check_float_type(Float_type* type, bool issue_error,
+ Location location) const
+{
+ mpfr_t val;
+ switch (this->classification_)
+ {
+ case NC_INT:
+ case NC_RUNE:
+ mpfr_init_set_z(val, this->u_.int_val, GMP_RNDN);
+ break;
+
+ case NC_FLOAT:
+ mpfr_init_set(val, this->u_.float_val, GMP_RNDN);
+ break;
+
+ case NC_COMPLEX:
+ if (!mpfr_zero_p(this->u_.complex_val.imag))
+ {
+ if (issue_error)
+ error_at(location, "complex constant truncated to float");
+ return false;
+ }
+ mpfr_init_set(val, this->u_.complex_val.real, GMP_RNDN);
+ break;
+
+ default:
+ go_unreachable();
+ }
+
+ bool ret;
+ if (type->is_abstract())
+ ret = true;
+ else if (mpfr_nan_p(val) || mpfr_inf_p(val) || mpfr_zero_p(val))
+ {
+ // A NaN or Infinity always fits in the range of the type.
+ ret = true;
+ }
+ else
+ {
+ mp_exp_t exp = mpfr_get_exp(val);
+ mp_exp_t max_exp;
+ switch (type->bits())
+ {
+ case 32:
+ max_exp = 128;
+ break;
+ case 64:
+ max_exp = 1024;
+ break;
+ default:
+ go_unreachable();
+ }
+
+ ret = exp <= max_exp;
+ }
+
+ mpfr_clear(val);
+
+ if (!ret && issue_error)
+ error_at(location, "floating point constant overflow");
+
+ return ret;
+}
+
+// Check whether the constant can be expressed in a complex type.
+
+bool
+Numeric_constant::check_complex_type(Complex_type* type, bool issue_error,
+ Location location) const
+{
+ if (type->is_abstract())
+ return true;
+
+ mp_exp_t max_exp;
+ switch (type->bits())
+ {
+ case 64:
+ max_exp = 128;
+ break;
+ case 128:
+ max_exp = 1024;
+ break;
+ default:
+ go_unreachable();
+ }
+
+ mpfr_t real;
+ switch (this->classification_)
+ {
+ case NC_INT:
+ case NC_RUNE:
+ mpfr_init_set_z(real, this->u_.int_val, GMP_RNDN);
+ break;
+
+ case NC_FLOAT:
+ mpfr_init_set(real, this->u_.float_val, GMP_RNDN);
+ break;
+
+ case NC_COMPLEX:
+ if (!mpfr_nan_p(this->u_.complex_val.imag)
+ && !mpfr_inf_p(this->u_.complex_val.imag)
+ && !mpfr_zero_p(this->u_.complex_val.imag))
+ {
+ if (mpfr_get_exp(this->u_.complex_val.imag) > max_exp)
+ {
+ if (issue_error)
+ error_at(location, "complex imaginary part overflow");
+ return false;
+ }
+ }
+ mpfr_init_set(real, this->u_.complex_val.real, GMP_RNDN);
+ break;
+
+ default:
+ go_unreachable();
+ }
+
+ bool ret;
+ if (mpfr_nan_p(real) || mpfr_inf_p(real) || mpfr_zero_p(real))
+ ret = true;
+ else
+ ret = mpfr_get_exp(real) <= max_exp;
+
+ mpfr_clear(real);
+
+ if (!ret && issue_error)
+ error_at(location, "complex real part overflow");
+
+ return ret;
+}
+
+// Return an Expression for this value.
+
+Expression*
+Numeric_constant::expression(Location loc) const
+{
+ switch (this->classification_)
+ {
+ case NC_INT:
+ return Expression::make_integer(&this->u_.int_val, this->type_, loc);
+ case NC_RUNE:
+ return Expression::make_character(&this->u_.int_val, this->type_, loc);
+ case NC_FLOAT:
+ return Expression::make_float(&this->u_.float_val, this->type_, loc);
+ case NC_COMPLEX:
+ return Expression::make_complex(&this->u_.complex_val.real,
+ &this->u_.complex_val.imag,
+ this->type_, loc);
+ default:
+ go_unreachable();
+ }
+}
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index 0a3f2050dd4..d58e6c5fcb0 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -18,6 +18,9 @@ class Traverse;
class Statement_inserter;
class Type;
struct Type_context;
+class Integer_type;
+class Float_type;
+class Complex_type;
class Function_type;
class Map_type;
class Struct_type;
@@ -38,6 +41,7 @@ class Field_reference_expression;
class Interface_field_reference_expression;
class Type_guard_expression;
class Receive_expression;
+class Numeric_constant;
class Named_object;
class Export;
class Import;
@@ -342,30 +346,11 @@ class Expression
is_constant() const
{ return this->do_is_constant(); }
- // If this is not a constant expression with integral type, return
- // false. If it is one, return true, and set VAL to the value. VAL
- // should already be initialized. If this returns true, it sets
- // *PTYPE to the type of the value, or NULL for an abstract type.
- // If IOTA_IS_CONSTANT is true, then an iota expression is assumed
- // to have its final value.
+ // If this is not a numeric constant, return false. If it is one,
+ // return true, and set VAL to hold the value.
bool
- integer_constant_value(bool iota_is_constant, mpz_t val, Type** ptype) const;
-
- // If this is not a constant expression with floating point type,
- // return false. If it is one, return true, and set VAL to the
- // value. VAL should already be initialized. If this returns true,
- // it sets *PTYPE to the type of the value, or NULL for an abstract
- // type.
- bool
- float_constant_value(mpfr_t val, Type** ptype) const;
-
- // If this is not a constant expression with complex type, return
- // false. If it is one, return true, and set REAL and IMAG to the
- // value. REAL and IMAG should already be initialized. If this
- // return strue, it sets *PTYPE to the type of the value, or NULL
- // for an abstract type.
- bool
- complex_constant_value(mpfr_t real, mpfr_t imag, Type** ptype) const;
+ numeric_constant_value(Numeric_constant* val) const
+ { return this->do_numeric_constant_value(val); }
// If this is not a constant expression with string type, return
// false. If it is one, return true, and set VAL to the value.
@@ -691,22 +676,10 @@ class Expression
do_is_constant() const
{ return false; }
- // Return whether this is a constant expression of integral type,
- // and set VAL to the value.
- virtual bool
- do_integer_constant_value(bool, mpz_t, Type**) const
- { return false; }
-
- // Return whether this is a constant expression of floating point
- // type, and set VAL to the value.
+ // Return whether this is a constant expression of numeric type, and
+ // set the Numeric_constant to the value.
virtual bool
- do_float_constant_value(mpfr_t, Type**) const
- { return false; }
-
- // Return whether this is a constant expression of complex type, and
- // set REAL and IMAGE to the value.
- virtual bool
- do_complex_constant_value(mpfr_t, mpfr_t, Type**) const
+ do_numeric_constant_value(Numeric_constant*) const
{ return false; }
// Return whether this is a constant expression of string type, and
@@ -869,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()
@@ -1189,42 +1167,21 @@ class Binary_expression : public Expression
right()
{ return this->right_; }
- // Apply binary opcode OP to LEFT_VAL and RIGHT_VAL, setting VAL.
- // LEFT_TYPE is the type of LEFT_VAL, RIGHT_TYPE is the type of
- // RIGHT_VAL; LEFT_TYPE and/or RIGHT_TYPE may be NULL. Return true
- // if this could be done, false if not.
- static bool
- eval_integer(Operator op, Type* left_type, mpz_t left_val,
- Type* right_type, mpz_t right_val, Location,
- mpz_t val);
-
- // Apply binary opcode OP to LEFT_VAL and RIGHT_VAL, setting VAL.
- // Return true if this could be done, false if not.
+ // Apply binary opcode OP to LEFT_NC and RIGHT_NC, setting NC.
+ // Return true if this could be done, false if not. Issue errors at
+ // LOCATION as appropriate.
static bool
- eval_float(Operator op, Type* left_type, mpfr_t left_val,
- Type* right_type, mpfr_t right_val, mpfr_t val,
- Location);
-
- // Apply binary opcode OP to LEFT_REAL/LEFT_IMAG and
- // RIGHT_REAL/RIGHT_IMAG, setting REAL/IMAG. Return true if this
- // could be done, false if not.
- static bool
- eval_complex(Operator op, Type* left_type, mpfr_t left_real,
- mpfr_t left_imag, Type* right_type, mpfr_t right_real,
- mpfr_t right_imag, mpfr_t real, mpfr_t imag, Location);
-
- // Compare integer constants according to OP.
- static bool
- compare_integer(Operator op, mpz_t left_val, mpz_t right_val);
-
- // Compare floating point constants according to OP.
- static bool
- compare_float(Operator op, Type* type, mpfr_t left_val, mpfr_t right_val);
+ eval_constant(Operator op, Numeric_constant* left_nc,
+ Numeric_constant* right_nc, Location location,
+ Numeric_constant* nc);
- // Compare complex constants according to OP.
+ // Compare constants LEFT_NC and RIGHT_NC according to OP, setting
+ // *RESULT. Return true if this could be done, false if not. Issue
+ // errors at LOCATION as appropriate.
static bool
- compare_complex(Operator op, Type* type, mpfr_t left_real, mpfr_t left_imag,
- mpfr_t right_val, mpfr_t right_imag);
+ compare_constant(Operator op, Numeric_constant* left_nc,
+ Numeric_constant* right_nc, Location location,
+ bool* result);
static Expression*
do_import(Import*);
@@ -1246,13 +1203,7 @@ class Binary_expression : public Expression
{ return this->left_->is_constant() && this->right_->is_constant(); }
bool
- do_integer_constant_value(bool, mpz_t val, Type**) const;
-
- bool
- do_float_constant_value(mpfr_t val, Type**) const;
-
- bool
- do_complex_constant_value(mpfr_t real, mpfr_t imag, Type**) const;
+ do_numeric_constant_value(Numeric_constant*) const;
void
do_discarding_value();
@@ -1283,6 +1234,34 @@ class Binary_expression : public Expression
do_dump_expression(Ast_dump_context*) const;
private:
+ static bool
+ operation_type(Operator op, Type* left_type, Type* right_type,
+ Type** result_type);
+
+ static bool
+ cmp_to_bool(Operator op, int cmp);
+
+ static bool
+ eval_integer(Operator op, const Numeric_constant*, const Numeric_constant*,
+ Location, Numeric_constant*);
+
+ static bool
+ eval_float(Operator op, const Numeric_constant*, const Numeric_constant*,
+ Location, Numeric_constant*);
+
+ static bool
+ eval_complex(Operator op, const Numeric_constant*, const Numeric_constant*,
+ Location, Numeric_constant*);
+
+ static bool
+ compare_integer(const Numeric_constant*, const Numeric_constant*, int*);
+
+ static bool
+ compare_float(const Numeric_constant*, const Numeric_constant *, int*);
+
+ static bool
+ compare_complex(const Numeric_constant*, const Numeric_constant*, int*);
+
Expression*
lower_struct_comparison(Gogo*, Statement_inserter*);
@@ -2101,4 +2080,173 @@ class Receive_expression : public Expression
Expression* channel_;
};
+// A numeric constant. This is used both for untyped constants and
+// for constants that have a type.
+
+class Numeric_constant
+{
+ public:
+ Numeric_constant()
+ : classification_(NC_INVALID), type_(NULL)
+ { }
+
+ ~Numeric_constant();
+
+ Numeric_constant(const Numeric_constant&);
+
+ Numeric_constant& operator=(const Numeric_constant&);
+
+ // Set to an unsigned long value.
+ void
+ set_unsigned_long(Type*, unsigned long);
+
+ // Set to an integer value.
+ void
+ set_int(Type*, const mpz_t);
+
+ // Set to a rune value.
+ void
+ set_rune(Type*, const mpz_t);
+
+ // Set to a floating point value.
+ void
+ set_float(Type*, const mpfr_t);
+
+ // Set to a complex value.
+ void
+ set_complex(Type*, const mpfr_t, const mpfr_t);
+
+ // Classifiers.
+ bool
+ is_int() const
+ { return this->classification_ == Numeric_constant::NC_INT; }
+
+ bool
+ is_rune() const
+ { return this->classification_ == Numeric_constant::NC_RUNE; }
+
+ bool
+ is_float() const
+ { return this->classification_ == Numeric_constant::NC_FLOAT; }
+
+ bool
+ is_complex() const
+ { return this->classification_ == Numeric_constant::NC_COMPLEX; }
+
+ // Value retrievers. These will initialize the values as well as
+ // set them. GET_INT is only valid if IS_INT returns true, and
+ // likewise respectively.
+ void
+ get_int(mpz_t*) const;
+
+ void
+ get_rune(mpz_t*) const;
+
+ void
+ get_float(mpfr_t*) const;
+
+ void
+ get_complex(mpfr_t*, mpfr_t*) const;
+
+ // Codes returned by to_unsigned_long.
+ enum To_unsigned_long
+ {
+ // Value is integer and fits in unsigned long.
+ NC_UL_VALID,
+ // Value is not integer.
+ NC_UL_NOTINT,
+ // Value is integer but is negative.
+ NC_UL_NEGATIVE,
+ // Value is non-negative integer but does not fit in unsigned
+ // long.
+ NC_UL_BIG
+ };
+
+ // If the value can be expressed as an integer that fits in an
+ // unsigned long, set *VAL and return NC_UL_VALID. Otherwise return
+ // one of the other To_unsigned_long codes.
+ To_unsigned_long
+ to_unsigned_long(unsigned long* val) const;
+
+ // If the value can be expressed as an int, return true and
+ // initialize and set VAL. This will return false for a value with
+ // an explicit float or complex type, even if the value is integral.
+ bool
+ to_int(mpz_t* val) const;
+
+ // If the value can be expressed as a float, return true and
+ // initialize and set VAL.
+ bool
+ to_float(mpfr_t* val) const;
+
+ // If the value can be expressed as a complex, return true and
+ // initialize and set VR and VI.
+ bool
+ to_complex(mpfr_t* vr, mpfr_t* vi) const;
+
+ // Get the type.
+ Type*
+ type() const;
+
+ // If the constant can be expressed in TYPE, then set the type of
+ // the constant to TYPE and return true. Otherwise return false,
+ // and, if ISSUE_ERROR is true, issue an error message. LOCATION is
+ // the location to use for the error.
+ bool
+ set_type(Type* type, bool issue_error, Location location);
+
+ // Return an Expression for this value.
+ Expression*
+ expression(Location) const;
+
+ private:
+ void
+ clear();
+
+ To_unsigned_long
+ mpz_to_unsigned_long(const mpz_t ival, unsigned long *val) const;
+
+ To_unsigned_long
+ mpfr_to_unsigned_long(const mpfr_t fval, unsigned long *val) const;
+
+ bool
+ check_int_type(Integer_type*, bool, Location) const;
+
+ bool
+ check_float_type(Float_type*, bool, Location) const;
+
+ bool
+ check_complex_type(Complex_type*, bool, Location) const;
+
+ // The kinds of constants.
+ enum Classification
+ {
+ NC_INVALID,
+ NC_RUNE,
+ NC_INT,
+ NC_FLOAT,
+ NC_COMPLEX
+ };
+
+ // The kind of constant.
+ Classification classification_;
+ // The value.
+ union
+ {
+ // If NC_INT or NC_RUNE.
+ mpz_t int_val;
+ // If NC_FLOAT.
+ mpfr_t float_val;
+ // If NC_COMPLEX.
+ struct
+ {
+ mpfr_t real;
+ mpfr_t imag;
+ } complex_val;
+ } u_;
+ // The type if there is one. This will be NULL for an untyped
+ // constant.
+ Type* type_;
+};
+
#endif // !defined(GO_EXPRESSIONS_H)
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 5fe5aead9c0..ee68b69cc97 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -1653,8 +1653,12 @@ Finalize_methods::type(Type* t)
}
case Type::TYPE_STRUCT:
+ // Traverse the field types first in case there is an embedded
+ // field with methods that the struct should inherit.
+ if (t->struct_type()->traverse_field_types(this) == TRAVERSE_EXIT)
+ return TRAVERSE_EXIT;
t->struct_type()->finalize_methods(this->gogo_);
- break;
+ return TRAVERSE_SKIP_COMPONENTS;
default:
break;
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index 1a9c153a578..7207db58d0d 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -3971,7 +3971,7 @@ Parse::if_stat()
bool saw_simple_stat = false;
Expression* cond = NULL;
- bool saw_send_stmt;
+ bool saw_send_stmt = false;
if (this->simple_stat_may_start_here())
{
cond = this->simple_stat(false, &saw_send_stmt, NULL, NULL);
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 65c64c5e906..7f91e553a4d 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -3214,10 +3214,9 @@ class Case_clauses::Hash_integer_value
size_t
Case_clauses::Hash_integer_value::operator()(Expression* pe) const
{
- Type* itype;
+ Numeric_constant nc;
mpz_t ival;
- mpz_init(ival);
- if (!pe->integer_constant_value(true, ival, &itype))
+ if (!pe->numeric_constant_value(&nc) || !nc.to_int(&ival))
go_unreachable();
size_t ret = mpz_get_ui(ival);
mpz_clear(ival);
@@ -3236,14 +3235,14 @@ class Case_clauses::Eq_integer_value
bool
Case_clauses::Eq_integer_value::operator()(Expression* a, Expression* b) const
{
- Type* atype;
- Type* btype;
+ Numeric_constant anc;
mpz_t aval;
+ Numeric_constant bnc;
mpz_t bval;
- mpz_init(aval);
- mpz_init(bval);
- if (!a->integer_constant_value(true, aval, &atype)
- || !b->integer_constant_value(true, bval, &btype))
+ if (!a->numeric_constant_value(&anc)
+ || !anc.to_int(&aval)
+ || !b->numeric_constant_value(&bnc)
+ || !bnc.to_int(&bval))
go_unreachable();
bool ret = mpz_cmp(aval, bval) == 0;
mpz_clear(aval);
@@ -3431,18 +3430,17 @@ Case_clauses::Case_clause::get_backend(Translate_context* context,
Expression* e = *p;
if (e->classification() != Expression::EXPRESSION_INTEGER)
{
- Type* itype;
+ Numeric_constant nc;
mpz_t ival;
- mpz_init(ival);
- if (!(*p)->integer_constant_value(true, ival, &itype))
+ if (!(*p)->numeric_constant_value(&nc) || !nc.to_int(&ival))
{
// Something went wrong. This can happen with a
// negative constant and an unsigned switch value.
go_assert(saw_errors());
continue;
}
- go_assert(itype != NULL);
- e = Expression::make_integer(&ival, itype, e->location());
+ go_assert(nc.type() != NULL);
+ e = Expression::make_integer(&ival, nc.type(), e->location());
mpz_clear(ival);
}
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 03f1b3ea0c6..9e64a6ac84a 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -2230,15 +2230,13 @@ Type::is_backend_type_size_known(Gogo* gogo)
return true;
else
{
+ Numeric_constant nc;
+ if (!at->length()->numeric_constant_value(&nc))
+ return false;
mpz_t ival;
- mpz_init(ival);
- Type* dummy;
- bool length_known = at->length()->integer_constant_value(true,
- ival,
- &dummy);
- mpz_clear(ival);
- if (!length_known)
+ if (!nc.to_int(&ival))
return false;
+ mpz_clear(ival);
return at->element_type()->is_backend_type_size_known(gogo);
}
}
@@ -5106,17 +5104,22 @@ Array_type::is_identical(const Array_type* t, bool errors_are_identical) const
// Try to determine the lengths. If we can't, assume the arrays
// are not identical.
bool ret = false;
- mpz_t v1;
- mpz_init(v1);
- Type* type1;
- mpz_t v2;
- mpz_init(v2);
- Type* type2;
- if (l1->integer_constant_value(true, v1, &type1)
- && l2->integer_constant_value(true, v2, &type2))
- ret = mpz_cmp(v1, v2) == 0;
- mpz_clear(v1);
- mpz_clear(v2);
+ Numeric_constant nc1, nc2;
+ if (l1->numeric_constant_value(&nc1)
+ && l2->numeric_constant_value(&nc2))
+ {
+ mpz_t v1;
+ if (nc1.to_int(&v1))
+ {
+ mpz_t v2;
+ if (nc2.to_int(&v2))
+ {
+ ret = mpz_cmp(v1, v2) == 0;
+ mpz_clear(v2);
+ }
+ mpz_clear(v1);
+ }
+ }
return ret;
}
@@ -5154,58 +5157,44 @@ Array_type::verify_length()
return false;
}
- mpz_t val;
- mpz_init(val);
- Type* vt;
- if (!this->length_->integer_constant_value(true, val, &vt))
+ Numeric_constant nc;
+ if (!this->length_->numeric_constant_value(&nc))
{
- mpfr_t fval;
- mpfr_init(fval);
- if (!this->length_->float_constant_value(fval, &vt))
- {
- if (this->length_->type()->integer_type() != NULL
- || this->length_->type()->float_type() != NULL)
- error_at(this->length_->location(),
- "array bound is not constant");
- else
- error_at(this->length_->location(),
- "array bound is not numeric");
- mpfr_clear(fval);
- mpz_clear(val);
- return false;
- }
- if (!mpfr_integer_p(fval))
- {
- error_at(this->length_->location(),
- "array bound truncated to integer");
- mpfr_clear(fval);
- mpz_clear(val);
- return false;
- }
- mpz_init(val);
- mpfr_get_z(val, fval, GMP_RNDN);
- mpfr_clear(fval);
+ if (this->length_->type()->integer_type() != NULL
+ || this->length_->type()->float_type() != NULL)
+ error_at(this->length_->location(), "array bound is not constant");
+ else
+ error_at(this->length_->location(), "array bound is not numeric");
+ return false;
}
- if (mpz_sgn(val) < 0)
+ unsigned long val;
+ switch (nc.to_unsigned_long(&val))
{
+ case Numeric_constant::NC_UL_VALID:
+ break;
+ case Numeric_constant::NC_UL_NOTINT:
+ error_at(this->length_->location(), "array bound truncated to integer");
+ return false;
+ case Numeric_constant::NC_UL_NEGATIVE:
error_at(this->length_->location(), "negative array bound");
- mpz_clear(val);
return false;
+ case Numeric_constant::NC_UL_BIG:
+ error_at(this->length_->location(), "array bound overflows");
+ return false;
+ default:
+ go_unreachable();
}
Type* int_type = Type::lookup_integer_type("int");
- int tbits = int_type->integer_type()->bits();
- int vbits = mpz_sizeinbase(val, 2);
- if (vbits + 1 > tbits)
+ unsigned int tbits = int_type->integer_type()->bits();
+ if (sizeof(val) <= tbits * 8
+ && val >> (tbits - 1) != 0)
{
error_at(this->length_->location(), "array bound overflows");
- mpz_clear(val);
return false;
}
- mpz_clear(val);
-
return true;
}
@@ -5457,11 +5446,11 @@ Array_type::get_length_tree(Gogo* gogo)
go_assert(this->length_ != NULL);
if (this->length_tree_ == NULL_TREE)
{
+ Numeric_constant nc;
mpz_t val;
- mpz_init(val);
- Type* t;
- if (this->length_->integer_constant_value(true, val, &t))
+ if (this->length_->numeric_constant_value(&nc) && nc.to_int(&val))
{
+ Type* t = nc.type();
if (t == NULL)
t = Type::lookup_integer_type("int");
else if (t->is_abstract())
@@ -5472,8 +5461,6 @@ Array_type::get_length_tree(Gogo* gogo)
}
else
{
- mpz_clear(val);
-
// Make up a translation context for the array length
// expression. FIXME: This won't work in general.
Translate_context context(gogo, NULL, NULL, NULL);
@@ -5824,23 +5811,17 @@ Array_type::do_reflection(Gogo* gogo, std::string* ret) const
ret->push_back('[');
if (this->length_ != NULL)
{
- mpz_t val;
- mpz_init(val);
- Type* type;
- if (!this->length_->integer_constant_value(true, val, &type))
- error_at(this->length_->location(),
- "array length must be integer constant expression");
- else if (mpz_cmp_si(val, 0) < 0)
- error_at(this->length_->location(), "array length is negative");
- else if (mpz_cmp_ui(val, mpz_get_ui(val)) != 0)
- error_at(this->length_->location(), "array length is too large");
+ Numeric_constant nc;
+ unsigned long val;
+ if (!this->length_->numeric_constant_value(&nc)
+ || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
+ error_at(this->length_->location(), "invalid array length");
else
{
char buf[50];
- snprintf(buf, sizeof buf, "%lu", mpz_get_ui(val));
+ snprintf(buf, sizeof buf, "%lu", val);
ret->append(buf);
}
- mpz_clear(val);
}
ret->push_back(']');
@@ -5856,23 +5837,17 @@ Array_type::do_mangled_name(Gogo* gogo, std::string* ret) const
this->append_mangled_name(this->element_type_, gogo, ret);
if (this->length_ != NULL)
{
- mpz_t val;
- mpz_init(val);
- Type* type;
- if (!this->length_->integer_constant_value(true, val, &type))
- error_at(this->length_->location(),
- "array length must be integer constant expression");
- else if (mpz_cmp_si(val, 0) < 0)
- error_at(this->length_->location(), "array length is negative");
- else if (mpz_cmp_ui(val, mpz_get_ui(val)) != 0)
- error_at(this->length_->location(), "array size is too large");
+ Numeric_constant nc;
+ unsigned long val;
+ if (!this->length_->numeric_constant_value(&nc)
+ || nc.to_unsigned_long(&val) != Numeric_constant::NC_UL_VALID)
+ error_at(this->length_->location(), "invalid array length");
else
{
char buf[50];
- snprintf(buf, sizeof buf, "%lu", mpz_get_ui(val));
+ snprintf(buf, sizeof buf, "%lu", val);
ret->append(buf);
}
- mpz_clear(val);
}
ret->push_back('e');
}
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 3fe80488a49..edc46b72073 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -680,6 +680,14 @@ class Type
complex_type() const
{ return this->convert<const Complex_type, TYPE_COMPLEX>(); }
+ // Return whether this is a numeric type.
+ bool
+ is_numeric_type() const
+ {
+ Type_classification tc = this->base()->classification_;
+ return tc == TYPE_INTEGER || tc == TYPE_FLOAT || tc == TYPE_COMPLEX;
+ }
+
// Return true if this is a boolean type.
bool
is_boolean_type() const
diff --git a/gcc/go/gofrontend/unsafe.cc b/gcc/go/gofrontend/unsafe.cc
index bc949c6b56e..930723e0908 100644
--- a/gcc/go/gofrontend/unsafe.cc
+++ b/gcc/go/gofrontend/unsafe.cc
@@ -57,11 +57,11 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
if (add_to_globals)
this->add_named_type(pointer_type);
- Type* int_type = this->lookup_global("int")->type_value();
+ Type* uintptr_type = Type::lookup_integer_type("uintptr");
// Sizeof.
Typed_identifier_list* results = new Typed_identifier_list;
- results->push_back(Typed_identifier("", int_type, bloc));
+ results->push_back(Typed_identifier("", uintptr_type, bloc));
Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc);
fntype->set_is_builtin();
no = bindings->add_function_declaration("Sizeof", package, fntype, bloc);
@@ -70,7 +70,7 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
// Offsetof.
results = new Typed_identifier_list;
- results->push_back(Typed_identifier("", int_type, bloc));
+ results->push_back(Typed_identifier("", uintptr_type, bloc));
fntype = Type::make_function_type(NULL, NULL, results, bloc);
fntype->set_is_varargs();
fntype->set_is_builtin();
@@ -80,7 +80,7 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported,
// Alignof.
results = new Typed_identifier_list;
- results->push_back(Typed_identifier("", int_type, bloc));
+ results->push_back(Typed_identifier("", uintptr_type, bloc));
fntype = Type::make_function_type(NULL, NULL, results, bloc);
fntype->set_is_varargs();
fntype->set_is_builtin();
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 daf5fa07410..03f8f610c97 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -42,15 +42,28 @@ along with GCC; see the file COPYING3. If not see
void
loop_optimizer_init (unsigned flags)
{
- struct loops *loops;
+ if (!current_loops)
+ {
+ struct loops *loops = ggc_alloc_cleared_loops ();
+
+ gcc_assert (!(cfun->curr_properties & PROP_loops));
+
+ /* Find the loops. */
- gcc_assert (!current_loops);
- loops = ggc_alloc_cleared_loops ();
+ flow_loops_find (loops);
+ current_loops = loops;
+ }
+ else
+ {
+ gcc_assert (cfun->curr_properties & PROP_loops);
- /* Find the loops. */
+ /* Ensure that the dominators are computed, like flow_loops_find does. */
+ calculate_dominance_info (CDI_DOMINATORS);
- flow_loops_find (loops);
- current_loops = loops;
+#ifdef ENABLE_CHECKING
+ verify_loop_structure ();
+#endif
+ }
if (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
{
@@ -104,6 +117,22 @@ loop_optimizer_finalize (void)
struct loop *loop;
basic_block bb;
+ if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
+ release_recorded_exits ();
+
+ /* If we should preserve loop structure, do not free it but clear
+ flags that advanced properties are there as we are not preserving
+ that in full. */
+ if (cfun->curr_properties & PROP_loops)
+ {
+ loops_state_clear (LOOP_CLOSED_SSA
+ | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
+ | LOOPS_HAVE_PREHEADERS
+ | LOOPS_HAVE_SIMPLE_LATCHES
+ | LOOPS_HAVE_FALLTHRU_PREHEADERS);
+ return;
+ }
+
gcc_assert (current_loops != NULL);
FOR_EACH_LOOP (li, loop, 0)
@@ -112,8 +141,6 @@ loop_optimizer_finalize (void)
}
/* Clean up. */
- if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
- release_recorded_exits ();
flow_loops_free (current_loops);
ggc_free (current_loops);
current_loops = NULL;
@@ -131,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 =
@@ -200,6 +236,8 @@ struct rtl_opt_pass pass_rtl_loop_init =
static unsigned int
rtl_loop_done (void)
{
+ /* No longer preserve loops, remove them now. */
+ cfun->curr_properties &= ~PROP_loops;
loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
@@ -223,7 +261,7 @@ struct rtl_opt_pass pass_rtl_loop_done =
TV_LOOP, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
- 0, /* properties_destroyed */
+ PROP_loops, /* properties_destroyed */
0, /* todo_flags_start */
TODO_verify_flow
| TODO_verify_rtl_sharing /* todo_flags_finish */
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 84986efcdda..ec1a5522d7f 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1242,7 +1242,7 @@ finalize_task_copyfn (gimple task_stmt)
/* Inform the callgraph about the new function. */
DECL_STRUCT_FUNCTION (child_fn)->curr_properties
- = cfun->curr_properties;
+ = cfun->curr_properties & ~PROP_loops;
old_fn = current_function_decl;
push_cfun (child_cfun);
@@ -3562,7 +3562,7 @@ expand_omp_taskreg (struct omp_region *region)
/* Inform the callgraph about the new function. */
DECL_STRUCT_FUNCTION (child_fn)->curr_properties
- = cfun->curr_properties;
+ = cfun->curr_properties & ~PROP_loops;
cgraph_add_new_function (child_fn, true);
/* Fix the callgraph edges for child_cfun. Those for cfun will be
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 6231db2965c..ca5c35adce8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,128 @@
+2012-04-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/pack18.adb: New test.
+ * gnat.dg/pack18_pkg.ads: New helper.
+
+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
+ * g++.dg/overload/virtual2.C: New.
+
+2012-03-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/vect7.ad[sb]: New test.
+
+2012-03-28 Paul Thomas <pault@gcc.gnu.org>
+ Tobias Burnus <burnus@gcc.gnu.org>
+
+ PR fortran/52652
+ * gfortran.dg/allocate_class_1.f90 : Change error test.
+ * gfortran.dg/allocate_with_typespec_4.f90 : Change error test.
+ * gfortran.dg/allocate_alloc_opt_1.f90 : Change error test.
+ * gfortran.dg/deallocate_alloc_opt_1.f90 : Change error test.
+
+2012-03-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/52691
+ * gcc.dg/pr52691.c: New test.
+
+ PR middle-end/52750
+ * gcc.c-torture/compile/pr52750.c: New test.
+
+2012-03-28 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/52692
+ * gcc.target/avr/torture/builtins-2.c: New test.
+
+2012-03-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/52736
+ * gcc.target/i386/pr52736.c: New test.
+
2012-03-27 Martin Jambor <mjambor@suse.cz>
PR middle-end/52693
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/overload/virtual2.C b/gcc/testsuite/g++.dg/overload/virtual2.C
new file mode 100644
index 00000000000..c93ba9e2988
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/virtual2.C
@@ -0,0 +1,31 @@
+// PR c++/52746
+// { dg-do run }
+
+extern "C" int printf(const char*,...);
+extern "C" void abort();
+bool db;
+
+struct A
+{
+ virtual ~A() {}
+};
+
+struct B : public A
+{
+ virtual ~B() { db = true; }
+};
+
+template<int> void test()
+{
+ B * b = new B;
+ A * a = b;
+ a->~A();
+ ::operator delete(b);
+}
+
+int main()
+{
+ test<0>();
+ if (!db)
+ abort();
+}
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/compile/pr52750.c b/gcc/testsuite/gcc.c-torture/compile/pr52750.c
new file mode 100644
index 00000000000..36391bac5d9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr52750.c
@@ -0,0 +1,11 @@
+/* PR middle-end/52750 */
+
+typedef signed char V __attribute__((vector_size (32)));
+
+void
+foo (V *x)
+{
+ V m = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
+ *x = __builtin_shuffle (*x, m);
+}
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/pr52691.c b/gcc/testsuite/gcc.dg/pr52691.c
new file mode 100644
index 00000000000..7a2d7d8ebb1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr52691.c
@@ -0,0 +1,24 @@
+/* PR middle-end/52691 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include <stdarg.h>
+
+int
+foo (int a, ...)
+{
+ int b = 0, c = 0;
+ va_list ap;
+ va_start (ap, a);
+ if (a > 1)
+ b = va_arg (ap, double);
+ if (a > 2)
+ c = va_arg (ap, long long);
+ va_end (ap);
+ return a + b + c;
+}
+
+/* { dg-final { scan-tree-dump "__builtin_next_arg" "optimized" { target { { i?86-*-* x86_64-*-* } && ia32 } } } } */
+/* { dg-final { scan-tree-dump "__builtin_next_arg" "optimized" { target { powerpc*-*-darwin* powerpc*-*-aix* } } } } */
+/* { dg-final { scan-tree-dump "__builtin_next_arg" "optimized" { target { powerpc*-*-linux* && lp64 } } } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
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/avr/torture/builtins-2.c b/gcc/testsuite/gcc.target/avr/torture/builtins-2.c
new file mode 100644
index 00000000000..ae207d9a939
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/torture/builtins-2.c
@@ -0,0 +1,46 @@
+/* { dg-options "-std=gnu99 -Tavr51-flash1.x" } */
+/* { dg-do run } */
+
+#include <stdlib.h>
+#include "../progmem.h"
+
+int volatile a;
+
+void f1 (void)
+{
+ __builtin_avr_sei ();
+ __builtin_avr_cli ();
+ __builtin_avr_wdr ();
+ __builtin_avr_sleep ();
+ __builtin_avr_nop ();
+ a = __builtin_avr_swap (a);
+ a = __builtin_avr_fmul (1,a);
+ a = __builtin_avr_fmuls (1,a);
+ a = __builtin_avr_fmulsu (1,a);
+ a = __builtin_avr_insert_bits (0x1f2f5364, a, a);
+}
+
+const __flash char c0 = 1;
+const __flash1 char c1 = 1;
+
+int main (void)
+{
+ const __memx void *p;
+
+ f1();
+ __builtin_avr_delay_cycles (1000);
+
+ p = &c0;
+ if (__builtin_avr_flash_segment (p) != 0)
+ abort();
+
+ p = &c1;
+ if (__builtin_avr_flash_segment (p) != 1)
+ abort();
+
+ if (__builtin_avr_flash_segment ("p") != -1)
+ abort();
+
+ exit (0);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr52736.c b/gcc/testsuite/gcc.target/i386/pr52736.c
new file mode 100644
index 00000000000..f35c1fd6c66
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr52736.c
@@ -0,0 +1,29 @@
+/* PR target/52736 */
+/* { dg-do run } */
+/* { dg-options "-O1 -msse2" } */
+/* { dg-require-effective-target sse2_runtime } */
+
+#include <x86intrin.h>
+
+typedef double D __attribute__((may_alias));
+__attribute__((aligned(16))) static const double r[4] = { 1., 5., 1., 3. };
+
+__attribute__((noinline, noclone))
+void
+foo (int x)
+{
+ asm volatile ("" : "+g" (x) : : "memory");
+ if (x != 3)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ __m128d t = _mm_set1_pd (5.);
+ ((D *)(&t))[0] = 1.;
+ foo (_mm_movemask_pd (_mm_cmpeq_pd (t, _mm_load_pd (&r[0]))));
+ ((D *)(&t))[1] = 3.;
+ foo (_mm_movemask_pd (_mm_cmpeq_pd (t, _mm_load_pd (&r[2]))));
+ return 0;
+}
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/allocate_alloc_opt_1.f90 b/gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90
index 52e0262f4e6..3a05e8cff02 100644
--- a/gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90
+++ b/gcc/testsuite/gfortran.dg/allocate_alloc_opt_1.f90
@@ -24,7 +24,7 @@ program a
allocate(i(2), errmsg=err) ! { dg-warning "useless without a STAT" }
allocate(i(2), stat=j, errmsg=x) ! { dg-error "must be a scalar CHARACTER" }
- allocate(err) ! { dg-error "nonprocedure pointer or an allocatable" }
+ allocate(err) ! { dg-error "neither a nonprocedure pointer nor an allocatable" }
allocate(error(2),stat=j,errmsg=error(1)) ! { dg-error "shall not be ALLOCATEd within" }
allocate(i(2), stat = i(1)) ! { dg-error "shall not be ALLOCATEd within" }
diff --git a/gcc/testsuite/gfortran.dg/allocate_class_1.f90 b/gcc/testsuite/gfortran.dg/allocate_class_1.f90
index 1dea056b74f..9a2a5cb2538 100644
--- a/gcc/testsuite/gfortran.dg/allocate_class_1.f90
+++ b/gcc/testsuite/gfortran.dg/allocate_class_1.f90
@@ -7,5 +7,5 @@
type :: t0
end type
class(t0) :: x ! { dg-error "must be dummy, allocatable or pointer" }
- allocate(x) ! { dg-error "is not a nonprocedure pointer or an allocatable variable" }
+ allocate(x) ! { dg-error "is neither a nonprocedure pointer nor an allocatable variable" }
end
diff --git a/gcc/testsuite/gfortran.dg/allocate_with_typespec_4.f90 b/gcc/testsuite/gfortran.dg/allocate_with_typespec_4.f90
index 327f28dcdc9..54ed109fc24 100644
--- a/gcc/testsuite/gfortran.dg/allocate_with_typespec_4.f90
+++ b/gcc/testsuite/gfortran.dg/allocate_with_typespec_4.f90
@@ -21,7 +21,7 @@ subroutine not_an_f03_intrinsic
allocate(real*8 :: y(1)) ! { dg-error "Invalid type-spec at" }
allocate(real*4 :: x8) ! { dg-error "Invalid type-spec at" }
allocate(real*4 :: y8(1)) ! { dg-error "Invalid type-spec at" }
- allocate(double complex :: d1) ! { dg-error "not a nonprocedure pointer or an allocatable" }
+ allocate(double complex :: d1) ! { dg-error "neither a nonprocedure pointer nor an allocatable" }
allocate(real_type :: b)
allocate(real_type :: c(1))
diff --git a/gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90 b/gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90
index 5c00741f61c..969ce257efe 100644
--- a/gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90
+++ b/gcc/testsuite/gfortran.dg/deallocate_alloc_opt_1.f90
@@ -24,7 +24,7 @@ program a
deallocate(i, errmsg=err) ! { dg-warning "useless without a STAT" }
deallocate(i, stat=j, errmsg=x) ! { dg-error "must be a scalar CHARACTER" }
- deallocate(err) ! { dg-error "nonprocedure pointer or an allocatable" }
+ deallocate(err) ! { dg-error "nonprocedure pointer nor an allocatable" }
deallocate(error,stat=j,errmsg=error(1)) ! { dg-error "shall not be DEALLOCATEd within" }
deallocate(i, stat = i(1)) ! { dg-error "shall not be DEALLOCATEd within" }
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/pack18.adb b/gcc/testsuite/gnat.dg/pack18.adb
new file mode 100644
index 00000000000..857a6f9787e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/pack18.adb
@@ -0,0 +1,12 @@
+-- { dg-do run }
+
+with Pack18_Pkg; use Pack18_Pkg;
+
+procedure Pack18 is
+ use Pack18_Pkg.Attributes_Tables;
+ Table : Instance;
+begin
+ Init (Table);
+ Set_Last (Table, 1);
+ Table.Table (Last (Table)).N := 0;
+end;
diff --git a/gcc/testsuite/gnat.dg/pack18_pkg.ads b/gcc/testsuite/gnat.dg/pack18_pkg.ads
new file mode 100644
index 00000000000..2b63fbab063
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/pack18_pkg.ads
@@ -0,0 +1,21 @@
+with GNAT.Dynamic_Tables;
+
+package Pack18_Pkg is
+
+ type String_Access is access String;
+
+ type Rec is record
+ S : String_Access;
+ B : Boolean;
+ N : Natural;
+ end record;
+ pragma Pack (Rec);
+
+ package Attributes_Tables is new GNAT.Dynamic_Tables
+ (Table_Component_Type => Rec,
+ Table_Index_Type => Natural,
+ Table_Low_Bound => 1,
+ Table_Initial => 200,
+ Table_Increment => 200);
+
+end Pack18_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/testsuite/gnat.dg/vect7.adb b/gcc/testsuite/gnat.dg/vect7.adb
new file mode 100644
index 00000000000..7911cc812c6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/vect7.adb
@@ -0,0 +1,20 @@
+-- { dg-do compile }
+
+package body Vect7 is
+
+ procedure Assign is
+ v1 : constant v4sf := (-1.0, -2.0, -3.0, -4.0);
+ v2 : v4sf := v1;
+ v3 : v4sf;
+ begin
+ v3 := vzero;
+ v3 := vconst;
+ v3 := v1;
+ v3 := v2;
+ v3 := (1.0, -2.0, 3.0, -4.0);
+ v3 := (1.0, -2.0, 3.0, F);
+
+ v2 := vzero;
+ end;
+
+end Vect7;
diff --git a/gcc/testsuite/gnat.dg/vect7.ads b/gcc/testsuite/gnat.dg/vect7.ads
new file mode 100644
index 00000000000..faf01679e23
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/vect7.ads
@@ -0,0 +1,15 @@
+package Vect7 is
+
+ type v4sf is array (1 .. 4) of Float;
+ for v4sf'Alignment use 16;
+ pragma Machine_Attribute (v4sf, "vector_type");
+
+ vzero : constant v4sf := (0.0, 0.0, 0.0, 0.0);
+ vconst : constant v4sf := (1.0, 2.0, 3.0, 4.0);
+ vvar : v4sf := vconst;
+
+ F : Float := 5.0;
+
+ procedure Assign;
+
+end Vect7;
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/trans-mem.c b/gcc/trans-mem.c
index 2badf250650..65f40e69c1b 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -34,6 +34,7 @@
#include "langhooks.h"
#include "tree-pretty-print.h"
#include "gimple-pretty-print.h"
+#include "cfgloop.h"
#define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 2000 - 1)
@@ -1270,6 +1271,12 @@ tm_log_emit_save_or_restores (basic_block entry_block,
cond_bb = create_empty_bb (before_bb);
code_bb = create_empty_bb (cond_bb);
*end_bb = create_empty_bb (code_bb);
+ if (current_loops && before_bb->loop_father)
+ {
+ add_bb_to_loop (cond_bb, before_bb->loop_father);
+ add_bb_to_loop (code_bb, before_bb->loop_father);
+ add_bb_to_loop (*end_bb, before_bb->loop_father);
+ }
redirect_edge_pred (fallthru_edge, *end_bb);
fallthru_edge->flags = EDGE_FALLTHRU;
make_edge (before_bb, cond_bb, old_flags);
@@ -2682,6 +2689,8 @@ expand_transaction (struct tm_region *region)
basic_block test_bb;
test_bb = create_empty_bb (slice_bb);
+ if (current_loops && slice_bb->loop_father)
+ add_bb_to_loop (test_bb, slice_bb->loop_father);
if (VEC_empty (tree, tm_log_save_addresses))
region->entry_block = test_bb;
gsi = gsi_last_bb (test_bb);
@@ -2719,6 +2728,8 @@ expand_transaction (struct tm_region *region)
basic_block empty_bb;
region->entry_block = empty_bb = create_empty_bb (atomic_bb);
+ if (current_loops && atomic_bb->loop_father)
+ add_bb_to_loop (empty_bb, atomic_bb->loop_father);
e = FALLTHRU_EDGE (atomic_bb);
redirect_edge_pred (e, empty_bb);
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-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 0c8c0852024..d28783b6b98 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -793,7 +793,6 @@ repair_loop_structures (void)
#endif
scev_reset ();
- loops_state_clear (LOOPS_NEED_FIXUP);
timevar_pop (TV_REPAIR_LOOPS);
}
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-eh.c b/gcc/tree-eh.c
index 521e2f7f44a..f19dc2cdffb 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "gimple.h"
#include "target.h"
+#include "cfgloop.h"
/* In some instances a tree and a gimple need to be stored in a same table,
i.e. in hash tables. This is a structure to do this. */
@@ -3041,6 +3042,8 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
gimple_stmt_iterator gsi2;
new_bb = create_empty_bb (bb);
+ if (current_loops)
+ add_bb_to_loop (new_bb, bb->loop_father);
lab = gimple_block_label (new_bb);
gsi2 = gsi_start_bb (new_bb);
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 319be2bb618..3dd6a7d019d 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -794,10 +794,7 @@ extern bool verify_eh_dispatch_edge (gimple);
extern void maybe_remove_unreachable_handlers (void);
/* In tree-ssa-pre.c */
-struct pre_expr_d;
-void add_to_value (unsigned int, struct pre_expr_d *);
void debug_value_expressions (unsigned int);
-void print_value_expressions (FILE *, unsigned int);
/* In tree-ssa-sink.c */
bool is_hidden_global_store (gimple);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 5d58c5169bb..d61b6b6a023 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -2093,7 +2093,7 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count)
cfun->static_chain_decl = src_cfun->static_chain_decl;
cfun->nonlocal_goto_save_area = src_cfun->nonlocal_goto_save_area;
cfun->function_end_locus = src_cfun->function_end_locus;
- cfun->curr_properties = src_cfun->curr_properties;
+ cfun->curr_properties = src_cfun->curr_properties & ~PROP_loops;
cfun->last_verified = src_cfun->last_verified;
cfun->va_list_gpr_size = src_cfun->va_list_gpr_size;
cfun->va_list_fpr_size = src_cfun->va_list_fpr_size;
diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c
index e4f6ec0b331..cc8b98d1ea4 100644
--- a/gcc/tree-mudflap.c
+++ b/gcc/tree-mudflap.c
@@ -45,6 +45,8 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "gimple.h"
+extern void add_bb_to_loop (basic_block, struct loop *);
+
/* Internal function decls */
@@ -560,6 +562,10 @@ mf_build_check_statement_for (tree base, tree limit,
set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb);
}
+ /* Update loop info. */
+ if (current_loops)
+ add_bb_to_loop (then_bb, cond_bb->loop_father);
+
/* Build our local variables. */
mf_elem = make_rename_temp (mf_cache_structptr_type, "__mf_elem");
mf_base = make_rename_temp (mf_uintptr_type, "__mf_base");
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index f5cffa3375b..f849a542465 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -239,6 +239,7 @@ struct dump_file_info
#define PROP_gimple_lomp (1 << 8) /* lowered OpenMP directives */
#define PROP_cfglayout (1 << 9) /* cfglayout mode on RTL */
#define PROP_gimple_lcx (1 << 10) /* lowered complex */
+#define PROP_loops (1 << 11) /* preserve loop structures */
#define PROP_trees \
(PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_lomp)
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 2080c06cce6..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
@@ -2288,7 +2289,7 @@ optimize_stdarg_builtin (gimple call)
case BUILT_IN_VA_START:
if (!va_list_simple_ptr
|| targetm.expand_builtin_va_start != NULL
- || builtin_decl_explicit_p (BUILT_IN_NEXT_ARG))
+ || !builtin_decl_explicit_p (BUILT_IN_NEXT_ARG))
return NULL_TREE;
if (gimple_call_num_args (call) != 2)
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-loop.c b/gcc/tree-ssa-loop.c
index 91eeb16cec9..a91bf3919ad 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -92,7 +92,7 @@ struct gimple_opt_pass pass_tree_loop_init =
0, /* static_pass_number */
TV_TREE_LOOP_INIT, /* tv_id */
PROP_cfg, /* properties_required */
- 0, /* properties_provided */
+ PROP_loops, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0 /* todo_flags_finish */
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 3f17e8bce02..6a2ce643d74 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -587,7 +587,7 @@ phi_trans_add (pre_expr e, pre_expr v, basic_block pred)
/* Add expression E to the expression set of value id V. */
-void
+static void
add_to_value (unsigned int v, pre_expr e)
{
bitmap_set_t set;
@@ -1031,7 +1031,7 @@ debug_bitmap_set (bitmap_set_t set)
/* Print out the expressions that have VAL to OUTFILE. */
-void
+static void
print_value_expressions (FILE *outfile, unsigned int val)
{
bitmap_set_t set = VEC_index (bitmap_set_t, value_expressions, val);
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 6000a0331c0..687eee0485a 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -624,6 +624,7 @@ thread_block (basic_block bb, bool noloop_only)
{
loop->header = NULL;
loop->latch = NULL;
+ loops_state_set (LOOPS_NEED_FIXUP);
}
}
@@ -825,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. */
@@ -969,6 +981,7 @@ thread_through_loop_header (struct loop *loop, bool may_peel_loop_headers)
original header. */
loop->header = NULL;
loop->latch = NULL;
+ loops_state_set (LOOPS_NEED_FIXUP);
return thread_block (header, false);
}
@@ -988,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-generic.c b/gcc/tree-vect-generic.c
index 203f62caec7..a865fec5d81 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -1,5 +1,5 @@
/* Lower vector operations to scalar operations.
- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -567,8 +567,9 @@ vector_element (gimple_stmt_iterator *gsi, tree vect, tree idx, tree *ptmpvec)
else
{
tree size = TYPE_SIZE (vect_elt_type);
- tree pos = fold_build2 (MULT_EXPR, TREE_TYPE (idx), idx, size);
- return fold_build3 (BIT_FIELD_REF, vect_elt_type, vect, size, pos);
+ tree pos = fold_build2 (MULT_EXPR, bitsizetype, bitsize_int (index),
+ size);
+ return fold_build3 (BIT_FIELD_REF, vect_elt_type, vect, size, pos);
}
}
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/tree.c b/gcc/tree.c
index cfea9f7b88d..7c7e43a5a88 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -724,6 +724,10 @@ tree_size (const_tree node)
return (sizeof (struct tree_vec)
+ (TREE_VEC_LENGTH (node) - 1) * sizeof (tree));
+ case VECTOR_CST:
+ return (sizeof (struct tree_vector)
+ + (TYPE_VECTOR_SUBPARTS (TREE_TYPE (node)) - 1) * sizeof (tree));
+
case STRING_CST:
return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1;
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 216a142d0c4..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,
@@ -32,11 +40,28 @@
windows-like hosts.
* configure: Rebuilt.
+2012-02-27 Mikael Pettersson <mikpe@it.uu.se>
+
+ PR libffi/52223
+ * Makefile.am (FLAGS_TO_PASS): Define.
+ * Makefile.in: Regenerate.
+
2012-02-23 Anthony Green <green@moxielogic.com>
* src/*/ffitarget.h: Ensure that users never include ffitarget.h
directly.
+2012-02-23 Kai Tietz <ktietz@redhat.com>
+
+ PR libffi/52221
+ * src/x86/ffi.c (ffi_closure_raw_THISCALL): New
+ prototype.
+ (ffi_prep_raw_closure_loc): Use ffi_closure_raw_THISCALL for
+ thiscall-convention.
+ (ffi_raw_call): Use ffi_prep_args_raw.
+ * src/x86/win32.S (ffi_closure_raw_THISCALL): Add
+ implementation for stub.
+
2012-02-10 Kai Tietz <ktietz@redhat.com>
* configure.ac (AM_LTLDFLAGS): Add -no-undefine for x64
@@ -262,6 +287,10 @@
* src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test,
just return FFI_BAD_ABI when things are wrong.
+2012-02-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * src/sparc/v9.S (STACKFRAME): Bump to 176.
+
2011-02-09 Stuart Shelton <srcshelton@gmail.com>
http://bugs.gentoo.org/show_bug.cgi?id=286911
@@ -790,6 +819,13 @@
* src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE
type on HP-UX.
+2012-02-13 Kai Tietz <ktietz@redhat.com>
+
+ PR libffi/52221
+ * src/x86/ffi.c (ffi_prep_raw_closure_loc): Add thiscall
+ support for X86_WIN32.
+ (FFI_INIT_TRAMPOLINE_THISCALL): Fix displacement.
+
2009-12-11 Eric Botcazou <ebotcazou@adacore.com>
* src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long
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/libffi/src/sparc/v9.S b/libffi/src/sparc/v9.S
index 489ff0293f2..bf31a2b5110 100644
--- a/libffi/src/sparc/v9.S
+++ b/libffi/src/sparc/v9.S
@@ -32,7 +32,7 @@
/* Only compile this in for 64bit builds, because otherwise the object file
will have inproper architecture due to used instructions. */
-#define STACKFRAME 128 /* Minimum stack framesize for SPARC */
+#define STACKFRAME 176 /* Minimum stack framesize for SPARC 64-bit */
#define STACK_BIAS 2047
#define ARGS (128) /* Offset of register area in frame */
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c
index 9343c260728..f643b345cba 100644
--- a/libffi/src/x86/ffi.c
+++ b/libffi/src/x86/ffi.c
@@ -426,6 +426,8 @@ unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
__attribute__ ((regparm(1)));
#ifdef X86_WIN32
+void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
+ __attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *)
@@ -593,7 +595,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
- unsigned int __dis = __fun - (__ctx + 22); \
+ unsigned int __dis = __fun - (__ctx + 49); \
unsigned short __size = (unsigned short)(SIZE); \
*(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \
*(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \
@@ -699,6 +701,9 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
int i;
if (cif->abi != FFI_SYSV) {
+#ifdef X86_WIN32
+ if (cif->abi != FFI_THISCALL)
+#endif
return FFI_BAD_ABI;
}
@@ -713,10 +718,20 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
}
-
+#ifdef X86_WIN32
+ if (cif->abi == FFI_SYSV)
+ {
+#endif
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
codeloc);
-
+#ifdef X86_WIN32
+ }
+ else if (cif->abi == FFI_THISCALL)
+ {
+ FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL,
+ codeloc, cif->bytes);
+ }
+#endif
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
@@ -761,7 +776,7 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
#ifdef X86_WIN32
case FFI_SYSV:
case FFI_STDCALL:
- ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags,
+ ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
case FFI_THISCALL:
@@ -789,7 +804,7 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
cif->abi = abi = FFI_THISCALL;
if (passed_regs < 1 && abi == FFI_THISCALL)
cif->abi = abi = FFI_STDCALL;
- ffi_call_win32(ffi_prep_args, &ecif, abi, cif->bytes, cif->flags,
+ ffi_call_win32(ffi_prep_args_raw, &ecif, abi, cif->bytes, cif->flags,
ecif.rvalue, fn);
}
break;
diff --git a/libffi/src/x86/win32.S b/libffi/src/x86/win32.S
index e5c93ecf7b9..deb4a0394d8 100644
--- a/libffi/src/x86/win32.S
+++ b/libffi/src/x86/win32.S
@@ -264,6 +264,18 @@ ffi_closure_SYSV ENDP
#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
#define CIF_FLAGS_OFFSET 20
+ffi_closure_raw_THISCALL PROC NEAR
+ push ebp
+ mov ebp, esp
+ push esi
+ sub esp, 36
+ mov esi, [eax + RAW_CLOSURE_CIF_OFFSET] ;; closure->cif
+ mov edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET] ;; closure->user_data
+ mov [esp + 12], edx
+ lea edx, [ebp + 12], edx
+ jmp stubraw
+ffi_closure_raw_SYSV ENDP
+
ffi_closure_raw_SYSV PROC NEAR USES esi
;; the ffi_closure ctx is passed in eax by the trampoline.
@@ -272,6 +284,7 @@ ffi_closure_raw_SYSV PROC NEAR USES esi
mov edx, [eax + RAW_CLOSURE_USER_DATA_OFFSET] ;; closure->user_data
mov [esp + 12], edx ;; user_data
lea edx, [ebp + 8]
+stubraw:
mov [esp + 8], edx ;; raw_args
lea edx, [ebp - 24]
mov [esp + 4], edx ;; &res
@@ -722,7 +735,21 @@ _ffi_closure_SYSV:
#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
#define CIF_FLAGS_OFFSET 20
-
+ .balign 16
+ .globl _ffi_closure_raw_THISCALL
+#ifndef __OS2__
+ .def _ffi_closure_raw_THISCALL; .scl 2; .type 32; .endef
+#endif
+_ffi_closure_raw_THISCALL:
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %esi
+ subl $36, %esp
+ movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */
+ movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+ movl %edx, 12(%esp) /* user_data */
+ leal 12(%ebp), %edx /* __builtin_dwarf_cfa () */
+ jmp .stubraw
# This assumes we are using gas.
.balign 16
.globl _ffi_closure_raw_SYSV
@@ -742,6 +769,7 @@ _ffi_closure_raw_SYSV:
movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
movl %edx, 12(%esp) /* user_data */
leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */
+.stubraw:
movl %edx, 8(%esp) /* raw_args */
leal -24(%ebp), %edx
movl %edx, 4(%esp) /* &res */
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index be35f81e0ad..354b3ceedf8 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,24 @@
+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
+ only for glibc.
+
+2012-03-28 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/52737
+ * config/avr/lib1funcs.S: Use __AVR_HAVE_SPH__ for SP_H checks
+ instead of __AVR_HAVE_8BIT_SP__.
+
2012-03-26 Tristan Gingold <gingold@adacore.com>
* config/ia64/unwind-ia64.h: Declare unw_word and unw_sword.
diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S
index 9bd235bb7b0..95a7d3d4eeb 100644
--- a/libgcc/config/avr/lib1funcs.S
+++ b/libgcc/config/avr/lib1funcs.S
@@ -25,7 +25,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define __zero_reg__ r1
#define __tmp_reg__ r0
#define __SREG__ 0x3f
+#if defined (__AVR_HAVE_SPH__)
#define __SP_H__ 0x3e
+#endif
#define __SP_L__ 0x3d
#define __RAMPZ__ 0x3B
#define __EIND__ 0x3C
@@ -1258,7 +1260,7 @@ ENDF __divmodsi4
#if defined (__AVR_HAVE_JMP_CALL__)
# define SPEED_DIV 8
-#elif defined (__AVR_HAVE_MOVW__) && !defined (__AVR_HAVE_8BIT_SP__)
+#elif defined (__AVR_HAVE_MOVW__) && defined (__AVR_HAVE_SPH__)
# define SPEED_DIV 16
#else
# define SPEED_DIV 0
@@ -1540,10 +1542,10 @@ DEFUN __divdi3_moddi3
4: ;; Epilogue: Restore the Z = 12 Registers and return
in r28, __SP_L__
-#if defined (__AVR_HAVE_8BIT_SP__)
- clr r29
-#else
+#if defined (__AVR_HAVE_SPH__)
in r29, __SP_H__
+#else
+ clr r29
#endif /* #SP = 8/16 */
ldi r30, 12
XJMP __epilogue_restores__ + ((18 - 12) * 2)
@@ -1691,7 +1693,7 @@ DEFUN __prologue_saves__
push r17
push r28
push r29
-#if defined (__AVR_HAVE_8BIT_SP__)
+#if !defined (__AVR_HAVE_SPH__)
in r28,__SP_L__
sub r28,r26
out __SP_L__,r28
@@ -1747,7 +1749,7 @@ DEFUN __epilogue_restores__
ldd r16,Y+4
ldd r17,Y+3
ldd r26,Y+2
-#if defined (__AVR_HAVE_8BIT_SP__)
+#if !defined (__AVR_HAVE_SPH__)
ldd r29,Y+1
add r28,r30
out __SP_L__,r28
diff --git a/libgcc/config/i386/linux-unwind.h b/libgcc/config/i386/linux-unwind.h
index f17a46cc8e7..ad0ccfa0be7 100644
--- a/libgcc/config/i386/linux-unwind.h
+++ b/libgcc/config/i386/linux-unwind.h
@@ -29,11 +29,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#ifndef inhibit_libc
-#ifdef __x86_64__
+/* There's no sys/ucontext.h for glibc 2.0, so no
+ signal-turned-exceptions for them. There's also no configure-run for
+ the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H. Using the
+ target libc version macro should be enough. */
+#if defined __GLIBC__ && !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
#include <signal.h>
#include <sys/ucontext.h>
+#ifdef __x86_64__
+
#define MD_FALLBACK_FRAME_STATE_FOR x86_64_fallback_frame_state
static _Unwind_Reason_Code
@@ -48,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)
@@ -108,15 +114,6 @@ x86_64_fallback_frame_state (struct _Unwind_Context *context,
#else /* ifdef __x86_64__ */
-/* There's no sys/ucontext.h for glibc 2.0, so no
- signal-turned-exceptions for them. There's also no configure-run for
- the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H. Using the
- target libc version macro should be enough. */
-#if defined __GLIBC__ && !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
-
-#include <signal.h>
-#include <sys/ucontext.h>
-
#define MD_FALLBACK_FRAME_STATE_FOR x86_fallback_frame_state
static _Unwind_Reason_Code
@@ -197,6 +194,6 @@ x86_frob_update_context (struct _Unwind_Context *context,
_Unwind_SetSignalFrame (context, 1);
}
-#endif /* not glibc 2.0 */
#endif /* ifdef __x86_64__ */
+#endif /* not glibc 2.0 */
#endif /* ifdef inhibit_libc */
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/dir.go b/libgo/go/os/dir.go
index f119a214639..c693aebf377 100644
--- a/libgo/go/os/dir.go
+++ b/libgo/go/os/dir.go
@@ -34,7 +34,7 @@ var elen int
func (file *File) readdirnames(n int) (names []string, err error) {
if elen == 0 {
var dummy syscall.Dirent
- elen = (unsafe.Offsetof(dummy.Name) +
+ elen = (int(unsafe.Offsetof(dummy.Name)) +
libc_pathconf(syscall.StringBytePtr(file.name), syscall.PC_NAME_MAX) +
1)
}
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/libcall_posix.go b/libgo/go/syscall/libcall_posix.go
index 92feae0c102..9961ba8ff2d 100644
--- a/libgo/go/syscall/libcall_posix.go
+++ b/libgo/go/syscall/libcall_posix.go
@@ -138,7 +138,7 @@ func (w WaitStatus) TrapCause() int
//sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
//select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) int
-const nfdbits = unsafe.Sizeof(fds_bits_type) * 8
+const nfdbits = int(unsafe.Sizeof(fds_bits_type) * 8)
type FdSet struct {
Bits [(FD_SETSIZE + nfdbits - 1) / nfdbits]fds_bits_type
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/mksysinfo.sh b/libgo/mksysinfo.sh
index 6d33e6cfb70..5b04e9f0a66 100755
--- a/libgo/mksysinfo.sh
+++ b/libgo/mksysinfo.sh
@@ -938,4 +938,9 @@ grep '^type _sock_fprog ' gen-sysinfo.go | \
-e 's/_sock_filter/SockFilter/' \
>> ${OUT}
+# The Solaris 11 Update 1 _zone_net_addr_t struct.
+grep '^type _zone_net_addr_t ' gen-sysinfo.go | \
+ sed -e 's/_in6_addr/[16]byte/' \
+ >> ${OUT}
+
exit $?
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 1020c19f0be..bb8bc2a0f87 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,73 @@
+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
+ * libsupc++/Makefile.am (LTCXXCOMPILE, CXXLINK): Tweak.
+ * libsupc++/Makefile.in: Regenerated.
+ * src/Makefile.am (LTCXXCOMPILE, CXXLINK): Tweak.
+ (libstdc___la_SOURCES): Add in compatiblity files, with content
+ that varies with -DPIC.
+ * src/Makefile.in: Regenerated.
+ * src/c++11/Makefile.am (LTCXXCOMPILE, CXXLINK): Tweak.
+ * src/c++11/Makefile.in: Regenerated.
+ * src/c++11/compatibility-atomic-c++0x.cc: Guard with PIC.
+ * src/c++11/compatibility-c++0x.cc: Same.
+ * src/c++11/future.cc: Consolidate compatibility bits into..
+ * src/c++11/mutex.cc: Consolidate compatibility bits into..
+ * src/c++11/compatibility-thread-cxx0x.cc: ...here. New.
+ * src/c++98/Makefile.am (LTCXXCOMPILE, CXXLINK): Tweak.
+ * src/c++98/Makefile.in: Regenerated.
+ * src/c++98/compatibility-ldbl.cc: Guard with PIC
+ * src/c++98/compatibility-list-2.cc: Same.
+ * src/c++98/compatibility-list.cc: Same.
+ * src/c++98/compatibility.cc: Tweak comments.
+
+2012-03-28 Terry Guo <terry.guo@arm.com>
+
+ * testsuite/Makefile.am (TEST_GCC_EXEC_PREFIX): New.
+ * testsuite/Makefile.in: Regenerated.
+
+2012-03-27 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/std/functional (mem_fn): Qualify to prevent ADL.
+ * testsuite/20_util/function_objects/mem_fn/adl.cc: New.
+
2012-03-27 Jonathan Wakely <jwakely.gcc@gmail.com>
* include/std/type_traits (result_of): Fix handling of cv-quals.
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 4be1bc793f3..980c6ab40e7 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -1,7 +1,7 @@
// <functional> -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-// 2011 Free Software Foundation, Inc.
+// 2011, 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
@@ -245,7 +245,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
>::type
__invoke(_Functor& __f, _Args&&... __args)
{
- return mem_fn(__f)(std::forward<_Args>(__args)...);
+ return std::mem_fn(__f)(std::forward<_Args>(__args)...);
}
// To pick up function references (that will become function pointers)
@@ -1709,12 +1709,22 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
template<typename _Member, typename _Class>
inline _Mem_fn<_Member _Class::*>
__callable_functor(_Member _Class::* &__p)
- { return mem_fn(__p); }
+ { return std::mem_fn(__p); }
template<typename _Member, typename _Class>
inline _Mem_fn<_Member _Class::*>
__callable_functor(_Member _Class::* const &__p)
- { return mem_fn(__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;
@@ -1970,7 +1980,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
static _Res
_M_invoke(const _Any_data& __functor, _ArgTypes... __args)
{
- return mem_fn(_Base::_M_get_pointer(__functor)->__value)(
+ return std::mem_fn(_Base::_M_get_pointer(__functor)->__value)(
std::forward<_ArgTypes>(__args)...);
}
};
@@ -2010,7 +2020,7 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type)
static void
_M_invoke(const _Any_data& __functor, _ArgTypes... __args)
{
- mem_fn(_Base::_M_get_pointer(__functor)->__value)(
+ std::mem_fn(_Base::_M_get_pointer(__functor)->__value)(
std::forward<_ArgTypes>(__args)...);
}
};
diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am
index bee43531667..eaf109e7309 100644
--- a/libstdc++-v3/libsupc++/Makefile.am
+++ b/libstdc++-v3/libsupc++/Makefile.am
@@ -32,17 +32,17 @@ toolexeclib_LTLIBRARIES = libsupc++.la
noinst_LTLIBRARIES = libsupc++convenience.la
std_HEADERS = \
- cxxabi.h exception initializer_list new typeinfo
+ cxxabi.h exception initializer_list new typeinfo
bits_HEADERS = \
atomic_lockfree_defines.h cxxabi_forced.h \
- exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h
+ exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h
headers = $(std_HEADERS) $(bits_HEADERS)
if GLIBCXX_HOSTED
c_sources = \
- cp-demangle.c
+ cp-demangle.c
endif
sources = \
@@ -95,7 +95,7 @@ sources = \
vmi_class_type_info.cc \
vterminate.cc
-libsupc___la_SOURCES = $(sources) $(c_sources)
+libsupc___la_SOURCES = $(sources) $(c_sources)
libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
@@ -106,9 +106,7 @@ libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
AM_CXXFLAGS = \
$(PIC_CXXFLAGS) \
$(XTEMPLATE_FLAGS) \
- $(WARN_CXXFLAGS) \
- $(OPTIMIZE_CXXFLAGS) \
- $(CONFIG_CXXFLAGS)
+ $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
"gxx_include_dir=$(gxx_include_dir)"
@@ -125,7 +123,7 @@ C_COMPILE = \
# LTCOMPILE is copied from LTCXXCOMPILE below.
LTCOMPILE = $(LIBTOOL) --tag CC --tag disable-shared $(LIBTOOLFLAGS) --mode=compile \
$(CC) $(DEFS) $(C_INCLUDES) $(PIC_CXXFLAGS) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
cp-demangle.c:
rm -f $@
@@ -178,9 +176,11 @@ nested_exception.o: nested_exception.cc
#
# We have to put --tag disable-shared after --tag CXX lest things
# CXX undo the affect of disable-shared.
-LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -190,10 +190,11 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
# course is problematic at this point. So, we get the top-level
# directory to configure libstdc++-v3 to use gcc as the C++
# compilation driver.
-CXXLINK = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=link $(CXX) \
- $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
-
+CXXLINK = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXX) \
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
# Install notes
# We have to have rules modified from the default to counteract SUN make
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index ee65762bdcb..831f22be933 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -344,15 +344,15 @@ toolexeclib_LTLIBRARIES = libsupc++.la
# 2) integrated libsupc++convenience.la that is to be a part of libstdc++.a
noinst_LTLIBRARIES = libsupc++convenience.la
std_HEADERS = \
- cxxabi.h exception initializer_list new typeinfo
+ cxxabi.h exception initializer_list new typeinfo
bits_HEADERS = \
atomic_lockfree_defines.h cxxabi_forced.h \
- exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h
+ exception_defines.h exception_ptr.h hash_bytes.h nested_exception.h
headers = $(std_HEADERS) $(bits_HEADERS)
@GLIBCXX_HOSTED_TRUE@c_sources = \
-@GLIBCXX_HOSTED_TRUE@ cp-demangle.c
+@GLIBCXX_HOSTED_TRUE@ cp-demangle.c
sources = \
array_type_info.cc \
@@ -404,7 +404,7 @@ sources = \
vmi_class_type_info.cc \
vterminate.cc
-libsupc___la_SOURCES = $(sources) $(c_sources)
+libsupc___la_SOURCES = $(sources) $(c_sources)
libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
@@ -415,9 +415,7 @@ libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
AM_CXXFLAGS = \
$(PIC_CXXFLAGS) \
$(XTEMPLATE_FLAGS) \
- $(WARN_CXXFLAGS) \
- $(OPTIMIZE_CXXFLAGS) \
- $(CONFIG_CXXFLAGS)
+ $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
"gxx_include_dir=$(gxx_include_dir)"
@@ -435,7 +433,7 @@ C_COMPILE = \
# LTCOMPILE is copied from LTCXXCOMPILE below.
LTCOMPILE = $(LIBTOOL) --tag CC --tag disable-shared $(LIBTOOLFLAGS) --mode=compile \
$(CC) $(DEFS) $(C_INCLUDES) $(PIC_CXXFLAGS) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
# Libtool notes
@@ -459,9 +457,11 @@ LTCOMPILE = $(LIBTOOL) --tag CC --tag disable-shared $(LIBTOOLFLAGS) --mode=comp
#
# We have to put --tag disable-shared after --tag CXX lest things
# CXX undo the affect of disable-shared.
-LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -471,9 +471,11 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
# course is problematic at this point. So, we get the top-level
# directory to configure libstdc++-v3 to use gcc as the C++
# compilation driver.
-CXXLINK = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=link $(CXX) \
- $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
+CXXLINK = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXX) \
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
# Install notes
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index eb80bfecdd7..28430cf36f0 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -29,10 +29,37 @@ SUBDIRS = c++98 c++11
# Cross compiler support.
toolexeclib_LTLIBRARIES = libstdc++.la
-vpath % $(top_srcdir)/src
-vpath % $(top_srcdir)
+vpath % $(top_srcdir)/src/c++98
+vpath % $(top_srcdir)/src/c++11
-libstdc___la_SOURCES =
+if GLIBCXX_LDBL_COMPAT
+ldbl_compat_sources = compatibility-ldbl.cc
+else
+ldbl_compat_sources =
+endif
+
+if ENABLE_PARALLEL
+parallel_compat_sources = \
+ compatibility-parallel_list.cc compatibility-parallel_list-2.cc
+else
+parallel_compat_sources =
+endif
+
+cxx98_sources = \
+ compatibility.cc \
+ compatibility-debug_list.cc \
+ compatibility-debug_list-2.cc \
+ compatibility-list.cc \
+ compatibility-list-2.cc \
+ ${ldbl_compat_sources} \
+ ${parallel_compat_sources}
+
+cxx11_sources = \
+ compatibility-c++0x.cc \
+ compatibility-atomic-c++0x.cc \
+ compatibility-thread-c++0x.cc
+
+libstdc___la_SOURCES = $(cxx98_sources) $(cxx11_sources)
libstdc___la_LIBADD = \
$(GLIBCXX_LIBS) \
@@ -52,6 +79,43 @@ libstdc___la_LDFLAGS = \
libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS)
+# Use special rules for parallel mode compilation.
+PARALLEL_FLAGS = -fopenmp -D_GLIBCXX_PARALLEL -I$(glibcxx_builddir)/../libgomp
+compatibility-parallel_list.lo: compatibility-parallel_list.cc
+ $(LTCXXCOMPILE) -c $<
+compatibility-parallel_list.o: compatibility-parallel_list.cc
+ $(CXXCOMPILE) -c $<
+
+compatibility-parallel_list-2.lo: compatibility-parallel_list-2.cc
+ $(LTCXXCOMPILE) -c $<
+compatibility-parallel_list-2.o: compatibility-parallel_list-2.cc
+ $(CXXCOMPILE) -c $<
+
+# Use special rules for compatibility-ldbl.cc compilation, as we need to
+# pass -mlong-double-64.
+if GLIBCXX_LDBL_COMPAT
+compatibility-ldbl.lo: compatibility-ldbl.cc
+ $(LTCXXCOMPILE) -mlong-double-64 -c $<
+compatibility-ldbl.o: compatibility-ldbl.cc
+ $(CXXCOMPILE) -mlong-double-64 -c $<
+endif
+
+# Use special rules for C++11 files/objects.
+compatibility-c++0x.lo: compatibility-c++0x.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+compatibility-c++0x.o: compatibility-c++0x.cc
+ $(CXXCOMPILE) -std=gnu++11 -c $<
+
+compatibility-atomic-c++0x.lo: compatibility-atomic-c++0x.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+compatibility-atomic-c++0x.o: compatibility-atomic-c++0x.cc
+ $(CXXCOMPILE) -std=gnu++11 -c $<
+
+compatibility-thread-c++0x.lo: compatibility-thread-c++0x.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+compatibility-thread-c++0x.o: compatibility-thread-c++0x.cc
+ $(CXXCOMPILE) -std=gnu++11 -c $<
+
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
# modified in a per-library or per-sub-library way. Need to manually
# set this option because CONFIG_CXXFLAGS has to be after
@@ -59,12 +123,9 @@ libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS)
# as the occasion calls for it.
AM_CXXFLAGS = \
$(XTEMPLATE_FLAGS) \
- $(WARN_CXXFLAGS) \
- $(OPTIMIZE_CXXFLAGS) \
- $(CONFIG_CXXFLAGS)
-
+ $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
-# libstdc++ libtool notes
+# Libtool notes
# 1) Need to explicitly set LTCXXCOMPILE so that AM_CXXFLAGS is
# last. (That way, things like -O2 passed down from the toplevel can
@@ -82,10 +143,11 @@ AM_CXXFLAGS = \
# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe
# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to
# attempt to infer which configuration to use
-LTCXXCOMPILE = $(LIBTOOL) --tag CXX \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
- $(CXX) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = \
+ $(LIBTOOL) --tag CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -95,8 +157,12 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
# course is problematic at this point. So, we get the top-level
# directory to configure libstdc++-v3 to use gcc as the C++
# compilation driver.
-CXXLINK = $(LIBTOOL) --tag CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
- $(CXX) $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
+CXXLINK = \
+ $(LIBTOOL) --tag CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXX) \
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
+
# Symbol versioning for shared libraries.
if ENABLE_SYMVERS
@@ -116,7 +182,7 @@ libstdc++-symbols.ver: ${glibcxx_srcdir}/$(SYMVER_FILE) \
fi; \
fi
$(EGREP) -v '^[ ]*#(#| |$$)' $@.tmp | \
- $(COMPILE) -E -P -include config.h - > $@ || (rm -f $@ ; exit 1)
+ $(CC) -E -P -include ../config.h - > $@ || (rm -f $@ ; exit 1)
rm -f $@.tmp
CLEANFILES = libstdc++-symbols.ver
@@ -165,7 +231,6 @@ endif
# Control additional build primary rules.
-# EXTRA_LTLIBRARIES =
all-once: libstdc++convenience.la $(STAMP_DEBUG)
install-data-once: $(STAMP_INSTALL_DEBUG)
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index 34c0a3156ed..3c1facf7f43 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -88,20 +88,22 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(toolexeclibdir)"
LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
am__DEPENDENCIES_1 =
-am_libstdc___la_OBJECTS =
+@GLIBCXX_LDBL_COMPAT_TRUE@am__objects_1 = compatibility-ldbl.lo
+@ENABLE_PARALLEL_TRUE@am__objects_2 = compatibility-parallel_list.lo \
+@ENABLE_PARALLEL_TRUE@ compatibility-parallel_list-2.lo
+am__objects_3 = compatibility.lo compatibility-debug_list.lo \
+ compatibility-debug_list-2.lo compatibility-list.lo \
+ compatibility-list-2.lo $(am__objects_1) $(am__objects_2)
+am__objects_4 = compatibility-c++0x.lo compatibility-atomic-c++0x.lo \
+ compatibility-thread-c++0x.lo
+am_libstdc___la_OBJECTS = $(am__objects_3) $(am__objects_4)
libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp =
am__depfiles_maybe =
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
SOURCES = $(libstdc___la_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
@@ -331,7 +333,27 @@ SUBDIRS = c++98 c++11
# Cross compiler support.
toolexeclib_LTLIBRARIES = libstdc++.la
-libstdc___la_SOURCES =
+@GLIBCXX_LDBL_COMPAT_FALSE@ldbl_compat_sources =
+@GLIBCXX_LDBL_COMPAT_TRUE@ldbl_compat_sources = compatibility-ldbl.cc
+@ENABLE_PARALLEL_FALSE@parallel_compat_sources =
+@ENABLE_PARALLEL_TRUE@parallel_compat_sources = \
+@ENABLE_PARALLEL_TRUE@ compatibility-parallel_list.cc compatibility-parallel_list-2.cc
+
+cxx98_sources = \
+ compatibility.cc \
+ compatibility-debug_list.cc \
+ compatibility-debug_list-2.cc \
+ compatibility-list.cc \
+ compatibility-list-2.cc \
+ ${ldbl_compat_sources} \
+ ${parallel_compat_sources}
+
+cxx11_sources = \
+ compatibility-c++0x.cc \
+ compatibility-atomic-c++0x.cc \
+ compatibility-thread-c++0x.cc
+
+libstdc___la_SOURCES = $(cxx98_sources) $(cxx11_sources)
libstdc___la_LIBADD = \
$(GLIBCXX_LIBS) \
$(top_builddir)/libsupc++/libsupc++convenience.la \
@@ -349,6 +371,9 @@ libstdc___la_LDFLAGS = \
libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS)
+# Use special rules for parallel mode compilation.
+PARALLEL_FLAGS = -fopenmp -D_GLIBCXX_PARALLEL -I$(glibcxx_builddir)/../libgomp
+
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
# modified in a per-library or per-sub-library way. Need to manually
# set this option because CONFIG_CXXFLAGS has to be after
@@ -356,12 +381,10 @@ libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS)
# as the occasion calls for it.
AM_CXXFLAGS = \
$(XTEMPLATE_FLAGS) \
- $(WARN_CXXFLAGS) \
- $(OPTIMIZE_CXXFLAGS) \
- $(CONFIG_CXXFLAGS)
+ $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
-# libstdc++ libtool notes
+# Libtool notes
# 1) Need to explicitly set LTCXXCOMPILE so that AM_CXXFLAGS is
# last. (That way, things like -O2 passed down from the toplevel can
@@ -379,10 +402,11 @@ AM_CXXFLAGS = \
# correct solution is to add `--tag CXX' to LTCXXCOMPILE and maybe
# CXXLINK, just after $(LIBTOOL), so that libtool doesn't have to
# attempt to infer which configuration to use
-LTCXXCOMPILE = $(LIBTOOL) --tag CXX \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
- $(CXX) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = \
+ $(LIBTOOL) --tag CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -392,8 +416,11 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
# course is problematic at this point. So, we get the top-level
# directory to configure libstdc++-v3 to use gcc as the C++
# compilation driver.
-CXXLINK = $(LIBTOOL) --tag CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
- $(CXX) $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
+CXXLINK = \
+ $(LIBTOOL) --tag CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXX) \
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
@ENABLE_SYMVERS_TRUE@CLEANFILES = libstdc++-symbols.ver $(version_dep)
@ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@version_arg = -Wl,-exported_symbols_list,libstdc++-symbols.explist
@@ -423,6 +450,7 @@ debugdir = ${glibcxx_builddir}/src/debug
all: all-recursive
.SUFFIXES:
+.SUFFIXES: .cc .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/fragment.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -493,6 +521,15 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
+.cc.o:
+ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ $(LTCXXCOMPILE) -c -o $@ $<
+
mostlyclean-libtool:
-rm -f *.lo
@@ -757,8 +794,40 @@ uninstall-am: uninstall-toolexeclibLTLIBRARIES
uninstall-toolexeclibLTLIBRARIES
-vpath % $(top_srcdir)/src
-vpath % $(top_srcdir)
+vpath % $(top_srcdir)/src/c++98
+vpath % $(top_srcdir)/src/c++11
+compatibility-parallel_list.lo: compatibility-parallel_list.cc
+ $(LTCXXCOMPILE) -c $<
+compatibility-parallel_list.o: compatibility-parallel_list.cc
+ $(CXXCOMPILE) -c $<
+
+compatibility-parallel_list-2.lo: compatibility-parallel_list-2.cc
+ $(LTCXXCOMPILE) -c $<
+compatibility-parallel_list-2.o: compatibility-parallel_list-2.cc
+ $(CXXCOMPILE) -c $<
+
+# Use special rules for compatibility-ldbl.cc compilation, as we need to
+# pass -mlong-double-64.
+@GLIBCXX_LDBL_COMPAT_TRUE@compatibility-ldbl.lo: compatibility-ldbl.cc
+@GLIBCXX_LDBL_COMPAT_TRUE@ $(LTCXXCOMPILE) -mlong-double-64 -c $<
+@GLIBCXX_LDBL_COMPAT_TRUE@compatibility-ldbl.o: compatibility-ldbl.cc
+@GLIBCXX_LDBL_COMPAT_TRUE@ $(CXXCOMPILE) -mlong-double-64 -c $<
+
+# Use special rules for C++11 files/objects.
+compatibility-c++0x.lo: compatibility-c++0x.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+compatibility-c++0x.o: compatibility-c++0x.cc
+ $(CXXCOMPILE) -std=gnu++11 -c $<
+
+compatibility-atomic-c++0x.lo: compatibility-atomic-c++0x.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+compatibility-atomic-c++0x.o: compatibility-atomic-c++0x.cc
+ $(CXXCOMPILE) -std=gnu++11 -c $<
+
+compatibility-thread-c++0x.lo: compatibility-thread-c++0x.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+compatibility-thread-c++0x.o: compatibility-thread-c++0x.cc
+ $(CXXCOMPILE) -std=gnu++11 -c $<
# Symbol versioning for shared libraries.
@ENABLE_SYMVERS_TRUE@libstdc++-symbols.ver: ${glibcxx_srcdir}/$(SYMVER_FILE) \
@@ -777,7 +846,7 @@ vpath % $(top_srcdir)
@ENABLE_SYMVERS_TRUE@ fi; \
@ENABLE_SYMVERS_TRUE@ fi
@ENABLE_SYMVERS_TRUE@ $(EGREP) -v '^[ ]*#(#| |$$)' $@.tmp | \
-@ENABLE_SYMVERS_TRUE@ $(COMPILE) -E -P -include config.h - > $@ || (rm -f $@ ; exit 1)
+@ENABLE_SYMVERS_TRUE@ $(CC) -E -P -include ../config.h - > $@ || (rm -f $@ ; exit 1)
@ENABLE_SYMVERS_TRUE@ rm -f $@.tmp
@ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@libstdc++-symbols.ver-sun : libstdc++-symbols.ver \
@ENABLE_SYMVERS_SUN_TRUE@@ENABLE_SYMVERS_TRUE@ $(toplevel_srcdir)/contrib/make_sunver.pl \
@@ -800,7 +869,6 @@ vpath % $(top_srcdir)
@ENABLE_SYMVERS_DARWIN_TRUE@@ENABLE_SYMVERS_TRUE@ > $@ || (rm -f $@ ; exit 1)
# Control additional build primary rules.
-# EXTRA_LTLIBRARIES =
all-once: libstdc++convenience.la $(STAMP_DEBUG)
install-data-once: $(STAMP_INSTALL_DEBUG)
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 395af5c8579..e8a4d3a66f9 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -32,8 +32,6 @@ headers =
sources = \
chrono.cc \
condition_variable.cc \
- compatibility-c++0x.cc \
- compatibility-atomic-c++0x.cc \
debug.cc \
functexcept.cc \
functional.cc \
@@ -60,7 +58,6 @@ inst_sources =
endif
vpath % $(top_srcdir)/src/c++11
-vpath % $(top_srcdir)
libc__11convenience_la_SOURCES = $(sources) $(inst_sources)
@@ -70,11 +67,10 @@ libc__11convenience_la_SOURCES = $(sources) $(inst_sources)
# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden
# as the occasion calls for it.
AM_CXXFLAGS = \
+ -std=gnu++11 \
$(PIC_CXXFLAGS) \
$(XTEMPLATE_FLAGS) \
- $(WARN_CXXFLAGS) \
- $(OPTIMIZE_CXXFLAGS) \
- $(CONFIG_CXXFLAGS) -std=gnu++11
+ $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
"gxx_include_dir=$(gxx_include_dir)"
@@ -99,9 +95,11 @@ AM_MAKEFLAGS = \
# attempt to infer which configuration to use.
# We have to put --tag disable-shared after --tag CXX lest things
# CXX undo the affect of disable-shared.
-LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -111,6 +109,8 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
# course is problematic at this point. So, we get the top-level
# directory to configure libstdc++-v3 to use gcc as the C++
# compilation driver.
-CXXLINK = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=link $(CXX) \
- $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
+CXXLINK = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXX) \
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index b7f362af689..0c63c514741 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -66,11 +66,10 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libc__11convenience_la_LIBADD =
-am__objects_1 = chrono.lo condition_variable.lo compatibility-c++0x.lo \
- compatibility-atomic-c++0x.lo debug.lo functexcept.lo \
- functional.lo future.lo hash_c++0x.lo hashtable_c++0x.lo \
- limits.lo mutex.lo placeholders.lo regex.lo shared_ptr.lo \
- system_error.lo thread.lo
+am__objects_1 = chrono.lo condition_variable.lo debug.lo \
+ functexcept.lo functional.lo future.lo hash_c++0x.lo \
+ hashtable_c++0x.lo limits.lo mutex.lo placeholders.lo regex.lo \
+ shared_ptr.lo system_error.lo thread.lo
@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = fstream-inst.lo \
@ENABLE_EXTERN_TEMPLATE_TRUE@ string-inst.lo wstring-inst.lo
am_libc__11convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2)
@@ -301,8 +300,6 @@ headers =
sources = \
chrono.cc \
condition_variable.cc \
- compatibility-c++0x.cc \
- compatibility-atomic-c++0x.cc \
debug.cc \
functexcept.cc \
functional.cc \
@@ -333,11 +330,10 @@ libc__11convenience_la_SOURCES = $(sources) $(inst_sources)
# OPTIMIZE_CXXFLAGS on the compile line so that -O2 can be overridden
# as the occasion calls for it.
AM_CXXFLAGS = \
+ -std=gnu++11 \
$(PIC_CXXFLAGS) \
$(XTEMPLATE_FLAGS) \
- $(WARN_CXXFLAGS) \
- $(OPTIMIZE_CXXFLAGS) \
- $(CONFIG_CXXFLAGS) -std=gnu++11
+ $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
"gxx_include_dir=$(gxx_include_dir)"
@@ -363,9 +359,11 @@ AM_MAKEFLAGS = \
# attempt to infer which configuration to use.
# We have to put --tag disable-shared after --tag CXX lest things
# CXX undo the affect of disable-shared.
-LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -375,9 +373,11 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
# course is problematic at this point. So, we get the top-level
# directory to configure libstdc++-v3 to use gcc as the C++
# compilation driver.
-CXXLINK = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=link $(CXX) \
- $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
+CXXLINK = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXX) \
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
all: all-am
@@ -612,7 +612,6 @@ uninstall-am:
vpath % $(top_srcdir)/src/c++11
-vpath % $(top_srcdir)
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/libstdc++-v3/src/c++11/compatibility-atomic-c++0x.cc b/libstdc++-v3/src/c++11/compatibility-atomic-c++0x.cc
index 1ee0d7e35a8..8ccad9330ed 100644
--- a/libstdc++-v3/src/c++11/compatibility-atomic-c++0x.cc
+++ b/libstdc++-v3/src/c++11/compatibility-atomic-c++0x.cc
@@ -1,6 +1,6 @@
// <atomic> compatibility -*- C++ -*-
-// Copyright (C) 2008, 2009, 2010, 2011
+// Copyright (C) 2008, 2009, 2010, 2011, 2012
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -30,6 +30,8 @@
// XXX GLIBCXX_ABI Deprecated
// gcc-4.7.0
+#ifdef PIC
+
#define LOGSIZE 4
namespace
@@ -133,6 +135,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
+#endif
// XXX GLIBCXX_ABI Deprecated
// gcc-4.5.0
diff --git a/libstdc++-v3/src/c++11/compatibility-c++0x.cc b/libstdc++-v3/src/c++11/compatibility-c++0x.cc
index 03c58d244f2..bd5dbe0ff06 100644
--- a/libstdc++-v3/src/c++11/compatibility-c++0x.cc
+++ b/libstdc++-v3/src/c++11/compatibility-c++0x.cc
@@ -1,6 +1,6 @@
// Compatibility symbols for previous versions, C++0x bits -*- C++ -*-
-// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011, 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
@@ -30,6 +30,8 @@
# error "compatibility-c++0x.cc must be compiled with -std=gnu++0x"
#endif
+#ifdef PIC
+
namespace std _GLIBCXX_VISIBILITY(default)
{
// gcc-4.4.0
@@ -119,3 +121,4 @@ namespace std _GLIBCXX_VISIBILITY(default)
} // namespace chrono
}
+#endif
diff --git a/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc b/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc
new file mode 100644
index 00000000000..cc8761eea15
--- /dev/null
+++ b/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc
@@ -0,0 +1,72 @@
+// Compatibility symbols for previous versions, C++0x bits -*- C++ -*-
+
+// Copyright (C) 2009, 2010, 2011, 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.
+
+// 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/>.
+
+#include <future>
+#include <mutex>
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+# error "compatibility-c++0x.cc must be compiled with -std=gnu++0x"
+#endif
+
+#define _GLIBCXX_ASM_SYMVER(cur, old, version) \
+ asm (".symver " #cur "," #old "@@@" #version);
+
+// XXX GLIBCXX_ABI Deprecated
+// gcc-4.6.0
+// <future> export changes
+#if defined(_GLIBCXX_SYMVER_GNU) && defined(PIC) \
+ && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE) \
+ && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
+
+namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
+{
+ const std::error_category* future_category = &std::future_category();
+}
+
+_GLIBCXX_ASM_SYMVER(_ZN9__gnu_cxx15future_categoryE, _ZSt15future_category, GLIBCXX_3.4.14)
+
+#endif
+
+// XXX GLIBCXX_ABI Deprecated
+// gcc-4.6.0
+// <mutex> export changes
+#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
+#if defined(_GLIBCXX_SYMVER_GNU) && defined(PIC) \
+ && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE) \
+ && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
+
+namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
+{
+ std::defer_lock_t defer_lock;
+ std::try_to_lock_t try_to_lock;
+ std::adopt_lock_t adopt_lock;
+}
+
+_GLIBCXX_ASM_SYMVER(_ZN9__gnu_cxx10adopt_lockE, _ZSt10adopt_lock, GLIBCXX_3.4.11)
+_GLIBCXX_ASM_SYMVER(_ZN9__gnu_cxx10defer_lockE, _ZSt10defer_lock, GLIBCXX_3.4.11)
+_GLIBCXX_ASM_SYMVER(_ZN9__gnu_cxx11try_to_lockE, _ZSt11try_to_lock, GLIBCXX_3.4.11)
+
+
+#endif
+#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
diff --git a/libstdc++-v3/src/c++11/future.cc b/libstdc++-v3/src/c++11/future.cc
index a4881397523..380c3a45185 100644
--- a/libstdc++-v3/src/c++11/future.cc
+++ b/libstdc++-v3/src/c++11/future.cc
@@ -96,23 +96,3 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
-
-// XXX GLIBCXX_ABI Deprecated
-// gcc-4.6.0
-// <future> export changes
-#if defined(_GLIBCXX_SYMVER_GNU) && defined(PIC) \
- && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE) \
- && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
-
-namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
-{
- const std::error_category* future_category = &__future_category_instance();
-}
-
-#define _GLIBCXX_ASM_SYMVER(cur, old, version) \
- asm (".symver " #cur "," #old "@@@" #version);
-
-_GLIBCXX_ASM_SYMVER(_ZN9__gnu_cxx15future_categoryE, _ZSt15future_category, GLIBCXX_3.4.14)
-
-#endif
-
diff --git a/libstdc++-v3/src/c++11/mutex.cc b/libstdc++-v3/src/c++11/mutex.cc
index d6f2f03700f..86d0293473f 100644
--- a/libstdc++-v3/src/c++11/mutex.cc
+++ b/libstdc++-v3/src/c++11/mutex.cc
@@ -1,6 +1,6 @@
// mutex -*- C++ -*-
-// Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2008, 2009, 2010, 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
@@ -92,30 +92,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
-
-// XXX GLIBCXX_ABI Deprecated
-// gcc-4.6.0
-// <mutex> export changes
-#if defined(_GLIBCXX_SYMVER_GNU) && defined(PIC) \
- && defined(_GLIBCXX_HAVE_AS_SYMVER_DIRECTIVE) \
- && defined(_GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT)
-
-namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
-{
- std::defer_lock_t defer_lock;
- std::try_to_lock_t try_to_lock;
- std::adopt_lock_t adopt_lock;
-}
-
-#define _GLIBCXX_ASM_SYMVER(cur, old, version) \
- asm (".symver " #cur "," #old "@@" #version);
-
-_GLIBCXX_ASM_SYMVER(_ZN9__gnu_cxx10adopt_lockE, _ZSt10adopt_lock, GLIBCXX_3.4.11)
-_GLIBCXX_ASM_SYMVER(_ZN9__gnu_cxx10defer_lockE, _ZSt10defer_lock, GLIBCXX_3.4.11)
-_GLIBCXX_ASM_SYMVER(_ZN9__gnu_cxx11try_to_lockE, _ZSt11try_to_lock, GLIBCXX_3.4.11)
-
-
-#endif
+} // namespace std
#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index e960d948cf8..05767e9ff23 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -25,7 +25,7 @@
include $(top_srcdir)/fragment.am
# Convenience library for C++98 runtime.
-noinst_LTLIBRARIES = libc++98convenience.la
+noinst_LTLIBRARIES = libc++98convenience.la
headers =
@@ -74,7 +74,7 @@ atomicity.cc: ${atomicity_file}
# particular host, but with ad hoc naming rules.
host_sources_extra = \
basic_file.cc c++locale.cc \
- ${inst_sources} ${ldbl_compat_sources} ${parallel_sources}
+ ${inst_sources} ${parallel_sources}
c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC)
$(LN_S) ${glibcxx_srcdir}/$(CLOCALE_CC) ./$@ || true
@@ -83,19 +83,11 @@ basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
if ENABLE_PARALLEL
-parallel_sources = parallel_settings.cc \
- compatibility-parallel_list.cc \
- compatibility-parallel_list-2.cc
+parallel_sources = parallel_settings.cc
else
parallel_sources =
endif
-if GLIBCXX_LDBL_COMPAT
-ldbl_compat_sources = compatibility-ldbl.cc
-else
-ldbl_compat_sources =
-endif
-
if ENABLE_EXTERN_TEMPLATE
XTEMPLATE_FLAGS = -fno-implicit-templates
inst_sources = \
@@ -122,11 +114,6 @@ sources = \
pool_allocator.cc \
mt_allocator.cc \
codecvt.cc \
- compatibility.cc \
- compatibility-debug_list.cc \
- compatibility-debug_list-2.cc \
- compatibility-list.cc \
- compatibility-list-2.cc \
complex_io.cc \
ctype.cc \
globals_io.cc \
@@ -153,7 +140,6 @@ sources = \
${host_sources_extra}
vpath % $(top_srcdir)/src/c++98
-vpath % $(top_srcdir)
libc__98convenience_la_SOURCES = $(sources)
@@ -180,25 +166,6 @@ parallel_settings.lo: parallel_settings.cc
parallel_settings.o: parallel_settings.cc
$(CXXCOMPILE) $(PARALLEL_FLAGS) -c $<
-compatibility-parallel_list.lo: compatibility-parallel_list.cc
- $(LTCXXCOMPILE) -c $<
-compatibility-parallel_list.o: compatibility-parallel_list.cc
- $(CXXCOMPILE) -c $<
-
-compatibility-parallel_list-2.lo: compatibility-parallel_list-2.cc
- $(LTCXXCOMPILE) -c $<
-compatibility-parallel_list-2.o: compatibility-parallel_list-2.cc
- $(CXXCOMPILE) -c $<
-
-if GLIBCXX_LDBL_COMPAT
-# Use special rules for compatibility-ldbl.cc compilation, as we need to
-# pass -mlong-double-64.
-compatibility-ldbl.lo: compatibility-ldbl.cc
- $(LTCXXCOMPILE) -mlong-double-64 -c $<
-compatibility-ldbl.o: compatibility-ldbl.cc
- $(CXXCOMPILE) -mlong-double-64 -c $<
-endif
-
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
# modified in a per-library or per-sub-library way. Need to manually
# set this option because CONFIG_CXXFLAGS has to be after
@@ -207,9 +174,7 @@ endif
AM_CXXFLAGS = \
$(PIC_CXXFLAGS) \
$(XTEMPLATE_FLAGS) \
- $(WARN_CXXFLAGS) \
- $(OPTIMIZE_CXXFLAGS) \
- $(CONFIG_CXXFLAGS)
+ $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
"gxx_include_dir=$(gxx_include_dir)"
@@ -234,9 +199,11 @@ AM_MAKEFLAGS = \
# attempt to infer which configuration to use.
# We have to put --tag disable-shared after --tag CXX lest things
# CXX undo the affect of disable-shared.
-LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -246,6 +213,8 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
# course is problematic at this point. So, we get the top-level
# directory to configure libstdc++-v3 to use gcc as the C++
# compilation driver.
-CXXLINK = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=link $(CXX) \
- $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
+CXXLINK = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXX) \
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index b0e6c14d048..f36742ba021 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -76,23 +76,18 @@ am__objects_1 = atomicity.lo codecvt_members.lo collate_members.lo \
@ENABLE_EXTERN_TEMPLATE_TRUE@ misc-inst.lo ostream-inst.lo \
@ENABLE_EXTERN_TEMPLATE_TRUE@ sstream-inst.lo streambuf-inst.lo \
@ENABLE_EXTERN_TEMPLATE_TRUE@ wlocale-inst.lo
-@GLIBCXX_LDBL_COMPAT_TRUE@am__objects_3 = compatibility-ldbl.lo
-@ENABLE_PARALLEL_TRUE@am__objects_4 = parallel_settings.lo \
-@ENABLE_PARALLEL_TRUE@ compatibility-parallel_list.lo \
-@ENABLE_PARALLEL_TRUE@ compatibility-parallel_list-2.lo
-am__objects_5 = basic_file.lo c++locale.lo $(am__objects_2) \
- $(am__objects_3) $(am__objects_4)
-am__objects_6 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
- codecvt.lo compatibility.lo compatibility-debug_list.lo \
- compatibility-debug_list-2.lo compatibility-list.lo \
- compatibility-list-2.lo complex_io.lo ctype.lo globals_io.lo \
- hash_tr1.lo hashtable_tr1.lo ios.lo ios_failure.lo ios_init.lo \
+@ENABLE_PARALLEL_TRUE@am__objects_3 = parallel_settings.lo
+am__objects_4 = basic_file.lo c++locale.lo $(am__objects_2) \
+ $(am__objects_3)
+am__objects_5 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \
+ codecvt.lo complex_io.lo ctype.lo globals_io.lo hash_tr1.lo \
+ hashtable_tr1.lo ios.lo ios_failure.lo ios_init.lo \
ios_locale.lo list.lo locale.lo locale_init.lo \
locale_facets.lo localename.lo math_stubs_float.lo \
math_stubs_long_double.lo stdexcept.lo strstream.lo tree.lo \
istream.lo streambuf.lo valarray.lo $(am__objects_1) \
- $(am__objects_5)
-am_libc__98convenience_la_OBJECTS = $(am__objects_6)
+ $(am__objects_4)
+am_libc__98convenience_la_OBJECTS = $(am__objects_5)
libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp =
@@ -315,7 +310,7 @@ WARN_CXXFLAGS = \
AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
# Convenience library for C++98 runtime.
-noinst_LTLIBRARIES = libc++98convenience.la
+noinst_LTLIBRARIES = libc++98convenience.la
headers =
# Source files linked in via configuration/make substitution for a
@@ -337,15 +332,10 @@ atomicity_file = ${glibcxx_srcdir}/$(ATOMICITY_SRCDIR)/atomicity.h
# particular host, but with ad hoc naming rules.
host_sources_extra = \
basic_file.cc c++locale.cc \
- ${inst_sources} ${ldbl_compat_sources} ${parallel_sources}
+ ${inst_sources} ${parallel_sources}
@ENABLE_PARALLEL_FALSE@parallel_sources =
-@ENABLE_PARALLEL_TRUE@parallel_sources = parallel_settings.cc \
-@ENABLE_PARALLEL_TRUE@ compatibility-parallel_list.cc \
-@ENABLE_PARALLEL_TRUE@ compatibility-parallel_list-2.cc
-
-@GLIBCXX_LDBL_COMPAT_FALSE@ldbl_compat_sources =
-@GLIBCXX_LDBL_COMPAT_TRUE@ldbl_compat_sources = compatibility-ldbl.cc
+@ENABLE_PARALLEL_TRUE@parallel_sources = parallel_settings.cc
@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
@ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources =
@@ -370,11 +360,6 @@ sources = \
pool_allocator.cc \
mt_allocator.cc \
codecvt.cc \
- compatibility.cc \
- compatibility-debug_list.cc \
- compatibility-debug_list-2.cc \
- compatibility-list.cc \
- compatibility-list-2.cc \
complex_io.cc \
ctype.cc \
globals_io.cc \
@@ -417,9 +402,7 @@ PARALLEL_FLAGS = -fopenmp -D_GLIBCXX_PARALLEL -I$(glibcxx_builddir)/../libgomp
AM_CXXFLAGS = \
$(PIC_CXXFLAGS) \
$(XTEMPLATE_FLAGS) \
- $(WARN_CXXFLAGS) \
- $(OPTIMIZE_CXXFLAGS) \
- $(CONFIG_CXXFLAGS)
+ $(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
"gxx_include_dir=$(gxx_include_dir)"
@@ -445,9 +428,11 @@ AM_MAKEFLAGS = \
# attempt to infer which configuration to use.
# We have to put --tag disable-shared after --tag CXX lest things
# CXX undo the affect of disable-shared.
-LTCXXCOMPILE = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(TOPLEVEL_INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -457,9 +442,11 @@ LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
# course is problematic at this point. So, we get the top-level
# directory to configure libstdc++-v3 to use gcc as the C++
# compilation driver.
-CXXLINK = $(LIBTOOL) --tag CXX --tag disable-shared $(LIBTOOLFLAGS) \
- --mode=link $(CXX) \
- $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
+CXXLINK = \
+ $(LIBTOOL) --tag CXX --tag disable-shared \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXX) \
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
all: all-am
@@ -726,7 +713,6 @@ basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
$(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true
vpath % $(top_srcdir)/src/c++98
-vpath % $(top_srcdir)
strstream.lo: strstream.cc
$(LTCXXCOMPILE) -I$(GLIBCXX_INCLUDE_DIR)/backward -Wno-deprecated -c $<
strstream.o: strstream.cc
@@ -744,23 +730,6 @@ parallel_settings.lo: parallel_settings.cc
parallel_settings.o: parallel_settings.cc
$(CXXCOMPILE) $(PARALLEL_FLAGS) -c $<
-compatibility-parallel_list.lo: compatibility-parallel_list.cc
- $(LTCXXCOMPILE) -c $<
-compatibility-parallel_list.o: compatibility-parallel_list.cc
- $(CXXCOMPILE) -c $<
-
-compatibility-parallel_list-2.lo: compatibility-parallel_list-2.cc
- $(LTCXXCOMPILE) -c $<
-compatibility-parallel_list-2.o: compatibility-parallel_list-2.cc
- $(CXXCOMPILE) -c $<
-
-# Use special rules for compatibility-ldbl.cc compilation, as we need to
-# pass -mlong-double-64.
-@GLIBCXX_LDBL_COMPAT_TRUE@compatibility-ldbl.lo: compatibility-ldbl.cc
-@GLIBCXX_LDBL_COMPAT_TRUE@ $(LTCXXCOMPILE) -mlong-double-64 -c $<
-@GLIBCXX_LDBL_COMPAT_TRUE@compatibility-ldbl.o: compatibility-ldbl.cc
-@GLIBCXX_LDBL_COMPAT_TRUE@ $(CXXCOMPILE) -mlong-double-64 -c $<
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/libstdc++-v3/src/c++98/compatibility-ldbl.cc b/libstdc++-v3/src/c++98/compatibility-ldbl.cc
index a103856adfa..b40e54a7c98 100644
--- a/libstdc++-v3/src/c++98/compatibility-ldbl.cc
+++ b/libstdc++-v3/src/c++98/compatibility-ldbl.cc
@@ -1,6 +1,6 @@
// Compatibility symbols for -mlong-double-64 compatibility -*- C++ -*-
-// Copyright (C) 2006, 2008, 2009, 2010, 2011
+// Copyright (C) 2006, 2008, 2009, 2010, 2011, 2012
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -27,6 +27,8 @@
#include <cmath>
#include <tr1/functional>
+#ifdef PIC
+
#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
#ifdef __LONG_DOUBLE_128__
@@ -78,3 +80,5 @@ extern "C" void _ZNKSt4hashIeEclEe (void)
__attribute__((alias ("_ZNKSt3tr14hashIeEclEe")));
#endif
+
+#endif
diff --git a/libstdc++-v3/src/c++98/compatibility-list-2.cc b/libstdc++-v3/src/c++98/compatibility-list-2.cc
index ac69798740d..975450cb100 100644
--- a/libstdc++-v3/src/c++98/compatibility-list-2.cc
+++ b/libstdc++-v3/src/c++98/compatibility-list-2.cc
@@ -1,6 +1,6 @@
// Compatibility symbols for previous versions, list bits -*- C++ -*-
-// Copyright (C) 2011 Free Software Foundation, Inc.
+// Copyright (C) 2011, 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
@@ -24,6 +24,8 @@
#include <bits/move.h>
+#ifdef PIC
+
#ifndef _GLIBCXX_BEGIN_NAMESPACE_COMPAT
# define _GLIBCXX_BEGIN_NAMESPACE_COMPAT
#endif
@@ -111,3 +113,5 @@ _GLIBCXX_BEGIN_NAMESPACE_COMPAT
_GLIBCXX_END_NAMESPACE_COMPAT
} // namespace std
+
+#endif
diff --git a/libstdc++-v3/src/c++98/compatibility-list.cc b/libstdc++-v3/src/c++98/compatibility-list.cc
index a0d706b27a9..8b91849b300 100644
--- a/libstdc++-v3/src/c++98/compatibility-list.cc
+++ b/libstdc++-v3/src/c++98/compatibility-list.cc
@@ -1,6 +1,6 @@
// Compatibility symbols for previous versions, list bits -*- C++ -*-
-// Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2010, 2011, 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
@@ -24,6 +24,8 @@
#include <bits/move.h>
+#ifdef PIC
+
#ifndef _GLIBCXX_BEGIN_NAMESPACE_COMPAT
# define _GLIBCXX_BEGIN_NAMESPACE_COMPAT
#endif
@@ -144,3 +146,5 @@ _GLIBCXX_BEGIN_NAMESPACE_COMPAT
_GLIBCXX_END_NAMESPACE_COMPAT
} // namespace std
+
+#endif
diff --git a/libstdc++-v3/src/c++98/compatibility.cc b/libstdc++-v3/src/c++98/compatibility.cc
index d4cf5d7c122..38d9e4b6743 100644
--- a/libstdc++-v3/src/c++98/compatibility.cc
+++ b/libstdc++-v3/src/c++98/compatibility.cc
@@ -199,7 +199,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace std
// NB: These symbols renames should go into the shared library only,
@@ -228,7 +228,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace std
/* gcc-4.0.0
@@ -357,7 +357,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace std
// The rename syntax for default exported names is
// asm (".symver name1,exportedname@GLIBCXX_3.4")
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/20_util/function_objects/mem_fn/adl.cc b/libstdc++-v3/testsuite/20_util/function_objects/mem_fn/adl.cc
new file mode 100644
index 00000000000..907db848911
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function_objects/mem_fn/adl.cc
@@ -0,0 +1,44 @@
+// { 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/>.
+
+#include <functional>
+
+namespace n {
+ struct X { int i; };
+ void mem_fn(int X::*);
+}
+
+using n::X;
+
+X x{};
+int X::* p = &X::i;
+
+int test01()
+{
+ auto ref = std::ref(p);
+ return ref(x);
+}
+
+int test02()
+{
+ std::function<int(X)> fun(p);
+ return fun(x);
+}
+
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>
diff --git a/libstdc++-v3/testsuite/Makefile.am b/libstdc++-v3/testsuite/Makefile.am
index 166bd160fd2..7094ad52991 100644
--- a/libstdc++-v3/testsuite/Makefile.am
+++ b/libstdc++-v3/testsuite/Makefile.am
@@ -60,6 +60,7 @@ site.exp: Makefile
@echo 'set libiconv "$(LIBICONV)"' >>site.tmp
@echo 'set baseline_dir "$(baseline_dir)"' >> site.tmp
@echo 'set baseline_subdir_switch "$(baseline_subdir_switch)"' >> site.tmp
+ @echo 'set TEST_GCC_EXEC_PREFIX "$(libdir)/gcc/"' >> site.tmp
@echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp
@test ! -f site.exp || \
sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp
diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in
index 8c91fd03ec9..e433bb9effe 100644
--- a/libstdc++-v3/testsuite/Makefile.in
+++ b/libstdc++-v3/testsuite/Makefile.in
@@ -505,6 +505,7 @@ site.exp: Makefile
@echo 'set libiconv "$(LIBICONV)"' >>site.tmp
@echo 'set baseline_dir "$(baseline_dir)"' >> site.tmp
@echo 'set baseline_subdir_switch "$(baseline_subdir_switch)"' >> site.tmp
+ @echo 'set TEST_GCC_EXEC_PREFIX "$(libdir)/gcc/"' >> site.tmp
@echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp
@test ! -f site.exp || \
sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp