2006-02-17 Jakub Jelinek PR libstdc++/11953 * gthr-posix.h (_REENTRANT): Only define if __osf__ is defined. * config/ia64/linux.h (CPP_SPEC): Define. * config/s390/linux.h (CPP_SPEC): Define. --- gcc/gthr-posix.h (revision 111211) +++ gcc/gthr-posix.h (revision 111212) @@ -36,7 +36,7 @@ Software Foundation, 51 Franklin Street, #define __GTHREADS 1 /* Some implementations of require this to be defined. */ -#ifndef _REENTRANT +#if !defined(_REENTRANT) && defined(__osf__) #define _REENTRANT 1 #endif --- gcc/config/s390/linux.h (revision 111211) +++ gcc/config/s390/linux.h (revision 111212) @@ -89,6 +89,7 @@ Software Foundation, 51 Franklin Street, %{m31:-dynamic-linker /lib/ld.so.1} \ %{m64:-dynamic-linker /lib64/ld64.so.1}}}}" +#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" #define TARGET_ASM_FILE_END file_end_indicate_exec_stack --- gcc/config/ia64/linux.h (revision 111211) +++ gcc/config/ia64/linux.h (revision 111212) @@ -48,6 +48,7 @@ do { \ %{!dynamic-linker:-dynamic-linker /lib/ld-linux-ia64.so.2}} \ %{static:-static}}" +#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" #define JMP_BUF_SIZE 76 2004-05-27 Josef Zlomek PR middle-end/14084 * emit-rtl.c (gen_rtx_REG_offset): Adjust the offset according to size of decl. --- gcc/emit-rtl.c 25 May 2004 12:04:15 -0000 1.391 +++ gcc/emit-rtl.c 27 May 2004 04:28:12 -0000 1.392 @@ -746,13 +746,96 @@ gen_reg_rtx (enum machine_mode mode) return val; } -/* Generate a register with same attributes as REG, - but offsetted by OFFSET. */ +/* Generate a register with same attributes as REG, but offsetted by OFFSET. + Do the big endian correction if needed. */ rtx gen_rtx_REG_offset (rtx reg, enum machine_mode mode, unsigned int regno, int offset) { rtx new = gen_rtx_REG (mode, regno); + tree decl; + HOST_WIDE_INT var_size; + + /* PR middle-end/14084 + The problem appears when a variable is stored in a larger register + and later it is used in the original mode or some mode in between + or some part of variable is accessed. + + On little endian machines there is no problem because + the REG_OFFSET of the start of the variable is the same when + accessed in any mode (it is 0). + + However, this is not true on big endian machines. + The offset of the start of the variable is different when accessed + in different modes. + When we are taking a part of the REG we have to change the OFFSET + from offset WRT size of mode of REG to offset WRT size of variable. + + If we would not do the big endian correction the resulting REG_OFFSET + would be larger than the size of the DECL. + + Examples of correction, for BYTES_BIG_ENDIAN WORDS_BIG_ENDIAN machine: + + REG.mode MODE DECL size old offset new offset description + DI SI 4 4 0 int32 in SImode + DI SI 1 4 0 char in SImode + DI QI 1 7 0 char in QImode + DI QI 4 5 1 1st element in QImode + of char[4] + DI HI 4 6 2 1st element in HImode + of int16[2] + + If the size of DECL is equal or greater than the size of REG + we can't do this correction because the register holds the + whole variable or a part of the variable and thus the REG_OFFSET + is already correct. */ + + decl = REG_EXPR (reg); + if ((BYTES_BIG_ENDIAN || WORDS_BIG_ENDIAN) + && decl != NULL + && offset > 0 + && GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode) + && ((var_size = int_size_in_bytes (TREE_TYPE (decl))) > 0 + && var_size < GET_MODE_SIZE (GET_MODE (reg)))) + { + int offset_le; + + /* Convert machine endian to little endian WRT size of mode of REG. */ + if (WORDS_BIG_ENDIAN) + offset_le = ((GET_MODE_SIZE (GET_MODE (reg)) - 1 - offset) + / UNITS_PER_WORD) * UNITS_PER_WORD; + else + offset_le = (offset / UNITS_PER_WORD) * UNITS_PER_WORD; + + if (BYTES_BIG_ENDIAN) + offset_le += ((GET_MODE_SIZE (GET_MODE (reg)) - 1 - offset) + % UNITS_PER_WORD); + else + offset_le += offset % UNITS_PER_WORD; + + if (offset_le >= var_size) + { + /* MODE is wider than the variable so the new reg will cover + the whole variable so the resulting OFFSET should be 0. */ + offset = 0; + } + else + { + /* Convert little endian to machine endian WRT size of variable. */ + if (WORDS_BIG_ENDIAN) + offset = ((var_size - 1 - offset_le) + / UNITS_PER_WORD) * UNITS_PER_WORD; + else + offset = (offset_le / UNITS_PER_WORD) * UNITS_PER_WORD; + + if (BYTES_BIG_ENDIAN) + offset += ((var_size - 1 - offset_le) + % UNITS_PER_WORD); + else + offset += offset_le % UNITS_PER_WORD; + } + } + REG_ATTRS (new) = get_reg_attrs (REG_EXPR (reg), REG_OFFSET (reg) + offset); return new; 2005-01-13 Jakub Jelinek PR rtl-optimization/16104 * expr.c (convert_move): Handle vector from resp. to if mode sizes differ. * gcc.c-torture/execute/20050113-1.c: New test. --- gcc/expr.c.jj 2004-12-27 21:31:08.000000000 +0100 +++ gcc/expr.c 2005-01-13 15:56:31.229253647 +0100 @@ -590,7 +590,26 @@ convert_move (rtx to, rtx from, int unsi if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode)) { if (GET_MODE_BITSIZE (from_mode) != GET_MODE_BITSIZE (to_mode)) - abort (); + { + if (VECTOR_MODE_P (from_mode)) + { + enum machine_mode new_mode; + + new_mode = mode_for_size (GET_MODE_BITSIZE (from_mode), + MODE_INT, 0); + from = simplify_gen_subreg (new_mode, from, from_mode, 0); + } + if (VECTOR_MODE_P (to_mode)) + { + enum machine_mode new_mode; + + new_mode = mode_for_size (GET_MODE_BITSIZE (to_mode), + MODE_INT, 0); + to = simplify_gen_subreg (new_mode, to, to_mode, 0); + } + convert_move (to, from, unsignedp); + return; + } if (VECTOR_MODE_P (to_mode)) from = simplify_gen_subreg (to_mode, from, GET_MODE (from), 0); --- gcc/testsuite/gcc.c-torture/execute/20050113-1.c.jj 2005-01-13 15:51:09.194383356 +0100 +++ gcc/testsuite/gcc.c-torture/execute/20050113-1.c 2005-01-13 15:37:22.000000000 +0100 @@ -0,0 +1,56 @@ +/* PR rtl-optimization/16104 */ + +extern void abort (void); + +typedef int V2SI __attribute__ ((vector_size (8))); +typedef short V2HI __attribute__ ((vector_size (4))); + +int +test1 (void) +{ + return (long long) (V2SI) 0LL; +} + +int +test2 (V2SI x) +{ + return (long long) x; +} + +V2SI +test3 (void) +{ + return (V2SI) (long long) (int) (V2HI) 0; +} + +V2SI +test4 (V2HI x) +{ + return (V2SI) (long long) (int) x; +} + +int +main (void) +{ + if (sizeof (short) != 2 || sizeof (int) != 4 || sizeof (long long) != 8) + return 0; + + if (test1 () != 0) + abort (); + + V2SI x = { 2, 2 }; + if (test2 (x) != 2) + abort (); + + union { V2SI x; int y[2]; } u; + u.x = test3 (); + if (u.y[0] != 0 || u.y[1] != 0) + abort (); + + V2HI y = { 4, 4 }; + union { V2SI x; long long y; } v; + v.x = test4 (y); + if (v.y != 0x40004) + abort (); + return 0; +} 2005-09-07 Jakub Jelinek PR target/18300 * config/i386/i386.c (classify_argument): Only use different iterators for nested loops if nested loops sharing the same iterator would hang. 2004-11-13 Zak Kipling PR target/18300 * config/i386/i386.c (classify_argument): Fix infinite loop when passing object with 3 or more base classes by value. --- gcc/config/i386/i386.c.jj 2005-07-21 11:01:36.000000000 +0200 +++ gcc/config/i386/i386.c 2005-09-07 14:22:19.000000000 +0200 @@ -2028,8 +2028,17 @@ classify_argument (enum machine_mode mod { tree bases = TYPE_BINFO_BASETYPES (type); int n_bases = TREE_VEC_LENGTH (bases); - int i; - + int i, basenum; + enum x86_64_reg_class saveclasses[MAX_CLASSES]; + bool seen[MAX_CLASSES]; + + /* PR target/18300: The following code mistakenly uses the same + iterator variable in both nested for loops. But to preserve + binary compatibility, do whatever this code used to do before + unless old GCC would hang in an infinite loop. In that case + use whatever GCC 4.0+ does. */ + memset (seen, 0, sizeof (seen)); + memcpy (saveclasses, classes, sizeof (saveclasses)); for (i = 0; i < n_bases; ++i) { tree binfo = TREE_VEC_ELT (bases, i); @@ -2037,6 +2046,12 @@ classify_argument (enum machine_mode mod int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8; tree type = BINFO_TYPE (binfo); + if (i < MAX_CLASSES) + { + if (seen[i]) + break; + seen[i] = true; + } num = classify_argument (TYPE_MODE (type), type, subclasses, (offset + bit_offset) % 256); @@ -2049,6 +2064,32 @@ classify_argument (enum machine_mode mod merge_classes (subclasses[i], classes[i + pos]); } } + if (i < n_bases) + { + /* Older GCC 3.[0-4].x would hang in the above loop, so + don't worry about backwards compatibility and + just DTRT. */ + memcpy (classes, saveclasses, sizeof (saveclasses)); + for (basenum = 0; basenum < n_bases; ++basenum) + { + tree binfo = TREE_VEC_ELT (bases, basenum); + int num; + int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8; + tree type = BINFO_TYPE (binfo); + + num = classify_argument (TYPE_MODE (type), + type, subclasses, + (offset + bit_offset) % 256); + if (!num) + return 0; + for (i = 0; i < num; i++) + { + int pos = (offset + (bit_offset % 64)) / 8 / 8; + classes[i + pos] = + merge_classes (subclasses[i], classes[i + pos]); + } + } + } } /* And now merge the fields of structure. */ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) @@ -2116,8 +2157,17 @@ classify_argument (enum machine_mode mod { tree bases = TYPE_BINFO_BASETYPES (type); int n_bases = TREE_VEC_LENGTH (bases); - int i; - + int i, basenum; + enum x86_64_reg_class saveclasses[MAX_CLASSES]; + bool seen[MAX_CLASSES]; + + /* PR target/18300: The following code mistakenly uses the same + iterator variable in both nested for loops. But to preserve + binary compatibility, do whatever this code used to do before + unless old GCC would hang in an infinite loop. In that case + use whatever GCC 4.0+ does. */ + memset (seen, 0, sizeof (seen)); + memcpy (saveclasses, classes, sizeof (saveclasses)); for (i = 0; i < n_bases; ++i) { tree binfo = TREE_VEC_ELT (bases, i); @@ -2125,6 +2175,12 @@ classify_argument (enum machine_mode mod int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8; tree type = BINFO_TYPE (binfo); + if (i < MAX_CLASSES) + { + if (seen[i]) + break; + seen[i] = true; + } num = classify_argument (TYPE_MODE (type), type, subclasses, (offset + (bit_offset % 64)) % 256); @@ -2137,6 +2193,32 @@ classify_argument (enum machine_mode mod merge_classes (subclasses[i], classes[i + pos]); } } + if (i < n_bases) + { + /* Older GCC 3.[0-4].x would hang in the above loop, so + don't worry about backwards compatibility and + just DTRT. */ + memcpy (classes, saveclasses, sizeof (saveclasses)); + for (basenum = 0; basenum < n_bases; ++basenum) + { + tree binfo = TREE_VEC_ELT (bases, basenum); + int num; + int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8; + tree type = BINFO_TYPE (binfo); + + num = classify_argument (TYPE_MODE (type), + type, subclasses, + (offset + (bit_offset % 64)) % 256); + if (!num) + return 0; + for (i = 0; i < num; i++) + { + int pos = (offset + (bit_offset % 64)) / 8 / 8; + classes[i + pos] = + merge_classes (subclasses[i], classes[i + pos]); + } + } + } } for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) { --- gcc/testsuite/g++.dg/other/infloop-1.C 1 Jan 1970 00:00:00 -0000 +++ gcc/testsuite/g++.dg/other/infloop-1.C 13 Nov 2004 23:09:08 -0000 1.1 @@ -0,0 +1,16 @@ +// PR 18300: This sends old compilers into an infinite loop on x86_64 +// Testcase and patch contributed by Zak Kipling + +struct base1 { }; +struct base2 { }; +struct base3 { }; + +struct derived : base1, base2, base3 { }; + +void foo(derived); + +int main() +{ + foo(derived()); +} + --- gcc/testsuite/g++.dg/ext/visibility/staticdatamem.C 1 Jan 1970 00:00:00 -0000 +++ gcc/testsuite/g++.dg/ext/visibility/staticdatamem.C 14 Dec 2004 02:15:55 -0000 1.1 @@ -0,0 +1,20 @@ +// PR c++/18925 +// { dg-do compile { target ia64-*-linux* } } +// { dg-options "-fPIC -fvisibility=hidden" } +// { dg-final { scan-assembler-not "gprel" } } + +class __attribute__ ((visibility("default"))) Type +{ + private: + static long _staticTypeCount; + public: + Type() { _staticTypeCount++; } + ~Type(); +}; + +long Type::_staticTypeCount = 0; + +Type::~Type() +{ + _staticTypeCount--; +} 2005-05-07 Richard Henderson PR target/21412 * config/rs6000/rs6000.c (rs6000_emit_move): Look for tls addresses with constant offsets. 2004-07-11 Ulrich Weigand * config/s390/s390.c (legitimize_tls_address): Handle constant offsets added to TLS symbol addresses. 2004-07-06 Richard Henderson * config/i386/i386.c (legitimize_address): Handle CONST with TLS operand. (ix86_expand_move): Don't call legitimize_pic_address directly. 2006-05-05 Jakub Jelinek * gcc.dg/tls/opt-12.c: New test. --- gcc/config/s390/s390.c (revision 84404) +++ gcc/config/s390/s390.c (revision 84535) @@ -2913,6 +2913,18 @@ legitimize_tls_address (rtx addr, rtx re } } + else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS + && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT) + { + new = XEXP (XEXP (addr, 0), 0); + if (GET_CODE (new) != SYMBOL_REF) + new = gen_rtx_CONST (Pmode, new); + + new = legitimize_tls_address (new, reg); + new = plus_constant (new, INTVAL (XEXP (XEXP (addr, 0), 1))); + new = force_operand (new, 0); + } + else abort (); /* for now ... */ --- gcc/config/i386/i386.c 2005-11-21 14:56:49.000000000 +0100 +++ gcc/config/i386/i386.c 2006-05-05 11:21:54.000000000 +0200 @@ -6604,6 +6604,13 @@ legitimize_address (rtx x, rtx oldx ATTR log = tls_symbolic_operand (x, mode); if (log) return legitimize_tls_address (x, log, false); + if (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == PLUS + && (log = tls_symbolic_operand (XEXP (XEXP (x, 0), 0), Pmode))) + { + rtx t = legitimize_tls_address (XEXP (XEXP (x, 0), 0), log, false); + return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1)); + } if (flag_pic && SYMBOLIC_CONST (x)) return legitimize_pic_address (x, 0); @@ -8395,6 +8402,10 @@ ix86_expand_move (enum machine_mode mode #else if (GET_CODE (op0) == MEM) op1 = force_reg (Pmode, op1); + else if (GET_CODE (op1) == CONST + && GET_CODE (XEXP (op1, 0)) == PLUS + && tls_symbolic_operand (XEXP (XEXP (op1, 0), 0), Pmode)) + op1 = legitimize_address (op1, op1, Pmode); else { rtx temp = op0; --- gcc/config/rs6000/rs6000.c (revision 99334) +++ gcc/config/rs6000/rs6000.c (revision 99367) @@ -4436,11 +4436,31 @@ rs6000_emit_move (rtx dest, rtx source, /* Recognize the case where operand[1] is a reference to thread-local data and load its address to a register. */ - if (GET_CODE (operands[1]) == SYMBOL_REF) + if (rs6000_tls_referenced_p (operands[1])) { - enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]); - if (model != 0) - operands[1] = rs6000_legitimize_tls_address (operands[1], model); + enum tls_model model; + rtx tmp = operands[1]; + rtx addend = NULL; + + if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS) + { + addend = XEXP (XEXP (tmp, 0), 1); + tmp = XEXP (XEXP (tmp, 0), 0); + } + + if (GET_CODE (tmp) != SYMBOL_REF) + abort (); + model = SYMBOL_REF_TLS_MODEL (tmp); + if (model == 0) + abort (); + + tmp = rs6000_legitimize_tls_address (tmp, model); + if (addend) + { + tmp = gen_rtx_PLUS (mode, tmp, addend); + tmp = force_operand (tmp, operands[0]); + } + operands[1] = tmp; } /* Handle the case where reload calls us with an invalid address. */ --- gcc/testsuite/gcc.dg/tls/opt-9.c (revision 0) +++ gcc/testsuite/gcc.dg/tls/opt-9.c (revision 99367) @@ -0,0 +1,7 @@ +/* PR 21412 */ +/* { dg-do compile */ +/* { dg-options "-O2 -fPIC" } */ + +struct S { int x[10]; }; +extern __thread struct S s; +int *foo() { return &s.x[2]; } --- gcc/testsuite/gcc.dg/tls/opt-12.c 2006-04-19 19:21:31.748476000 +0200 +++ gcc/testsuite/gcc.dg/tls/opt-12.c 2006-05-05 11:01:33.000000000 +0200 @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { XXdgXX-require-effective-target tls } */ + +__thread struct +{ + int a; + char b[32]; +} thr; + +int +main () +{ + __builtin_strcpy (thr.b, "abcd"); + return 0; +} 2005-07-22 Jakub Jelinek * src/sstream-inst.cc: Add .hidden directive for streamsize basic_stringbuf<{char,wchar_t}>::showmanyc(). * src/sstream-inst-showmanyc.cc: New file. * src/Makefile.am (libstdc++_nonshared.la): Add new library. * src/Makefile.in: Rebuilt. * testsuite/lib/libstdc++.exp: Append -lstdc++_nonshared for testsuite executable linking. 2005-06-08 Benjamin Kosnik PR libstdc++/21955 * include/std/std_sstream.h (basic_stringbuf::showmanyc): Add. * testsuite/27_io/basic_streambuf/in_avail/char/1.cc: New, test base class behavior. * testsuite/27_io/basic_streambuf/in_avail/wchar_t/1.cc: Same. * testsuite/27_io/basic_stringbuf/in_avail/char/21955.cc: New. * testsuite/27_io/basic_stringbuf/in_avail/char/1.cc: Match filebuf behavior. * testsuite/27_io/basic_stringbuf/str/char/1.cc: Same. --- libstdc++-v3/src/sstream-inst.cc.jj 2003-07-11 10:28:13.000000000 +0200 +++ libstdc++-v3/src/sstream-inst.cc 2005-07-21 17:46:08.000000000 +0200 @@ -60,3 +60,8 @@ namespace std template class basic_stringstream; #endif } // namespace std + +#ifdef PIC +__asm (".hidden _ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9showmanycEv"); +__asm (".hidden _ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9showmanycEv"); +#endif --- libstdc++-v3/src/sstream-inst-showmanyc.cc.jj 2005-07-21 21:27:40.000000000 +0200 +++ libstdc++-v3/src/sstream-inst-showmanyc.cc 2005-07-22 09:16:58.000000000 +0200 @@ -0,0 +1,39 @@ +// Explicit instantiation file. + +// Copyright (C) 2005 +// 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include + +namespace std +{ + // These symbols are hidden in libstdc++.so, as it is undesirable to export + // @@GLIBCXX_3.4.6 + template streamsize basic_stringbuf, allocator >::showmanyc(); + template streamsize basic_stringbuf, allocator >::showmanyc(); +} // namespace std --- libstdc++-v3/src/Makefile.am.jj 2004-04-20 15:55:47.000000000 +0200 +++ libstdc++-v3/src/Makefile.am 2005-07-22 09:00:32.000000000 +0200 @@ -25,7 +25,7 @@ include $(top_srcdir)/fragment.am # Cross compiler support. -toolexeclib_LTLIBRARIES = libstdc++.la +toolexeclib_LTLIBRARIES = libstdc++.la libstdc++_nonshared.la # Symbol versioning for shared libraries. if GLIBCXX_BUILD_VERSIONED_SHLIB @@ -150,6 +150,11 @@ libstdc___la_DEPENDENCIES = ${version_de libstdc___la_LDFLAGS = \ -version-info $(libtool_VERSION) ${version_arg} -lm +libstdc___nonshared_la_SOURCES = \ + sstream-inst-showmanyc.cc +libstdc___nonshared_la_LIBADD = +libstdc___nonshared_la_DEPENDENCIES = $(libstdc___nonshared_la_LIBADD) +libstdc___nonshared_la_LDFLAGS = -static # Use special rules for the deprecated source files so that they find # deprecated include files. @@ -159,6 +164,14 @@ strstream.lo: strstream.cc strstream.o: strstream.cc $(CXXCOMPILE) -I$(GLIBCXX_INCLUDE_DIR)/backward -Wno-deprecated -c $< +# Use special rules for libstdc++_nonshared.la files, as -prefer-pic +# doesn't seem to work for some reason. +sstream-inst-showmanyc.lo: sstream-inst-showmanyc.cc + $(LTCXXCOMPILE) -c $< \ + && cp -f .libs/sstream-inst-showmanyc.o sstream-inst-showmanyc.o +sstream-inst-showmanyc.o: sstream-inst-showmanyc.cc + $(CXXCOMPILE) -fPIC -DPIC -c $< + # Use special rules for the concept-checking instantiations so that all # the generated template functions are also instantiated. Force the checks # to be on so that the instantiations are actually seen. --- libstdc++-v3/src/Makefile.in.jj 2004-04-20 15:55:47.000000000 +0200 +++ libstdc++-v3/src/Makefile.in 2005-07-22 09:06:15.000000000 +0200 @@ -221,7 +221,7 @@ WARN_CXXFLAGS = \ AM_CPPFLAGS = $(GLIBCXX_INCLUDES) # Cross compiler support. -toolexeclib_LTLIBRARIES = libstdc++.la +toolexeclib_LTLIBRARIES = libstdc++.la libstdc++_nonshared.la # Symbol versioning for shared libraries. @GLIBCXX_BUILD_VERSIONED_SHLIB_TRUE@version_arg = -Wl,--version-script=libstdc++-symbol.ver @@ -308,6 +308,13 @@ libstdc___la_LDFLAGS = \ -version-info $(libtool_VERSION) ${version_arg} -lm +libstdc___nonshared_la_SOURCES = \ + sstream-inst-showmanyc.cc + +libstdc___nonshared_la_LIBADD = +libstdc___nonshared_la_DEPENDENCIES = $(libstdc___nonshared_la_LIBADD) +libstdc___nonshared_la_LDFLAGS = -static + # Use special rules for the deprecated source files so that they find # deprecated include files. GLIBCXX_INCLUDE_DIR = $(glibcxx_builddir)/include @@ -379,6 +386,8 @@ am__objects_3 = allocator.lo codecvt.lo $(am__objects_1) $(am__objects_2) am_libstdc___la_OBJECTS = $(am__objects_3) libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS) +am_libstdc___nonshared_la_OBJECTS = sstream-inst-showmanyc.lo +libstdc___nonshared_la_OBJECTS = $(am_libstdc___nonshared_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = @@ -386,10 +395,10 @@ am__depfiles_maybe = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) -DIST_SOURCES = $(libstdc___la_SOURCES) +DIST_SOURCES = $(libstdc___la_SOURCES) $(libstdc___nonshared_la_SOURCES) DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/fragment.am \ Makefile.am -SOURCES = $(libstdc___la_SOURCES) +SOURCES = $(libstdc___la_SOURCES) $(libstdc___nonshared_la_SOURCES) all: all-am @@ -430,6 +439,8 @@ clean-toolexeclibLTLIBRARIES: done libstdc++.la: $(libstdc___la_OBJECTS) $(libstdc___la_DEPENDENCIES) $(CXXLINK) -rpath $(toolexeclibdir) $(libstdc___la_LDFLAGS) $(libstdc___la_OBJECTS) $(libstdc___la_LIBADD) $(LIBS) +libstdc++_nonshared.la: $(libstdc___nonshared_la_OBJECTS) $(libstdc___nonshared_la_DEPENDENCIES) + $(CXXLINK) -rpath $(toolexeclibdir) $(libstdc___nonshared_la_LDFLAGS) $(libstdc___nonshared_la_OBJECTS) $(libstdc___nonshared_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) core *.core @@ -674,6 +685,14 @@ strstream.lo: strstream.cc strstream.o: strstream.cc $(CXXCOMPILE) -I$(GLIBCXX_INCLUDE_DIR)/backward -Wno-deprecated -c $< +# Use special rules for libstdc++_nonshared.la files, as -prefer-pic +# doesn't seem to work for some reason. +sstream-inst-showmanyc.lo: sstream-inst-showmanyc.cc + $(LTCXXCOMPILE) -c $< \ + && cp -f .libs/sstream-inst-showmanyc.o sstream-inst-showmanyc.o +sstream-inst-showmanyc.o: sstream-inst-showmanyc.cc + $(CXXCOMPILE) -fPIC -DPIC -c $< + # Use special rules for the concept-checking instantiations so that all # the generated template functions are also instantiated. Force the checks # to be on so that the instantiations are actually seen. --- libstdc++-v3/include/std/std_sstream.h.jj 2004-10-04 14:58:25.000000000 +0200 +++ libstdc++-v3/include/std/std_sstream.h 2005-07-21 17:17:16.000000000 +0200 @@ -185,6 +185,18 @@ namespace std _M_sync(const_cast(_M_string.data()), 0, __len); } + virtual streamsize + showmanyc() + { + streamsize __ret = -1; + if (_M_mode & ios_base::in) + { + _M_update_egptr(); + __ret = this->egptr() - this->gptr(); + } + return __ret; + } + // [documentation is inherited] virtual int_type underflow(); --- libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/1.cc.jj 2003-10-01 12:12:11.000000000 +0200 +++ libstdc++-v3/testsuite/27_io/basic_stringbuf/str/char/1.cc 2005-07-22 01:22:15.000000000 +0200 @@ -45,7 +45,7 @@ void test03() std::streamsize d1 = strb_01.in_avail(); std::streamsize d2 = strb_03.in_avail(); VERIFY( d1 ); // non-zero - VERIFY( !d2 ); // zero, cuz ios_base::out + VERIFY( d2 == -1 ); // -1, cuz ios_base::out VERIFY( d1 != d2 ); //these should be the same VERIFY( static_cast(str_01.length()) == d1 ); VERIFY( strb_01.str() == strb_03.str() ); //ditto --- libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/1.cc.jj 2003-10-01 12:12:10.000000000 +0200 +++ libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/1.cc 2005-07-22 01:22:04.000000000 +0200 @@ -49,8 +49,8 @@ void test04() VERIFY( strmof_1 == static_cast(str_01.length()) ); VERIFY( strmof_2 == static_cast(str_02.length()) ); strmof_1 = strb_03.in_avail(); - // zero cuz write-only, or eof()? zero, from showmany - VERIFY( strmof_1 == 0 ); + // zero cuz write-only, or eof() to match basic_filebuf + VERIFY( strmof_1 == -1 ); } int main() --- libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/21955.cc.jj 2005-07-22 01:22:04.000000000 +0200 +++ libstdc++-v3/testsuite/27_io/basic_stringbuf/in_avail/char/21955.cc 2005-07-22 01:22:04.000000000 +0200 @@ -0,0 +1,54 @@ +// 2005-06-07 Benjamin Kosnik + +// Copyright (C) 2005 +// 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +#include +#include +#include + +double +test_stringstream() +{ + double result; + char* source = "1918"; + std::stringstream s; + s << source; + + std::string tmp = s.str(); + std::streambuf* sb = s.rdbuf(); + int i = sb->in_avail(); + + if (i) + { + s >> result; + } + else + { + throw std::runtime_error("conversion failed"); + } + return result; +} + + +int main () +{ + test_stringstream(); + return 0; +} --- libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/char/1.cc.jj 2005-07-22 01:21:41.000000000 +0200 +++ libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/char/1.cc 2005-07-22 01:21:41.000000000 +0200 @@ -0,0 +1,54 @@ +// 2005-06-07 Benjamin Kosnik + +// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.8.1.4 Overridden virtual functions + +#include +#include + +typedef std::basic_streambuf streambuf_type; + +struct testbuf : streambuf_type +{ + testbuf() { } +}; + +void test05() +{ + typedef streambuf_type::int_type int_type; + typedef streambuf_type::traits_type traits_type; + typedef streambuf_type::pos_type pos_type; + typedef streambuf_type::off_type off_type; + typedef size_t size_type; + + bool test __attribute__((unused)) = true; + std::streamoff strmof_1, strmof_2; + testbuf sb01; + + // int in_avail() + strmof_1 = sb01.in_avail(); + VERIFY( strmof_1 == 0 ); +} + +int main() +{ + test05(); + return 0; +} --- libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/wchar_t/1.cc.jj 2005-07-22 01:21:41.000000000 +0200 +++ libstdc++-v3/testsuite/27_io/basic_streambuf/in_avail/wchar_t/1.cc 2005-07-22 01:21:41.000000000 +0200 @@ -0,0 +1,54 @@ +// 2005-06-07 Benjamin Kosnik + +// Copyright (C) 2005 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.8.1.4 Overridden virtual functions + +#include +#include + +typedef std::basic_streambuf streambuf_type; + +struct testbuf : streambuf_type +{ + testbuf() { } +}; + +void test05() +{ + typedef streambuf_type::int_type int_type; + typedef streambuf_type::traits_type traits_type; + typedef streambuf_type::pos_type pos_type; + typedef streambuf_type::off_type off_type; + typedef size_t size_type; + + bool test __attribute__((unused)) = true; + std::streamoff strmof_1, strmof_2; + testbuf sb01; + + // int in_avail() + strmof_1 = sb01.in_avail(); + VERIFY( strmof_1 == 0 ); +} + +int main() +{ + test05(); + return 0; +} --- libstdc++-v3/libsupc++/eh_globals.cc.jj 2005-11-21 14:43:32.000000000 +0100 +++ libstdc++-v3/libsupc++/eh_globals.cc 2006-04-21 15:38:55.000000000 +0200 @@ -36,6 +36,26 @@ using namespace __cxxabiv1; +#if 1 +namespace __gnu_internal +{ + __cxxabiv1::__cxa_eh_globals* + get_global() throw() + { + static __thread __cxxabiv1::__cxa_eh_globals global __attribute__((tls_model ("initial-exec"))); + return &global; + } +} + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals_fast() throw() +{ return __gnu_internal::get_global(); } + +extern "C" __cxa_eh_globals* +__cxxabiv1::__cxa_get_globals() throw() +{ return __gnu_internal::get_global(); } + +#else // Single-threaded fallback buffer. static __cxa_eh_globals globals_static; @@ -125,3 +145,4 @@ __cxa_get_globals () throw() return &globals_static; #endif } +#endif 2005-11-23 Paolo Carlini PR libstdc++/24975 (basic_string) * include/bits/basic_string.h (_Rep::_S_empty_rep): Avoid strict-aliasing warnings. 2005-11-22 Paolo Carlini PR libstdc++/24975 * include/bits/stl_set.h (insert(iterator, const value_type&), erase(iterator), erase(iterator, iterator)): Don't break aliasing rules casting to _Rep_iterator&, forward to _Rb_tree facilities. * include/bits/stl_multiset.h (insert(iterator, const value_type&), erase(iterator), erase(iterator, iterator)): Likewise. * include/bits/stl_tree.h (_Rb_tree<>::_M_insert(_Const_Base_ptr, _Const_Base_ptr, const value_type&), insert_unique(const_iterator, const value_type&), insert_equal(const_iterator, const value_type&), erase(const_iterator), erase(const_iterator, const_iterator)): New, _Rb_tree<>::const_iterator counterparts of existing facilities. --- libstdc++-v3/include/bits/basic_string.h.jj 2007-02-23 21:29:15.000000000 +0100 +++ libstdc++-v3/include/bits/basic_string.h 2007-07-19 12:11:40.000000000 +0200 @@ -175,7 +175,16 @@ namespace std static _Rep& _S_empty_rep() - { return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); } + { +#if __GNUC__ >= 4 + // Work around type-punning warning in g++4. _S_empty_rep_storage + // is never modified, so type-punning is ok. + void* __p = reinterpret_cast(&_S_empty_rep_storage); + return *reinterpret_cast<_Rep*>(__p); +#else + return *reinterpret_cast<_Rep*>(&_S_empty_rep_storage); +#endif + } bool _M_is_leaked() const --- libstdc++-v3/include/bits/stl_tree.h.jj 2007-02-23 21:29:15.000000000 +0100 +++ libstdc++-v3/include/bits/stl_tree.h 2007-07-19 13:18:28.000000000 +0200 @@ -532,6 +532,12 @@ namespace std iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); +#if __GNUC__ >= 4 + const_iterator + _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __y, + const value_type& __v); +#endif + _Link_type _M_copy(_Const_Link_type __x, _Link_type __p); @@ -631,9 +637,19 @@ namespace std iterator insert_unique(iterator __position, const value_type& __x); +#if __GNUC__ >= 4 + const_iterator + insert_unique(const_iterator __position, const value_type& __x); +#endif + iterator insert_equal(iterator __position, const value_type& __x); +#if __GNUC__ >= 4 + const_iterator + insert_equal(const_iterator __position, const value_type& __x); +#endif + template void insert_unique(_InputIterator __first, _InputIterator __last); @@ -645,12 +661,22 @@ namespace std void erase(iterator __position); +#if __GNUC__ >= 4 + void + erase(const_iterator __position); +#endif + size_type erase(const key_type& __x); void erase(iterator __first, iterator __last); +#if __GNUC__ >= 4 + void + erase(const_iterator __first, const_iterator __last); +#endif + void erase(const key_type* __first, const key_type* __last); @@ -793,6 +819,28 @@ namespace std return iterator(__z); } +#if __GNUC__ >= 4 + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v) + { + _Link_type __z = _M_create_node(__v); + bool __insert_left; + + __insert_left = __x != 0 || __p == _M_end() + || _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__p)); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, + const_cast<_Base_ptr>(__p), + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return const_iterator(__z); + } +#endif + template typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator @@ -928,6 +976,54 @@ namespace std } } +#if __GNUC__ >= 4 + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + insert_unique(const_iterator __position, const _Val& __v) + { + if (__position._M_node == _M_leftmost()) + { + // begin() + if (size() > 0 + && _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__position._M_node))) + return _M_insert(__position._M_node, __position._M_node, __v); + // First argument just needs to be non-null. + else + return const_iterator(insert_unique(__v).first); + } + else if (__position._M_node == _M_end()) + { + // end() + if (_M_impl._M_key_compare(_S_key(_M_rightmost()), + _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); + else + return const_iterator(insert_unique(__v).first); + } + else + { + const_iterator __before = __position; + --__before; + if (_M_impl._M_key_compare(_S_key(__before._M_node), + _KeyOfValue()(__v)) + && _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__position._M_node))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // First argument just needs to be non-null. + } + else + return const_iterator(insert_unique(__v).first); + } + } +#endif + template typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator @@ -974,6 +1070,54 @@ namespace std } } +#if __GNUC__ >= 4 + template + typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + insert_equal(const_iterator __position, const _Val& __v) + { + if (__position._M_node == _M_leftmost()) + { + // begin() + if (size() > 0 + && !_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + return _M_insert(__position._M_node, __position._M_node, __v); + // first argument just needs to be non-null + else + return const_iterator(insert_equal(__v)); + } + else if (__position._M_node == _M_end()) + { + // end() + if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); + else + return const_iterator(insert_equal(__v)); + } + else + { + const_iterator __before = __position; + --__before; + if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__before._M_node)) + && !_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, __position._M_node, __v); + // First argument just needs to be non-null. + } + else + return const_iterator(insert_equal(__v)); + } + } +#endif + template template @@ -1008,6 +1152,20 @@ namespace std --_M_impl._M_node_count; } +#if __GNUC__ >= 4 + template + inline void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(const_iterator __position) + { + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase(const_cast<_Base_ptr>(__position._M_node), + this->_M_impl._M_header)); + destroy_node(__y); + --_M_impl._M_node_count; + } +#endif + template typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type @@ -1082,6 +1240,20 @@ namespace std while (__first != __last) erase(__first++); } +#if __GNUC__ >= 4 + template + void + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + erase(const_iterator __first, const_iterator __last) + { + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) erase(__first++); + } +#endif + template void --- libstdc++-v3/include/bits/stl_multiset.h.jj 2007-02-23 21:29:15.000000000 +0100 +++ libstdc++-v3/include/bits/stl_multiset.h 2007-07-19 12:30:47.000000000 +0200 @@ -328,8 +328,12 @@ namespace _GLIBCXX_STD iterator insert(iterator __position, const value_type& __x) { +#if __GNUC__ >= 4 + return _M_t.insert_equal(__position, __x); +#else typedef typename _Rep_type::iterator _Rep_iterator; return _M_t.insert_equal((_Rep_iterator&)__position, __x); +#endif } /** @@ -358,8 +362,12 @@ namespace _GLIBCXX_STD void erase(iterator __position) { +#if __GNUC__ >= 4 + _M_t.erase(__position); +#else typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__position); +#endif } /** @@ -391,8 +399,12 @@ namespace _GLIBCXX_STD void erase(iterator __first, iterator __last) { +#if __GNUC__ >= 4 + _M_t.erase(__first, __last); +#else typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); +#endif } /** --- libstdc++-v3/include/bits/stl_set.h.jj 2007-02-23 21:29:15.000000000 +0100 +++ libstdc++-v3/include/bits/stl_set.h 2007-07-19 12:23:57.000000000 +0200 @@ -337,8 +337,12 @@ namespace _GLIBCXX_STD iterator insert(iterator __position, const value_type& __x) { +#if __GNUC__ >= 4 + return _M_t.insert_unique(__position, __x); +#else typedef typename _Rep_type::iterator _Rep_iterator; return _M_t.insert_unique((_Rep_iterator&)__position, __x); +#endif } /** @@ -366,8 +370,12 @@ namespace _GLIBCXX_STD void erase(iterator __position) { +#if __GNUC__ >= 4 + _M_t.erase(__position); +#else typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__position); +#endif } /** @@ -398,8 +406,12 @@ namespace _GLIBCXX_STD void erase(iterator __first, iterator __last) { +#if __GNUC__ >= 4 + _M_t.erase(__first, __last); +#else typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); +#endif } /** 2006-02-27 Jakub Jelinek PR other/26208 * unwind-dw2.c (struct _Unwind_Context): Add signal_frame field. (_Unwind_FrameState): Add signal_frame field. (extract_cie_info): Handle S flag in augmentation string. (execute_cfa_program): If context->signal_frame, execute also fs->pc == context->ra instructions. (uw_frame_state_for): If context->signal_frame, don't subtract one from context->ra to find FDE. (uw_update_context_1): Set context->signal_frame to fs->signal_frame. (_Unwind_GetIPInfo): New function. * unwind-c.c (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead of _Unwind_GetIP. * unwind-sjlj.c (_Unwind_GetIPInfo): New function. * unwind.h (_Unwind_GetIPInfo): New prototype. * unwind-compat.c (_Unwind_GetIPInfo): New function. * libgcc-std.ver (_Unwind_GetIPInfo): Export @@GCC_4.2.0. * config/ia64/unwind-ia64.c (_Unwind_GetIPInfo): New function. * config/i386/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Set (FS)->signal_frame. * config/i386/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise. * config/rs6000/linux-unwind.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise. * config/s390/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise. * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead of _Unwind_GetIP. * exception.cc (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead of _Unwind_GetIP. * include/i386-signal.h (MAKE_THROW_FRAME): Change into empty macro. (HANDLE_DIVIDE_OVERFLOW): Don't adjust _res->eip if falling through to throw. * include/x86_64-signal.h (MAKE_THROW_FRAME): Change into empty macro. * include/powerpc-signal.h (MAKE_THROW_FRAME): Change into empty macro. --- libjava/exception.cc.jj 2005-11-21 14:47:25.000000000 +0100 +++ libjava/exception.cc 2006-04-21 14:00:19.000000000 +0200 @@ -199,6 +199,7 @@ PERSONALITY_FUNCTION (int version, int handler_switch_value; bool saw_cleanup; bool saw_handler; + int ip_before_insn = 0; // Interface version check. @@ -214,10 +215,10 @@ PERSONALITY_FUNCTION (int version, goto install_context; } - // FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of + // FIXME: In Phase 1, record _Unwind_GetIPInfo in xh->obj as a part of // the stack trace for this exception. This will only collect Java // frames, but perhaps that is acceptable. - // FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site + // FIXME2: _Unwind_GetIPInfo is nonsensical for SJLJ, being a call-site // index instead of a PC value. We could perhaps arrange for // _Unwind_GetRegionStart to return context->fc->jbuf[1], which // is the address of the handler label for __builtin_longjmp, but @@ -232,7 +233,9 @@ PERSONALITY_FUNCTION (int version, // Parse the LSDA header. p = parse_lsda_header (context, language_specific_data, &info); - ip = _Unwind_GetIP (context) - 1; + ip = _Unwind_GetIPInfo (context, &ip_before_insn); + if (! ip_before_insn) + --ip; landing_pad = 0; action_record = 0; handler_switch_value = 0; --- libjava/include/i386-signal.h.jj 2005-11-21 14:47:15.000000000 +0100 +++ libjava/include/i386-signal.h 2006-04-21 14:57:55.000000000 +0200 @@ -22,19 +22,7 @@ details. */ #define SIGNAL_HANDLER(_name) \ static void _name (int _dummy) -#define MAKE_THROW_FRAME(_exception) \ -do \ -{ \ - void **_p = (void **)&_dummy; \ - struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; \ - \ - /* Advance the program counter so that it is after the start of the \ - instruction: the x86 exception handler expects \ - the PC to point to the instruction after a call. */ \ - _regs->eip += 2; \ - \ -} \ -while (0) +#define MAKE_THROW_FRAME(_exception) #define HANDLE_DIVIDE_OVERFLOW \ do \ @@ -84,14 +72,6 @@ do \ _regs->eip = (unsigned long)_eip; \ return; \ } \ - else \ - { \ - /* Advance the program counter so that it is after the start \ - of the instruction: this is because the x86 exception \ - handler expects the PC to point to the instruction after a \ - call. */ \ - _regs->eip += 2; \ - } \ } \ } \ while (0) --- libjava/include/x86_64-signal.h.jj 2006-04-20 17:02:27.000000000 +0200 +++ libjava/include/x86_64-signal.h 2006-04-21 14:00:19.000000000 +0200 @@ -34,17 +34,7 @@ extern "C" }; } -#define MAKE_THROW_FRAME(_exception) \ -do \ -{ \ - /* Advance the program counter so that it is after the start of the \ - instruction: the x86_64 exception handler expects \ - the PC to point to the instruction after a call. */ \ - struct ucontext *_uc = (struct ucontext *)_p; \ - volatile struct sigcontext *_sc = (struct sigcontext *) &_uc->uc_mcontext; \ - _sc->rip += 2; \ -} \ -while (0) +#define MAKE_THROW_FRAME(_exception) #define RESTORE(name, syscall) RESTORE2 (name, syscall) #define RESTORE2(name, syscall) \ --- libjava/include/powerpc-signal.h.jj 2005-11-21 14:47:15.000000000 +0100 +++ libjava/include/powerpc-signal.h 2006-04-21 14:00:19.000000000 +0200 @@ -22,18 +22,12 @@ details. */ #define SIGNAL_HANDLER(_name) \ static void _name (int /* _signal */, struct sigcontext *_sc) -/* PPC either leaves PC pointing at a faulting instruction or the - following instruction, depending on the signal. SEGV always does - the former, so we adjust the saved PC to point to the following - instruction. This is what the handler in libgcc expects. */ +/* MD_FALBACK_FRAME_STATE_FOR takes care of special casing PC + before the faulting instruction, so we don't need to do anything + here. */ + +#define MAKE_THROW_FRAME(_exception) -#define MAKE_THROW_FRAME(_exception) \ -do \ - { \ - _sc->regs->nip += 4; \ - } \ -while (0) - /* For an explanation why we cannot simply use sigaction to install the handlers, see i386-signal.h. */ --- libstdc++-v3/libsupc++/eh_personality.cc.jj 2005-11-21 14:43:32.000000000 +0100 +++ libstdc++-v3/libsupc++/eh_personality.cc 2006-04-21 14:24:34.000000000 +0200 @@ -201,6 +201,7 @@ PERSONALITY_FUNCTION (int version, _Unwind_Ptr landing_pad, ip; int handler_switch_value; void *thrown_ptr = xh + 1; + int ip_before_insn = 0; // Interface version check. if (version != 1) @@ -227,7 +228,9 @@ PERSONALITY_FUNCTION (int version, // Parse the LSDA header. p = parse_lsda_header (context, language_specific_data, &info); info.ttype_base = base_of_encoded_value (info.ttype_encoding, context); - ip = _Unwind_GetIP (context) - 1; + ip = _Unwind_GetIPInfo (context, &ip_before_insn); + if (! ip_before_insn) + --ip; landing_pad = 0; action_record = 0; handler_switch_value = 0; --- gcc/libgcc-std.ver.jj 2005-11-21 14:43:21.000000000 +0100 +++ gcc/libgcc-std.ver 2006-04-21 14:02:13.000000000 +0200 @@ -234,3 +234,8 @@ GCC_3.4.4 { __negvti2 __subvti3 } + +%inherit GCC_4.2.0 GCC_3.4.4 +GCC_4.2.0 { + _Unwind_GetIPInfo +} --- gcc/unwind-c.c.jj 2005-11-21 14:43:20.000000000 +0100 +++ gcc/unwind-c.c 2006-04-21 14:00:08.000000000 +0200 @@ -102,6 +102,7 @@ PERSONALITY_FUNCTION (int version, lsda_header_info info; const unsigned char *language_specific_data, *p, *action_record; _Unwind_Ptr landing_pad, ip; + int ip_before_insn = 0; if (version != 1) return _URC_FATAL_PHASE1_ERROR; @@ -119,7 +120,9 @@ PERSONALITY_FUNCTION (int version, /* Parse the LSDA header. */ p = parse_lsda_header (context, language_specific_data, &info); - ip = _Unwind_GetIP (context) - 1; + ip = _Unwind_GetIPInfo (context, &ip_before_insn); + if (! ip_before_insn) + --ip; landing_pad = 0; #ifdef __USING_SJLJ_EXCEPTIONS__ --- gcc/config/s390/linux.h.jj 2005-11-21 14:40:55.000000000 +0100 +++ gcc/config/s390/linux.h 2006-04-21 14:15:46.000000000 +0200 @@ -113,6 +113,7 @@ Software Foundation, 59 Temple Place - S } __attribute__ ((__aligned__ (8))) sigregs_; \ \ sigregs_ *regs_; \ + int *signo_ = NULL; \ \ /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn */ \ if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173)) \ @@ -133,6 +134,7 @@ Software Foundation, 59 Temple Place - S } *uc_ = (CONTEXT)->cfa + 8 + 128; \ \ regs_ = &uc_->uc_mcontext; \ + signo_ = (CONTEXT)->cfa + sizeof(long); \ } \ \ /* Old-style RT frame and all non-RT frames: \ @@ -141,6 +143,11 @@ Software Foundation, 59 Temple Place - S else \ { \ regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8); \ + /* Recent kernels store the signal number immediately after \ + the sigregs; old kernels have the return trampoline at \ + this location. */ \ + if ((void *)(regs_ + 1) != (CONTEXT)->ra) \ + signo_ = (int *)(regs_ + 1); \ } \ \ new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32; \ @@ -167,6 +174,12 @@ Software Foundation, 59 Temple Place - S (FS)->regs.reg[32].loc.offset = (long)®s_->psw_addr - new_cfa_; \ (FS)->retaddr_column = 32; \ \ + /* SIGILL, SIGFPE and SIGTRAP are delivered with psw_addr \ + after the faulting instruction rather than before it. \ + Don't set FS->signal_frame in that case. */ \ + if (!signo_ || (*signo_ != 4 && *signo_ != 5 && *signo_ != 8)) \ + (FS)->signal_frame = 1; \ + \ goto SUCCESS; \ } while (0) --- gcc/config/i386/linux.h.jj 2005-11-21 14:41:07.000000000 +0100 +++ gcc/config/i386/linux.h 2006-04-21 14:18:05.000000000 +0200 @@ -268,6 +268,7 @@ Boston, MA 02111-1307, USA. */ (FS)->regs.reg[8].how = REG_SAVED_OFFSET; \ (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \ (FS)->retaddr_column = 8; \ + (FS)->signal_frame = 1; \ goto SUCCESS; \ } while (0) #endif /* not USE_GNULIBC_1 */ --- gcc/config/i386/linux64.h.jj 2005-11-21 14:41:07.000000000 +0100 +++ gcc/config/i386/linux64.h 2006-04-21 14:18:45.000000000 +0200 @@ -136,6 +136,7 @@ Boston, MA 02111-1307, USA. */ (FS)->regs.reg[16].how = REG_SAVED_OFFSET; \ (FS)->regs.reg[16].loc.offset = (long)&sc_->rip - new_cfa_; \ (FS)->retaddr_column = 16; \ + (FS)->signal_frame = 1; \ goto SUCCESS; \ } while (0) #else /* ifdef __x86_64__ */ @@ -190,6 +191,7 @@ Boston, MA 02111-1307, USA. */ (FS)->regs.reg[8].how = REG_SAVED_OFFSET; \ (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \ (FS)->retaddr_column = 8; \ + (FS)->signal_frame = 1; \ goto SUCCESS; \ } while (0) #endif /* ifdef __x86_64__ */ --- gcc/config/ia64/unwind-ia64.c.jj 2005-11-21 14:40:57.000000000 +0100 +++ gcc/config/ia64/unwind-ia64.c 2006-04-21 14:00:11.000000000 +0200 @@ -1748,6 +1748,13 @@ _Unwind_GetIP (struct _Unwind_Context *c return context->rp; } +inline _Unwind_Ptr +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) +{ + *ip_before_insn = 0; + return context->rp; +} + /* Overwrite the return address for CONTEXT with VAL. */ inline void --- gcc/unwind-compat.c.jj 2005-11-21 14:43:20.000000000 +0100 +++ gcc/unwind-compat.c 2006-04-21 13:59:59.000000000 +0200 @@ -134,6 +134,13 @@ _Unwind_GetIP (struct _Unwind_Context *c } symver (_Unwind_GetIP, GCC_3.0); +_Unwind_Ptr +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) +{ + *ip_before_insn = 0; + return __libunwind_Unwind_GetIP (context); +} + extern void *__libunwind_Unwind_GetLanguageSpecificData (struct _Unwind_Context *); --- gcc/unwind-sjlj.c.jj 2005-11-21 14:43:21.000000000 +0100 +++ gcc/unwind-sjlj.c 2006-04-21 14:00:08.000000000 +0200 @@ -202,6 +202,13 @@ _Unwind_GetIP (struct _Unwind_Context *c return context->fc->call_site + 1; } +_Unwind_Ptr +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) +{ + *ip_before_insn = 0; + return context->fc->call_site + 1; +} + /* Set the return landing pad index in CONTEXT. */ void --- gcc/unwind.h.jj 2005-11-21 14:43:20.000000000 +0100 +++ gcc/unwind.h 2006-04-21 14:08:51.000000000 +0200 @@ -151,6 +151,7 @@ extern _Unwind_Word _Unwind_GetGR (struc extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word); extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); +extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *); extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr); /* @@@ Retrieve the CFA of the given context. */ --- gcc/unwind-dw2.c.jj 2005-11-21 14:43:21.000000000 +0100 +++ gcc/unwind-dw2.c 2006-04-21 14:05:32.000000000 +0200 @@ -82,6 +82,7 @@ struct _Unwind_Context void *lsda; struct dwarf_eh_bases bases; _Unwind_Word args_size; + char signal_frame; }; /* Byte size of every register managed by these routines. */ @@ -137,6 +138,7 @@ typedef struct unsigned char fde_encoding; unsigned char lsda_encoding; unsigned char saw_z; + unsigned char signal_frame; void *eh_ptr; } _Unwind_FrameState; @@ -271,6 +273,16 @@ _Unwind_GetIP (struct _Unwind_Context *c return (_Unwind_Ptr) context->ra; } +/* Retrieve the return address and flag whether that IP is before + or after first not yet fully executed instruction. */ + +inline _Unwind_Ptr +_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) +{ + *ip_before_insn = context->signal_frame != 0; + return (_Unwind_Ptr) context->ra; +} + /* Overwrite the return address for CONTEXT with VAL. */ inline void @@ -382,6 +394,13 @@ extract_cie_info (const struct dwarf_cie aug += 1; } + /* "S" indicates a signal frame. */ + else if (aug[0] == 'S') + { + fs->signal_frame = 1; + aug += 1; + } + /* Otherwise we have an unknown augmentation string. Bail unless we saw a 'z' prefix. */ else @@ -818,8 +837,10 @@ execute_cfa_program (const unsigned char a different stack configuration that we are not interested in. We assume that the call itself is unwind info-neutral; if not, or if there are delay instructions that adjust the stack, these must be - reflected at the point immediately before the call insn. */ - while (insn_ptr < insn_end && fs->pc < context->ra) + reflected at the point immediately before the call insn. + In signal frames, return address is after last completed instruction, + so we add 1 to return address to make the comparison <=. */ + while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame) { unsigned char insn = *insn_ptr++; _Unwind_Word reg, utmp; @@ -1021,7 +1042,8 @@ uw_frame_state_for (struct _Unwind_Conte if (context->ra == 0) return _URC_END_OF_STACK; - fde = _Unwind_Find_FDE (context->ra - 1, &context->bases); + fde = _Unwind_Find_FDE (context->ra + context->signal_frame - 1, + &context->bases); if (fde == NULL) { /* Couldn't find frame unwind info for this function. Try a @@ -1376,6 +1398,8 @@ uw_update_context_1 (struct _Unwind_Cont break; } + context->signal_frame = fs->signal_frame; + MD_FROB_UPDATE_CONTEXT (context, fs); } --- gcc/unwind-dw2.c.jj 2006-05-22 13:39:48.000000000 -0400 +++ gcc/unwind-dw2.c 2006-05-22 13:48:20.000000000 -0400 @@ -40,6 +40,7 @@ #include "unwind-pe.h" #include "unwind-dw2-fde.h" #include "gthr.h" +#include #ifndef __USING_SJLJ_EXCEPTIONS__ @@ -81,8 +82,15 @@ struct _Unwind_Context void *ra; void *lsda; struct dwarf_eh_bases bases; - _Unwind_Word args_size; - char signal_frame; +#if __BYTE_ORDER == __BIG_ENDIAN + _Unwind_Word signal_frame : 1; + _Unwind_Word args_size : sizeof (_Unwind_Word) * 8 - 1; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + _Unwind_Word args_size : sizeof (_Unwind_Word) * 8 - 1; + _Unwind_Word signal_frame : 1; +#else +#error Unknown endianity +#endif }; /* Byte size of every register managed by these routines. */ @@ -1003,7 +1011,13 @@ execute_cfa_program (const unsigned char break; case DW_CFA_GNU_args_size: - insn_ptr = read_uleb128 (insn_ptr, &context->args_size); + { + _Unwind_Word args_size; + insn_ptr = read_uleb128 (insn_ptr, &args_size); + context->args_size = args_size; + if (context->args_size != args_size) + abort (); + } break; case DW_CFA_GNU_negative_offset_extended: --- libjava/exception.cc.jj 2006-05-22 13:39:48.000000000 -0400 +++ libjava/exception.cc 2006-05-22 14:48:30.000000000 -0400 @@ -31,6 +31,153 @@ namespace std } #include "unwind.h" +#if defined PIC && !defined __ia64__ + +#include + +extern "C" { + +static void *libgcc_s_handle; + +_Unwind_Reason_Code __attribute__((visibility ("hidden"))) +_Unwind_RaiseException (struct _Unwind_Exception *exc) +{ + static _Unwind_Reason_Code (*RaiseException) (struct _Unwind_Exception *); + + if (RaiseException == NULL) + { + if (libgcc_s_handle == NULL) + libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); + RaiseException = (__typeof (RaiseException)) + dlsym (libgcc_s_handle, "_Unwind_RaiseException"); + } + return RaiseException (exc); +} + +void __attribute__((visibility ("hidden"))) +_Unwind_Resume (struct _Unwind_Exception *exc) +{ + static void (*Resume) (struct _Unwind_Exception *); + + if (Resume == NULL) + { + if (libgcc_s_handle == NULL) + libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); + Resume = (__typeof (Resume)) + dlsym (libgcc_s_handle, "_Unwind_Resume"); + } + Resume (exc); +} + +__attribute__((visibility ("hidden"))) void * +_Unwind_GetLanguageSpecificData (struct _Unwind_Context *ctx) +{ + static void * (*GetLanguageSpecificData) (struct _Unwind_Context *); + + if (GetLanguageSpecificData == NULL) + { + if (libgcc_s_handle == NULL) + libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); + GetLanguageSpecificData = (__typeof (GetLanguageSpecificData)) + dlsym (libgcc_s_handle, "_Unwind_GetLanguageSpecificData"); + } + return GetLanguageSpecificData (ctx); +} + +_Unwind_Ptr __attribute__((visibility ("hidden"))) +_Unwind_GetRegionStart (struct _Unwind_Context *ctx) +{ + static _Unwind_Ptr (*GetRegionStart) (struct _Unwind_Context *); + + if (GetRegionStart == NULL) + { + if (libgcc_s_handle == NULL) + libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); + GetRegionStart = (__typeof (GetRegionStart)) + dlsym (libgcc_s_handle, "_Unwind_GetRegionStart"); + } + return GetRegionStart (ctx); +} + +_Unwind_Ptr __attribute__((visibility ("hidden"))) +_Unwind_GetDataRelBase (struct _Unwind_Context *ctx) +{ + static _Unwind_Ptr (*GetDataRelBase) (struct _Unwind_Context *); + + if (GetDataRelBase == NULL) + { + if (libgcc_s_handle == NULL) + libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); + GetDataRelBase = (__typeof (GetDataRelBase)) + dlsym (libgcc_s_handle, "_Unwind_GetDataRelBase"); + } + return GetDataRelBase (ctx); +} + +_Unwind_Ptr __attribute__((visibility ("hidden"))) +_Unwind_GetTextRelBase (struct _Unwind_Context *ctx) +{ + static _Unwind_Ptr (*GetTextRelBase) (struct _Unwind_Context *); + + if (GetTextRelBase == NULL) + { + if (libgcc_s_handle == NULL) + libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); + GetTextRelBase = (__typeof (GetTextRelBase)) + dlsym (libgcc_s_handle, "_Unwind_GetTextRelBase"); + } + return GetTextRelBase (ctx); +} + +_Unwind_Ptr __attribute__((visibility ("hidden"))) +_Unwind_GetIPInfo (struct _Unwind_Context *ctx, int *ip) +{ + static _Unwind_Ptr (*GetIPInfo) (struct _Unwind_Context *, int *ip); + + if (GetIPInfo == NULL) + { + if (libgcc_s_handle == NULL) + libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); + GetIPInfo = (__typeof (GetIPInfo)) + dlsym (libgcc_s_handle, "_Unwind_GetIPInfo"); + } + return GetIPInfo (ctx, ip); +} + +void __attribute__((visibility ("hidden"))) +_Unwind_SetIP (struct _Unwind_Context *ctx, _Unwind_Ptr ip) +{ + static void (*SetIP) (struct _Unwind_Context *, _Unwind_Ptr ip); + + if (SetIP == NULL) + { + if (libgcc_s_handle == NULL) + libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); + SetIP = (__typeof (SetIP)) + dlsym (libgcc_s_handle, "_Unwind_SetIP"); + } + SetIP (ctx, ip); +} + +void __attribute__((visibility ("hidden"))) +_Unwind_SetGR (struct _Unwind_Context *ctx, int num, _Unwind_Ptr gr) +{ + static void (*SetGR) (struct _Unwind_Context *, int num, _Unwind_Ptr gr); + + if (SetGR == NULL) + { + if (libgcc_s_handle == NULL) + libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); + SetGR = (__typeof (SetGR)) + dlsym (libgcc_s_handle, "_Unwind_SetGR"); + } + SetGR (ctx, num, gr); +} + +} + +#endif + struct alignment_test_struct { char space; 2005-05-08 Roger Sayle PR inline-asm/8788 * stmt.c (expand_asm_operands): Avoid calling force_reg on BLKmode operands. * gcc.dg/pr8788-1.c: New testcase. --- gcc/stmt.c (revision 99421) +++ gcc/stmt.c (revision 99422) @@ -877,7 +877,7 @@ expand_asm_operands (tree string, tree o if (asm_operand_ok (op, constraint) <= 0) { - if (allows_reg) + if (allows_reg && TYPE_MODE (type) != BLKmode) op = force_reg (TYPE_MODE (type), op); else if (!allows_mem) warning (0, "asm operand %d probably doesn%'t match constraints", --- gcc/testsuite/gcc.dg/pr8788-1.c (revision 0) +++ gcc/testsuite/gcc.dg/pr8788-1.c (revision 99422) @@ -0,0 +1,20 @@ +/* PR inline-asm/8788 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef struct { + long x[6]; +} myjmp_buf; + +typedef struct { + myjmp_buf regs; +} my_stack; + +void switch_to_stack (my_stack *stack){ + asm ( /* { dg-error "impossible constraint" } */ +/* { dg-warning "asm operand 1" "asm operand 1" { target *-*-* } 14 } */ + "\n" + : "+r" (stack->regs) + ); +} + 2005-11-30 Alexandre Oliva * gcc.c (find_a_file): Use update_path before access tests. Mostly from Thomas Walker * prefix.c (update_path): Move dir/../-stripping code to... (maybe_strip_dotdots): New function. Reorganize. --- gcc/gcc.c.orig 2005-12-01 18:38:38.000000000 -0200 +++ gcc/gcc.c 2005-12-01 18:41:01.000000000 -0200 @@ -2371,7 +2371,7 @@ find_a_file (struct path_prefix *pprefix, const char *name, int mode, int multilib) { - char *temp; + char *temp, *temp2; const char *const file_suffix = ((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : ""); struct prefix_list *pl; @@ -2407,19 +2407,18 @@ NULL)); } - temp = xmalloc (len); - /* Determine the filename to execute (special case for absolute paths). */ if (IS_ABSOLUTE_PATH (name)) { - if (access (name, mode) == 0) - { - strcpy (temp, name); - return temp; - } + /* IS_ABSOLUTE_PATHNAME lets anything through that starts with '/' */ + temp = update_path (name, NULL); + if (access (temp, mode) == 0) + return temp; } else + { + temp = xmalloc (len); for (pl = pprefix->plist; pl; pl = pl->next) { const char *this_name @@ -2435,24 +2434,30 @@ strcat (temp, machine_suffix); strcat (temp, multilib_name); strcat (temp, file_suffix); - if (access_check (temp, mode) == 0) + temp2 = update_path (temp, NULL); + if (access_check (temp2, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; - return temp; + free (temp); + return temp2; } + free (temp2); } /* Now try just the multilib_name. */ strcpy (temp, pl->prefix); strcat (temp, machine_suffix); strcat (temp, multilib_name); - if (access_check (temp, mode) == 0) + temp2 = update_path (temp, NULL); + if (access_check (temp2, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; - return temp; + free (temp); + return temp2; } + free (temp2); } /* Certain prefixes are tried with just the machine type, @@ -2467,23 +2472,29 @@ strcat (temp, just_machine_suffix); strcat (temp, multilib_name); strcat (temp, file_suffix); - if (access_check (temp, mode) == 0) + temp2 = update_path (temp, NULL); + if (access_check (temp2, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; - return temp; + free (temp); + return temp2; } + free (temp2); } strcpy (temp, pl->prefix); strcat (temp, just_machine_suffix); strcat (temp, multilib_name); - if (access_check (temp, mode) == 0) + temp2 = update_path (temp, NULL); + if (access_check (temp2, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; - return temp; + free (temp); + return temp2; } + free (temp2); } /* Certain prefixes can't be used without the machine suffix @@ -2497,24 +2508,31 @@ strcpy (temp, pl->prefix); strcat (temp, this_name); strcat (temp, file_suffix); - if (access_check (temp, mode) == 0) + temp2 = update_path (temp, NULL); + if (access_check (temp2, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; - return temp; + free (temp); + return temp2; } + free (temp2); } strcpy (temp, pl->prefix); strcat (temp, this_name); - if (access_check (temp, mode) == 0) + temp2 = update_path (temp, NULL); + if (access_check (temp2, mode) == 0) { if (pl->used_flag_ptr != 0) *pl->used_flag_ptr = 1; - return temp; + free (temp); + return temp2; } + free (temp2); } } + } free (temp); return 0; --- gcc/prefix.c.orig 2005-12-01 18:38:38.000000000 -0200 +++ gcc/prefix.c 2005-12-01 18:46:37.000000000 -0200 @@ -238,6 +238,105 @@ while (*string++); } +/* Strip dir/.. from a pathname when it makes sense, e.g., when this + would turn an inaccessible pathname into an accessible one. + + We short-circuit dir/.. when dir does not exist, and when + some/dir/../thing does not exist but some/thing does. In case + there are multiple possible dir/../ stripping possibilities that + would turn an inaccessible pathname into an accessible one, the one + closer to the end of the pathname is preferred. + + RESULT is the pathname that might contain such dotdot sequences to + be stripped. P points into RESULT, and indicates the location + where we should start looking for ../ sequences. + + Even though RESULT is const, P is not, and that's because + characters in it may be temporarily overwritten, so RESULT must not + be in read-only storage. + + The returned value is either a newly-allocated memory area, holding + a string that is the result of dotdot-stripping from the original + input strip, or RESULT itself, in which case any modifications made + to the string will have been undone. */ + +static const char * +maybe_strip_dotdots (const char *result, char *p) +{ + char *temp; + const char *path, *before, *after; + size_t len; + + while (1) + { + p = strchr (p, '.'); + if (p == NULL) + return result; + /* Look for `/../' */ + if (p[1] == '.' + && IS_DIR_SEPARATOR (p[2]) + && (p != result && IS_DIR_SEPARATOR (p[-1]))) + break; + else + ++p; + } + + *p = 0; + if (access (result, X_OK) == 0) + { + *p = '.'; + + path = maybe_strip_dotdots (result, p + 3); + if (access (path, F_OK) == 0) + return path; + if (path != result) + free ((char *) path); + } + else + *p = '.'; + + /* If we couldn't access the dir, or if recursion resulted in a + non-accessible pathname, we try stripping out dir/../. If `dir' + turns out to be `.', strip one more path component. */ + before = p; + do + { + --before; + while (before != result && IS_DIR_SEPARATOR (*before)) + --before; + while (before != result && !IS_DIR_SEPARATOR (before[-1])) + --before; + } + while (before != result && *before == '.' + && IS_DIR_SEPARATOR (*(before + 1))); + /* If we have something like `./..' or `/..', don't + strip anything more. */ + if (*before == '.' || IS_DIR_SEPARATOR (*before)) + return result; + + after = p + 3; + while (IS_DIR_SEPARATOR (*after)) + ++after; + + len = (after - result) + strlen (after); + + temp = xmalloc (len + 1 - (after - before)); + memcpy (temp, result, before - result); + memcpy (temp + (before - result), after, len + 1 - (after - result)); + + path = maybe_strip_dotdots (temp, temp + (before - result)); + + if (path != temp) + free (temp); + + if (access (path, F_OK) == 0) + result = path; + else if (path != result) + free ((char *) path); + + return result; +} + /* Update PATH using KEY if PATH starts with PREFIX. The returned string is always malloc-ed, and the caller is responsible for freeing it. */ @@ -245,7 +344,7 @@ char * update_path (const char *path, const char *key) { - char *result, *p; + char *result, *temp; if (! strncmp (path, std_prefix, strlen (std_prefix)) && key != 0) { @@ -265,62 +364,11 @@ else result = xstrdup (path); -#ifndef ALWAYS_STRIP_DOTDOT -#define ALWAYS_STRIP_DOTDOT 0 -#endif + temp = result; + result = (char *) maybe_strip_dotdots (temp, temp); - p = result; - while (1) - { - char *src, *dest; - - p = strchr (p, '.'); - if (p == NULL) - break; - /* Look for `/../' */ - if (p[1] == '.' - && IS_DIR_SEPARATOR (p[2]) - && (p != result && IS_DIR_SEPARATOR (p[-1]))) - { - *p = 0; - if (!ALWAYS_STRIP_DOTDOT && access (result, X_OK) == 0) - { - *p = '.'; - break; - } - else - { - /* We can't access the dir, so we won't be able to - access dir/.. either. Strip out `dir/../'. If `dir' - turns out to be `.', strip one more path component. */ - dest = p; - do - { - --dest; - while (dest != result && IS_DIR_SEPARATOR (*dest)) - --dest; - while (dest != result && !IS_DIR_SEPARATOR (dest[-1])) - --dest; - } - while (dest != result && *dest == '.'); - /* If we have something like `./..' or `/..', don't - strip anything more. */ - if (*dest == '.' || IS_DIR_SEPARATOR (*dest)) - { - *p = '.'; - break; - } - src = p + 3; - while (IS_DIR_SEPARATOR (*src)) - ++src; - p = dest; - while ((*dest++ = *src++) != 0) - ; - } - } - else - ++p; - } + if (result != temp) + free (temp); #ifdef UPDATE_PATH_HOST_CANONICALIZE /* Perform host dependent canonicalization when needed. */ 2005-09-29 Alexandre Oliva * error.c (dump_type) : Print reworded message. * g++.dg/overload/unknown1.C: New. --- gcc/cp/error.c.orig 2004-11-07 11:22:11.000000000 -0200 +++ gcc/cp/error.c 2005-09-29 16:13:20.000000000 -0300 @@ -302,7 +302,7 @@ switch (TREE_CODE (t)) { case UNKNOWN_TYPE: - pp_identifier (cxx_pp, ""); + pp_identifier (cxx_pp, ""); break; case TREE_LIST: --- gcc/testsuite/g++.dg/overload/unknown1.C 1970-01-01 00:00:00.000000000 +0000 +++ gcc/testsuite/g++.dg/overload/unknown1.C 2005-09-29 16:12:49.000000000 -0300 @@ -0,0 +1,9 @@ +// { dg-do compile } + +void foo(void); +int foo(int); +template void bar(T f); + +void baz() { + bar(foo); // { dg-error "" } +} 2005-12-18 Alexandre Oliva * optabs.c (expand_vector_binop): Do not use a SUBREG to modify a subword in the output if it matches any of the inputs. 2006-04-20 Jakub Jelinek * gcc.c-torture/execute/20060420-1.c: New test. --- gcc/optabs.c.orig 2005-11-21 11:43:20.000000000 -0200 +++ gcc/optabs.c 2005-12-18 18:35:14.000000000 -0200 @@ -1933,16 +1933,19 @@ for (i = 0; i < elts; ++i) { - /* If this is part of a register, and not the first item in the - word, we can't store using a SUBREG - that would clobber - previous results. + /* If this is part of a register, and not the first item in + the word, we can't store using a SUBREG - that would + clobber previous results, or even the input operands, if + target matches any of them. And storing with a SUBREG is only possible for the least significant part, hence we can't do it for big endian (unless we want to permute the evaluation order. */ if (GET_CODE (target) == REG && (BYTES_BIG_ENDIAN ? subsize < UNITS_PER_WORD - : ((i * subsize) % UNITS_PER_WORD) != 0)) + : (((i * subsize) % UNITS_PER_WORD) != 0 + || (subsize < UNITS_PER_WORD + && (target == op0 || target == op1))))) t = NULL_RTX; else t = simplify_gen_subreg (submode, target, mode, i * subsize); --- gcc/testsuite/gcc.c-torture/execute/20060420-1.c.jj 2006-04-20 18:47:19.000000000 +0200 +++ gcc/testsuite/gcc.c-torture/execute/20060420-1.c 2006-04-20 19:07:20.000000000 +0200 @@ -0,0 +1,71 @@ +extern void abort (void); + +typedef float v4flt __attribute__ ((vector_size (16))); + +void __attribute__ ((noinline)) foo (float *dst, float **src, int a, int n) +{ + int i, j; + int z = sizeof (v4flt) / sizeof (float); + unsigned m = sizeof (v4flt) - 1; + + for (j = 0; j < n && (((unsigned long) dst + j) & m); ++j) + { + float t = src[0][j]; + for (i = 1; i < a; ++i) + t += src[i][j]; + dst[j] = t; + } + + for (; j < (n - (4 * z - 1)); j += 4 * z) + { + v4flt t0 = *(v4flt *) (src[0] + j + 0 * z); + v4flt t1 = *(v4flt *) (src[0] + j + 1 * z); + v4flt t2 = *(v4flt *) (src[0] + j + 2 * z); + v4flt t3 = *(v4flt *) (src[0] + j + 3 * z); + for (i = 1; i < a; ++i) + { + t0 += *(v4flt *) (src[i] + j + 0 * z); + t1 += *(v4flt *) (src[i] + j + 1 * z); + t2 += *(v4flt *) (src[i] + j + 2 * z); + t3 += *(v4flt *) (src[i] + j + 3 * z); + } + *(v4flt *) (dst + j + 0 * z) = t0; + *(v4flt *) (dst + j + 1 * z) = t1; + *(v4flt *) (dst + j + 2 * z) = t2; + *(v4flt *) (dst + j + 3 * z) = t3; + } + for (; j < n; ++j) + { + float t = src[0][j]; + for (i = 1; i < a; ++i) + t += src[i][j]; + dst[j] = t; + } +} + +float buffer[64]; + +int +main (void) +{ + int i; + float *dst, *src[2]; + + dst = buffer; + dst += (-(long int) buffer & (16 * sizeof (float) - 1)) / sizeof (float); + src[0] = dst + 16; + src[1] = dst + 32; + for (i = 0; i < 16; ++i) + { + src[0][i] = (float) i + 11 * (float) i; + src[1][i] = (float) i + 12 * (float) i; + } + foo (dst, src, 2, 16); + for (i = 0; i < 16; ++i) + { + float e = (float) i + 11 * (float) i + (float) i + 12 * (float) i; + if (dst[i] != e) + abort (); + } + return 0; +} 2006-03-01 Alexandre Oliva * dwarf2out.c (dwarf2out_stack_adjust): Always track the stack pointer, instead of assuming it is possible to derive the correct args size from a call insn. --- gcc/dwarf2out.c.orig 2006-03-01 05:13:50.000000000 -0300 +++ gcc/dwarf2out.c 2006-03-01 05:41:38.000000000 -0300 @@ -1069,26 +1069,6 @@ dwarf2out_stack_adjust (rtx insn) if (prologue_epilogue_contains (insn) || sibcall_epilogue_contains (insn)) return; - if (!flag_asynchronous_unwind_tables && GET_CODE (insn) == CALL_INSN) - { - /* Extract the size of the args from the CALL rtx itself. */ - insn = PATTERN (insn); - if (GET_CODE (insn) == PARALLEL) - insn = XVECEXP (insn, 0, 0); - if (GET_CODE (insn) == SET) - insn = SET_SRC (insn); - if (GET_CODE (insn) != CALL) - abort (); - - dwarf2out_args_size ("", INTVAL (XEXP (insn, 1))); - return; - } - - /* If only calls can throw, and we have a frame pointer, - save up adjustments until we see the CALL_INSN. */ - else if (!flag_asynchronous_unwind_tables && cfa.reg != STACK_POINTER_REGNUM) - return; - if (GET_CODE (insn) == BARRIER) { /* When we see a BARRIER, we know to reset args_size to 0. Usually @@ -1111,9 +1091,20 @@ dwarf2out_stack_adjust (rtx insn) if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET) offset += stack_adjust_offset (XVECEXP (PATTERN (insn), 0, i)); } + else if (GET_CODE (insn) == CALL_INSN) + offset = 0; else return; + /* We handle this separately because we want stack adjustments in a + CALL_INSN to be handled. */; + if (GET_CODE (insn) == CALL_INSN) + { + /* If only calls can throw, adjust args_size only at call sites. */ + if (!flag_asynchronous_unwind_tables) + dwarf2out_args_size ("", args_size); + } + if (offset == 0) return; @@ -1128,6 +1119,16 @@ dwarf2out_stack_adjust (rtx insn) if (args_size < 0) args_size = 0; + /* If only calls can throw and we have a frame pointer, we'll save + up adjustments until we see the CALL_INSN. We used to return + early and derive args_size from NARGS in the CALL_INSN itself, + but that doesn't compute the right value if we have nested call + expansions, e.g., stack adjustments for a call have already been + emitted, and then we issue another call to compute an argument + for the enclosing call (i.e., bar (foo ())). */ + if (!flag_asynchronous_unwind_tables && cfa.reg != STACK_POINTER_REGNUM) + return; + label = dwarf2out_cfi_label (); def_cfa_1 (label, &cfa); dwarf2out_args_size (label, args_size); 2006-02-25 Alexandre Oliva * varasm.c (copy_constant): Handle VECTOR_CST. * gcc.dg/altivec-23.c: New test. --- gcc/varasm.c 2006-02-25 03:52:54.000000000 -0300 +++ gcc/varasm.c 2006-02-25 03:54:56.000000000 -0300 @@ -2464,6 +2464,19 @@ copy_constant (tree exp) return copy; } + case VECTOR_CST: + { + tree copy = copy_node (exp); + tree list = copy_list (TREE_VECTOR_CST_ELTS (exp)); + tree tail; + + TREE_VECTOR_CST_ELTS (copy) = list; + for (tail = list; tail; tail = TREE_CHAIN (tail)) + TREE_VALUE (tail) = copy_constant (TREE_VALUE (tail)); + + return copy; + } + default: { tree t; --- gcc/testsuite/gcc.dg/altivec-23.c 1970-01-01 00:00:00.000000000 +0000 +++ gcc/testsuite/gcc.dg/altivec-23.c 2006-02-25 04:10:36.000000000 -0300 @@ -0,0 +1,25 @@ +/* Verify that it is possible to define variables of composite types + containing vector types. We used to crash handling the + initializer of automatic ones. */ + +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-xfail-if "" { "powerpc-ibm-aix*" } { "-maltivec" } { "" } } */ +/* { dg-options "-maltivec -mabi=altivec" } */ + +#include + +typedef int bt; +typedef vector bt vt; +typedef struct { vt x; bt y[sizeof(vt) / sizeof (bt)]; } st; +#define INIT { 1, 2, 3, 4 } + +void f () +{ + vt x = INIT; + vt y[1] = { INIT }; + st s = { INIT, INIT }; +} + +vt x = INIT; +vt y[1] = { INIT }; +st s = { INIT, INIT }; 2006-12-08 Alexandre Oliva * g++.dg/template/array17.C: New test. 2006-10-27 Alexandre Oliva * typeck.c (non_reference): Don't dereference NULL type. --- gcc/cp/typeck.c.orig 2005-11-21 11:56:03.000000000 -0200 +++ gcc/cp/typeck.c 2006-10-27 03:28:04.000000000 -0300 @@ -6443,7 +6443,7 @@ casts_away_constness (tree t1, tree t2) tree non_reference (tree t) { - if (TREE_CODE (t) == REFERENCE_TYPE) + if (t != NULL_TREE && TREE_CODE (t) == REFERENCE_TYPE) t = TREE_TYPE (t); return t; } --- gcc/testsuite/g++.dg/template/array17.C 2006-10-04 16:28:56.502613000 +0200 +++ gcc/testsuite/g++.dg/template/array17.C 2006-12-08 12:38:27.000000000 +0100 @@ -0,0 +1,23 @@ +// { dg-do compile } + +template +struct V { + T& operator[](int); +}; + +struct S { + S operator +(int); + template T value(); +}; + +template +void R (T v) +{ + v[(S() + 0).template value()][0] = 0; +} + +int +main () +{ + R(V >()); +} 2006-12-08 Jakub Jelinek * g++.dg/opt/ifcvt1.C: New test. 2005-11-09 Eric Botcazou * ifcvt.c (noce_get_alt_condition): Use prev_nonnote_insn. (noce_try_abs): Negate if the comparison is reversed. Look only one instruction backwards for a REG_EQUAL note. * gcc.dg/ifcvt-fabs-1.c: New test. --- gcc/ifcvt.c.orig 2005-11-21 11:43:21.000000000 -0200 +++ gcc/ifcvt.c 2006-10-26 02:21:07.000000000 -0300 @@ -1406,7 +1406,7 @@ noce_get_alt_condition (struct noce_if_i rtx prev_insn; /* First, look to see if we put a constant in a register. */ - prev_insn = PREV_INSN (if_info->cond_earliest); + prev_insn = prev_nonnote_insn (if_info->cond_earliest); if (prev_insn && INSN_P (prev_insn) && GET_CODE (PATTERN (prev_insn)) == SET) @@ -1642,25 +1642,30 @@ noce_try_abs (struct noce_if_info *if_in if (rtx_equal_p (XEXP (cond, 0), b)) c = XEXP (cond, 1); else if (rtx_equal_p (XEXP (cond, 1), b)) - c = XEXP (cond, 0); + { + c = XEXP (cond, 0); + negate = !negate; + } else return FALSE; - /* Verify that C is zero. Search backward through the block for - a REG_EQUAL note if necessary. */ + /* Verify that C is zero. Search one step backward for a + REG_EQUAL note or a simple source if necessary. */ if (REG_P (c)) { - rtx insn, note = NULL; - for (insn = earliest; - insn != BB_HEAD (if_info->test_bb); - insn = PREV_INSN (insn)) - if (INSN_P (insn) - && ((note = find_reg_note (insn, REG_EQUAL, c)) - || (note = find_reg_note (insn, REG_EQUIV, c)))) - break; - if (! note) + rtx set, insn = prev_nonnote_insn (earliest); + if (insn + && (set = single_set (insn)) + && rtx_equal_p (SET_DEST (set), c)) + { + rtx note = find_reg_equal_equiv_note (insn); + if (note) + c = XEXP (note, 0); + else + c = SET_SRC (set); + } + else return FALSE; - c = XEXP (note, 0); } if (GET_CODE (c) == MEM && GET_CODE (XEXP (c, 0)) == SYMBOL_REF --- gcc/testsuite/gcc.dg/ifcvt-fabs-1.c 1970-01-01 00:00:00.000000000 +0000 +++ gcc/testsuite/gcc.dg/ifcvt-fabs-1.c 2006-10-26 02:20:24.000000000 -0300 @@ -0,0 +1,21 @@ +/* { dg-do run } */ +/* { dg-options "-O" } */ +/* { dg-options "-O -march=i686" { target i686-*-* } } */ + +extern void abort(void); + +float foo(float f) +{ + if (f < 0.0f) + f = -f; + + return f; +} + +int main(void) +{ + if (foo (-1.0f) != 1.0f) + abort (); + + return 0; +} --- gcc/testsuite/g++.dg/opt/ifcvt1.C 2006-10-04 16:28:56.502613000 +0200 +++ gcc/testsuite/g++.dg/opt/ifcvt1.C 2006-12-08 12:23:23.000000000 +0100 @@ -0,0 +1,17 @@ +// { dg-do compile } +// { dg-options "-O2 -fnon-call-exceptions" } + +struct S { ~S () throw () {} }; +double bar (); + +int +foo () +{ + S a; + int i = 0; + double c = bar (); + c = c < 0 ? -c : c; + if (c <= 1.e-8) + i += 24; + return i; +} 2007-04-02 Jakub Jelinek * expr.c (expand_expr_real) : Force op1 into register if target overlaps with op1. * g77.f-torture/execute/20070402.f: New test. --- gcc/expr.c.jj 2006-10-05 00:37:01.000000000 +0200 +++ gcc/expr.c 2007-04-02 13:28:52.000000000 +0200 @@ -8949,6 +8949,9 @@ expand_expr_real (tree exp, rtx target, if (! target) target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp))); + else if (GET_CODE (target) == MEM + && reg_overlap_mentioned_p (target, op1)) + op1 = force_reg (mode, op1); start_sequence (); --- gcc/testsuite/g77.f-torture/execute/20070402.f.jj 2007-04-02 13:29:51.000000000 +0200 +++ gcc/testsuite/g77.f-torture/execute/20070402.f 2007-04-02 12:11:00.000000000 +0200 @@ -0,0 +1,21 @@ + program rh233941 + implicit none + complex*16 z + z = dcmplx(1.0, 2.0) + call sub(z) + stop + end program rh233941 + + subroutine sub(z) + implicit none + complex*16 z + z = dcmplx(-dimag(z), dreal(z)) + call sub2(z) + return + end subroutine sub + + subroutine sub2(z) + implicit none + complex*16 z + if (dreal(z).ne.-2.0.or.dimag(z).ne.1.0) call abort + end subroutine sub2 2007-01-24 Steve LoBasso Paolo Carlini * include/bits/deque.tcc (deque<>::erase(iterator, iterator)): Fix condition. * testsuite/23_containers/deque/modifiers/erase/3.cc: New. --- libstdc++-v3/include/bits/deque.tcc (revision 121146) +++ libstdc++-v3/include/bits/deque.tcc (revision 121147) @@ -140,7 +140,7 @@ namespace _GLIBCXX_STD { const difference_type __n = __last - __first; const difference_type __elems_before = __first - this->_M_impl._M_start; - if (static_cast(__elems_before) < (size() - __n) / 2) + if (static_cast(__elems_before) <= (size() - __n) / 2) { std::copy_backward(this->_M_impl._M_start, __first, __last); iterator __new_start = this->_M_impl._M_start + __n; --- libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/3.cc (revision 0) +++ libstdc++-v3/testsuite/23_containers/deque/modifiers/erase/3.cc (revision 121147) @@ -0,0 +1,52 @@ +// Copyright (C) 2007 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 2, 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 COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// 23.2.1.3 deque modifiers + +#include +#include + +void erase(size_t num_elm, size_t elm_strt, size_t elm_end) +{ + bool test __attribute__((unused)) = true; + using __gnu_test::copy_tracker; + using __gnu_test::assignment_operator; + + std::deque x(num_elm); + copy_tracker::reset(); + + x.erase(x.begin() + elm_strt, x.begin() + elm_end); + + const size_t min_num_cpy = std::min(elm_strt, num_elm - elm_end); + VERIFY( assignment_operator::count() == min_num_cpy ); +} + +// http://gcc.gnu.org/ml/libstdc++/2007-01/msg00098.html +void test01() +{ + for (size_t num_elm = 0; num_elm <= 10; ++num_elm) + for (size_t elm_strt = 0; elm_strt <= num_elm; ++elm_strt) + for (size_t elm_end = elm_strt; elm_end <= num_elm; ++elm_end) + erase(num_elm, elm_strt, elm_end); +} + +int main() +{ + test01(); + return 0; +} 2007-04-12 Jakub Jelinek * fr.po: Use %s rather than %S. * rw.po: Comment out translations with bogus format strings. --- gcc/po/fr.po.jj 2006-10-05 00:33:36.000000000 +0200 +++ gcc/po/fr.po 2007-04-13 00:23:29.000000000 +0200 @@ -17100,7 +17100,7 @@ msgstr "%s liste d'expressions traitée c #: cp/typeck.c:4490 msgid "%s from type `%T' to type `%T' casts away constness" -msgstr "%S à partir du « %T » vers le type « %T » provoque un transtypage sans constante" +msgstr "%s à partir du « %T » vers le type « %T » provoque un transtypage sans constante" #: cp/typeck.c:4692 msgid "invalid static_cast from type `%T' to type `%T'" 2007-04-21 Alexandre Oliva * gcse.c (store_killed_in_insn): Handle PARALLELs. (store_killed_in_pat): New. * gcc.dg/movsi-sm-1.c: New. --- gcc/gcse.c.jj 2007-02-23 21:29:12.000000000 +0100 +++ gcc/gcse.c 2007-07-18 20:41:08.000000000 +0200 @@ -7427,6 +7427,40 @@ find_loads (rtx x, rtx store_pattern, in return ret; } +static inline bool +store_killed_in_pat (rtx x, rtx pat, int after) +{ + if (GET_CODE (pat) == SET) + { + rtx dest = SET_DEST (pat); + + if (GET_CODE (dest) == SIGN_EXTRACT + || GET_CODE (dest) == ZERO_EXTRACT) + dest = XEXP (dest, 0); + + /* Check for memory stores to aliased objects. */ + if (GET_CODE (dest) == MEM + && !expr_equiv_p (dest, x)) + { + if (after) + { + if (output_dependence (dest, x)) + return true; + } + else + { + if (output_dependence (x, dest)) + return true; + } + } + } + + if (find_loads (pat, x, after)) + return true; + + return false; +} + /* Check if INSN kills the store pattern X (is aliased with it). AFTER is true if we are checking the case when store X occurs after the insn. Return true if it it does. */ @@ -7434,7 +7468,7 @@ find_loads (rtx x, rtx store_pattern, in static bool store_killed_in_insn (rtx x, rtx x_regs, rtx insn, int after) { - rtx reg, base, note; + rtx reg, base, note, pat; if (!INSN_P (insn)) return false; @@ -7461,33 +7495,20 @@ store_killed_in_insn (rtx x, rtx x_regs, return false; } - if (GET_CODE (PATTERN (insn)) == SET) + pat = PATTERN (insn); + if (GET_CODE (pat) == SET) { - rtx pat = PATTERN (insn); - rtx dest = SET_DEST (pat); - - if (GET_CODE (dest) == SIGN_EXTRACT - || GET_CODE (dest) == ZERO_EXTRACT) - dest = XEXP (dest, 0); - - /* Check for memory stores to aliased objects. */ - if (GET_CODE (dest) == MEM - && !expr_equiv_p (dest, x)) - { - if (after) - { - if (output_dependence (dest, x)) - return true; - } - else - { - if (output_dependence (x, dest)) - return true; - } - } - if (find_loads (SET_SRC (pat), x, after)) + if (store_killed_in_pat (x, pat, after)) return true; } + else if (GET_CODE (pat) == PARALLEL) + { + int i; + + for (i = 0; i < XVECLEN (pat, 0); i++) + if (store_killed_in_pat (x, XVECEXP (pat, 0, i), after)) + return true; + } else if (find_loads (PATTERN (insn), x, after)) return true; --- gcc/testsuite/gcc.dg/movsi-sm-1.c.jj 2007-07-18 20:58:08.000000000 +0200 +++ gcc/testsuite/gcc.dg/movsi-sm-1.c 2007-07-18 21:01:52.000000000 +0200 @@ -0,0 +1,35 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-options "-O2 -mtune=i386" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +int ret = 1; +char buf[128]; + +void +__attribute__((noinline)) +bug (int arg) +{ + char str[28]; + + __builtin_memcpy (str, "Bugged!", 8); + + if (arg & 0200) + { + __builtin_memcpy (str, "This is what we should get!", 28); + ret = 0; + } + + if (arg & 0100) + __builtin_memcpy (str, "Broken!", 8); + + __builtin_sprintf (buf, "%s\n", str); +} + +int +main () +{ + bug (0200); + if (ret) + return ret; + return __builtin_strcmp (buf, "This is what we should get!\n") != 0; +} 2007-06-08 Jatin Nansi * config/locale/ieee_1003.1-2001/codecvt_specializations.h: Make sure _M_int_enc and _M_ext_enc are '\0' terminated. --- libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h.jj 2007-02-23 21:29:34.000000000 +0100 +++ libstdc++-v3/config/locale/ieee_1003.1-2001/codecvt_specializations.h 2007-07-19 14:20:20.000000000 +0200 @@ -83,8 +83,10 @@ int __ibom = 0, int __ebom = 0) : _M_in_desc(0), _M_out_desc(0), _M_ext_bom(__ebom), _M_int_bom(__ibom) { - strncpy(_M_int_enc, __int, _S_max_size); - strncpy(_M_ext_enc, __ext, _S_max_size); + strncpy(_M_int_enc, __int, _S_max_size - 1); + strncpy(_M_ext_enc, __ext, _S_max_size - 1); + _M_int_enc[_S_max_size - 1] = '\0'; + _M_ext_enc[_S_max_size - 1] = '\0'; _M_init(); } @@ -98,8 +100,10 @@ // information. __enc_traits(const __enc_traits& __obj): _M_in_desc(0), _M_out_desc(0) { - strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size); - strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size); + strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size - 1); + strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size - 1); + _M_int_enc[_S_max_size - 1] = '\0'; + _M_ext_enc[_S_max_size - 1] = '\0'; _M_ext_bom = __obj._M_ext_bom; _M_int_bom = __obj._M_int_bom; _M_destroy(); @@ -110,8 +114,10 @@ __enc_traits& operator=(const __enc_traits& __obj) { - strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size); - strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size); + strncpy(_M_int_enc, __obj._M_int_enc, _S_max_size - 1); + strncpy(_M_ext_enc, __obj._M_ext_enc, _S_max_size - 1); + _M_int_enc[_S_max_size - 1] = '\0'; + _M_ext_enc[_S_max_size - 1] = '\0'; _M_ext_bom = __obj._M_ext_bom; _M_int_bom = __obj._M_int_bom; _M_destroy();