Submitted By: Jim Gifford (jim at cross-lfs dot org) Date: 08-28-2013 Initial Package Version: 4.8.1 Origin: Upstream Upstream Status: Applied Description: This is a branch update for gcc-4.8.1, and should be rechecked periodically. This patch was made from Revision # 202050. diff -Naur gcc-4.8.1.orig/fixincludes/fixincl.x gcc-4.8.1/fixincludes/fixincl.x --- gcc-4.8.1.orig/fixincludes/fixincl.x 2013-01-15 22:07:20.000000000 -0600 +++ gcc-4.8.1/fixincludes/fixincl.x 2013-05-31 06:43:36.437119000 -0500 @@ -2,11 +2,11 @@ * * DO NOT EDIT THIS FILE (fixincl.x) * - * It has been AutoGen-ed Saturday December 29, 2012 at 09:17:09 AM BRST + * It has been AutoGen-ed Thursday May 16, 2013 at 03:34:25 PM MEST * From the definitions inclhack.def * and the template file fixincl */ -/* DO NOT SVN-MERGE THIS FILE, EITHER Sat Dec 29 09:17:10 BRST 2012 +/* DO NOT SVN-MERGE THIS FILE, EITHER Thu May 16 15:34:25 MEST 2013 * * You must regenerate it. Use the ./genfixes script. * @@ -6663,7 +6663,7 @@ */ static const char* apzSolaris_Pow_Int_OverloadPatch[] = { "format", - "#ifndef __GXX_EXPERIMENTAL_CXX0X__\n\ + "#if __cplusplus < 201103L\n\ %0\n\ #endif", (char*)NULL }; diff -Naur gcc-4.8.1.orig/fixincludes/inclhack.def gcc-4.8.1/fixincludes/inclhack.def --- gcc-4.8.1.orig/fixincludes/inclhack.def 2013-01-15 22:07:20.000000000 -0600 +++ gcc-4.8.1/fixincludes/inclhack.def 2013-05-31 06:43:36.437119000 -0500 @@ -3447,7 +3447,7 @@ /* - * The pow overloads with int were removed in C++ 2011. + * The pow overloads with int were removed in C++ 2011 DR 550. */ fix = { hackname = solaris_pow_int_overload; @@ -3456,7 +3456,7 @@ select = "^[ \t]*inline [a-z ]* pow\\([^()]*, int [^()]*\\)" " *\\{[^{}]*\n[^{}]*\\}"; c_fix = format; - c_fix_arg = "#ifndef __GXX_EXPERIMENTAL_CXX0X__\n%0\n#endif"; + c_fix_arg = "#if __cplusplus < 201103L\n%0\n#endif"; test_text = " inline long double pow(long double __X, int __Y) { return\n" diff -Naur gcc-4.8.1.orig/fixincludes/tests/base/iso/math_iso.h gcc-4.8.1/fixincludes/tests/base/iso/math_iso.h --- gcc-4.8.1.orig/fixincludes/tests/base/iso/math_iso.h 2011-08-10 03:43:38.000000000 -0500 +++ gcc-4.8.1/fixincludes/tests/base/iso/math_iso.h 2013-05-31 06:43:36.437119000 -0500 @@ -10,7 +10,7 @@ #if defined( SOLARIS_POW_INT_OVERLOAD_CHECK ) -#ifndef __GXX_EXPERIMENTAL_CXX0X__ +#if __cplusplus < 201103L inline long double pow(long double __X, int __Y) { return __powl(__X, (long double) (__Y)); } #endif diff -Naur gcc-4.8.1.orig/gcc/ada/gcc-interface/ada-tree.h gcc-4.8.1/gcc/ada/gcc-interface/ada-tree.h --- gcc-4.8.1.orig/gcc/ada/gcc-interface/ada-tree.h 2013-02-25 13:08:51.000000000 -0600 +++ gcc-4.8.1/gcc/ada/gcc-interface/ada-tree.h 2013-06-13 02:51:32.352026000 -0500 @@ -360,10 +360,6 @@ constant CONSTRUCTOR. */ #define DECL_CONST_ADDRESS_P(NODE) DECL_LANG_FLAG_0 (CONST_DECL_CHECK (NODE)) -/* Nonzero in a PARM_DECL if it is always used by double reference, i.e. a - pair of INDIRECT_REFs is needed to access the object. */ -#define DECL_BY_DOUBLE_REF_P(NODE) DECL_LANG_FLAG_0 (PARM_DECL_CHECK (NODE)) - /* Nonzero in a FIELD_DECL if it is declared as aliased. */ #define DECL_ALIASED_P(NODE) DECL_LANG_FLAG_0 (FIELD_DECL_CHECK (NODE)) diff -Naur gcc-4.8.1.orig/gcc/ada/gcc-interface/decl.c gcc-4.8.1/gcc/ada/gcc-interface/decl.c --- gcc-4.8.1.orig/gcc/ada/gcc-interface/decl.c 2013-05-07 03:03:15.000000000 -0500 +++ gcc-4.8.1/gcc/ada/gcc-interface/decl.c 2013-06-13 02:51:32.352026000 -0500 @@ -1019,7 +1019,7 @@ save_gnu_tree (gnat_entity, gnu_decl, true); saved = true; annotate_object (gnat_entity, gnu_type, NULL_TREE, - false, false); + false); /* This assertion will fail if the renamed object isn't aligned enough as to make it possible to honor the alignment set on the renaming. */ @@ -1605,7 +1605,7 @@ type of the object and not on the object directly, and makes it possible to support all confirming representation clauses. */ annotate_object (gnat_entity, TREE_TYPE (gnu_decl), gnu_object_size, - used_by_ref, false); + used_by_ref); } break; @@ -5595,7 +5595,7 @@ /* The parameter can be indirectly modified if its address is taken. */ bool ro_param = in_param && !Address_Taken (gnat_param); bool by_return = false, by_component_ptr = false; - bool by_ref = false, by_double_ref = false; + bool by_ref = false; tree gnu_param; /* Copy-return is used only for the first parameter of a valued procedure. @@ -5720,19 +5720,6 @@ gnu_param_type = build_qualified_type (gnu_param_type, TYPE_QUAL_RESTRICT); by_ref = true; - - /* In some ABIs, e.g. SPARC 32-bit, fat pointer types are themselves - passed by reference. Pass them by explicit reference, this will - generate more debuggable code at -O0. */ - if (TYPE_IS_FAT_POINTER_P (gnu_param_type) - && targetm.calls.pass_by_reference (pack_cumulative_args (NULL), - TYPE_MODE (gnu_param_type), - gnu_param_type, - true)) - { - gnu_param_type = build_reference_type (gnu_param_type); - by_double_ref = true; - } } /* Pass In Out or Out parameters using copy-in copy-out mechanism. */ @@ -5775,7 +5762,6 @@ gnu_param = create_param_decl (gnu_param_name, gnu_param_type, ro_param || by_ref || by_component_ptr); DECL_BY_REF_P (gnu_param) = by_ref; - DECL_BY_DOUBLE_REF_P (gnu_param) = by_double_ref; DECL_BY_COMPONENT_PTR_P (gnu_param) = by_component_ptr; DECL_BY_DESCRIPTOR_P (gnu_param) = (mech == By_Descriptor || mech == By_Short_Descriptor); @@ -7427,18 +7413,13 @@ /* Given GNAT_ENTITY, an object (constant, variable, parameter, exception) and GNU_TYPE, its corresponding GCC type, set Esize and Alignment to the size and alignment used by Gigi. Prefer SIZE over TYPE_SIZE if non-null. - BY_REF is true if the object is used by reference and BY_DOUBLE_REF is - true if the object is used by double reference. */ + BY_REF is true if the object is used by reference. */ void -annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size, bool by_ref, - bool by_double_ref) +annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size, bool by_ref) { if (by_ref) { - if (by_double_ref) - gnu_type = TREE_TYPE (gnu_type); - if (TYPE_IS_FAT_POINTER_P (gnu_type)) gnu_type = TYPE_UNCONSTRAINED_ARRAY (gnu_type); else diff -Naur gcc-4.8.1.orig/gcc/ada/gcc-interface/gigi.h gcc-4.8.1/gcc/ada/gcc-interface/gigi.h --- gcc-4.8.1.orig/gcc/ada/gcc-interface/gigi.h 2013-02-06 07:19:20.000000000 -0600 +++ gcc-4.8.1/gcc/ada/gcc-interface/gigi.h 2013-06-13 02:51:32.352026000 -0500 @@ -177,10 +177,9 @@ /* Given GNAT_ENTITY, an object (constant, variable, parameter, exception) and GNU_TYPE, its corresponding GCC type, set Esize and Alignment to the size and alignment used by Gigi. Prefer SIZE over TYPE_SIZE if non-null. - BY_REF is true if the object is used by reference and BY_DOUBLE_REF is - true if the object is used by double reference. */ + BY_REF is true if the object is used by reference. */ extern void annotate_object (Entity_Id gnat_entity, tree gnu_type, tree size, - bool by_ref, bool by_double_ref); + bool by_ref); /* Return the variant part of RECORD_TYPE, if any. Otherwise return NULL. */ extern tree get_variant_part (tree record_type); @@ -930,11 +929,10 @@ /* Convert GNU_EXPR, a pointer to a VMS descriptor, to GNU_TYPE, a regular pointer or fat pointer type. GNU_EXPR_ALT_TYPE is the alternate (32-bit) - pointer type of GNU_EXPR. BY_REF is true if the result is to be used by - reference. GNAT_SUBPROG is the subprogram to which the VMS descriptor is - passed. */ + pointer type of GNU_EXPR. GNAT_SUBPROG is the subprogram to which the + descriptor is passed. */ extern tree convert_vms_descriptor (tree gnu_type, tree gnu_expr, - tree gnu_expr_alt_type, bool by_ref, + tree gnu_expr_alt_type, Entity_Id gnat_subprog); /* Indicate that we need to take the address of T and that it therefore diff -Naur gcc-4.8.1.orig/gcc/ada/gcc-interface/trans.c gcc-4.8.1/gcc/ada/gcc-interface/trans.c --- gcc-4.8.1.orig/gcc/ada/gcc-interface/trans.c 2013-05-26 05:04:50.000000000 -0500 +++ gcc-4.8.1/gcc/ada/gcc-interface/trans.c 2013-08-13 10:59:03.399464000 -0500 @@ -1075,19 +1075,6 @@ { const bool read_only = DECL_POINTS_TO_READONLY_P (gnu_result); - /* First do the first dereference if needed. */ - if (TREE_CODE (gnu_result) == PARM_DECL - && DECL_BY_DOUBLE_REF_P (gnu_result)) - { - gnu_result = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result); - if (TREE_CODE (gnu_result) == INDIRECT_REF) - TREE_THIS_NOTRAP (gnu_result) = 1; - - /* The first reference, in case of a double reference, always points - to read-only, see gnat_to_gnu_param for the rationale. */ - TREE_READONLY (gnu_result) = 1; - } - /* If it's a PARM_DECL to foreign convention subprogram, convert it. */ if (TREE_CODE (gnu_result) == PARM_DECL && DECL_BY_COMPONENT_PTR_P (gnu_result)) @@ -2280,7 +2267,10 @@ if (TREE_CODE (val) != INTEGER_CST) return true; - return tree_int_cst_equal (val, min_or_max_val) == 1; + if (max) + return tree_int_cst_lt (val, min_or_max_val) == 0; + else + return tree_int_cst_lt (min_or_max_val, val) == 0; } /* Return true if VAL (of type TYPE) can equal the minimum value of TYPE. @@ -3251,7 +3241,6 @@ = convert_vms_descriptor (TREE_TYPE (gnu_subprog_param), gnu_stub_param, DECL_PARM_ALT_TYPE (gnu_stub_param), - DECL_BY_DOUBLE_REF_P (gnu_subprog_param), gnat_subprog); } else @@ -3546,8 +3535,7 @@ bool is_var_decl = (TREE_CODE (gnu_param) == VAR_DECL); annotate_object (gnat_param, TREE_TYPE (gnu_param), NULL_TREE, - DECL_BY_REF_P (gnu_param), - !is_var_decl && DECL_BY_DOUBLE_REF_P (gnu_param)); + DECL_BY_REF_P (gnu_param)); if (is_var_decl) save_gnu_tree (gnat_param, NULL_TREE, false); @@ -4009,12 +3997,6 @@ /* The symmetry of the paths to the type of an entity is broken here since arguments don't know that they will be passed by ref. */ gnu_formal_type = TREE_TYPE (gnu_formal); - - if (DECL_BY_DOUBLE_REF_P (gnu_formal)) - gnu_actual - = build_unary_op (ADDR_EXPR, TREE_TYPE (gnu_formal_type), - gnu_actual); - gnu_actual = build_unary_op (ADDR_EXPR, gnu_formal_type, gnu_actual); } else if (is_true_formal_parm && DECL_BY_COMPONENT_PTR_P (gnu_formal)) diff -Naur gcc-4.8.1.orig/gcc/ada/gcc-interface/utils.c gcc-4.8.1/gcc/ada/gcc-interface/utils.c --- gcc-4.8.1.orig/gcc/ada/gcc-interface/utils.c 2013-02-06 07:19:20.000000000 -0600 +++ gcc-4.8.1/gcc/ada/gcc-interface/utils.c 2013-06-13 02:51:32.352026000 -0500 @@ -4073,33 +4073,25 @@ /* Convert GNU_EXPR, a pointer to a VMS descriptor, to GNU_TYPE, a regular pointer or fat pointer type. GNU_EXPR_ALT_TYPE is the alternate (32-bit) - pointer type of GNU_EXPR. BY_REF is true if the result is to be used by - reference. GNAT_SUBPROG is the subprogram to which the VMS descriptor is - passed. */ + pointer type of GNU_EXPR. GNAT_SUBPROG is the subprogram to which the + descriptor is passed. */ tree convert_vms_descriptor (tree gnu_type, tree gnu_expr, tree gnu_expr_alt_type, - bool by_ref, Entity_Id gnat_subprog) + Entity_Id gnat_subprog) { tree desc_type = TREE_TYPE (TREE_TYPE (gnu_expr)); tree desc = build1 (INDIRECT_REF, desc_type, gnu_expr); tree mbo = TYPE_FIELDS (desc_type); const char *mbostr = IDENTIFIER_POINTER (DECL_NAME (mbo)); tree mbmo = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (mbo))); - tree real_type, is64bit, gnu_expr32, gnu_expr64; - - if (by_ref) - real_type = TREE_TYPE (gnu_type); - else - real_type = gnu_type; + tree is64bit, gnu_expr32, gnu_expr64; /* If the field name is not MBO, it must be 32-bit and no alternate. Otherwise primary must be 64-bit and alternate 32-bit. */ if (strcmp (mbostr, "MBO") != 0) { - tree ret = convert_vms_descriptor32 (real_type, gnu_expr, gnat_subprog); - if (by_ref) - ret = build_unary_op (ADDR_EXPR, gnu_type, ret); + tree ret = convert_vms_descriptor32 (gnu_type, gnu_expr, gnat_subprog); return ret; } @@ -4116,14 +4108,9 @@ integer_minus_one_node)); /* Build the 2 possible end results. */ - gnu_expr64 = convert_vms_descriptor64 (real_type, gnu_expr, gnat_subprog); - if (by_ref) - gnu_expr64 = build_unary_op (ADDR_EXPR, gnu_type, gnu_expr64); + gnu_expr64 = convert_vms_descriptor64 (gnu_type, gnu_expr, gnat_subprog); gnu_expr = fold_convert (gnu_expr_alt_type, gnu_expr); - gnu_expr32 = convert_vms_descriptor32 (real_type, gnu_expr, gnat_subprog); - if (by_ref) - gnu_expr32 = build_unary_op (ADDR_EXPR, gnu_type, gnu_expr32); - + gnu_expr32 = convert_vms_descriptor32 (gnu_type, gnu_expr, gnat_subprog); return build3 (COND_EXPR, gnu_type, is64bit, gnu_expr64, gnu_expr32); } diff -Naur gcc-4.8.1.orig/gcc/ada/targparm.ads gcc-4.8.1/gcc/ada/targparm.ads --- gcc-4.8.1.orig/gcc/ada/targparm.ads 2013-02-06 04:35:52.000000000 -0600 +++ gcc-4.8.1/gcc/ada/targparm.ads 2013-06-13 02:51:32.352026000 -0500 @@ -436,7 +436,7 @@ -- the source program may not contain explicit 64-bit shifts. In addition, -- the code generated for packed arrays will avoid the use of long shifts. - Support_Nondefault_SSO_On_Target : Boolean := False; + Support_Nondefault_SSO_On_Target : Boolean := True; -- If True, the back end supports the non-default Scalar_Storage_Order -- (i.e. allows non-confirming Scalar_Storage_Order attribute definition -- clauses). diff -Naur gcc-4.8.1.orig/gcc/asan.c gcc-4.8.1/gcc/asan.c --- gcc-4.8.1.orig/gcc/asan.c 2013-02-28 15:23:23.000000000 -0600 +++ gcc-4.8.1/gcc/asan.c 2013-08-13 12:02:13.543712000 -0500 @@ -1675,7 +1675,7 @@ access to the last byte of the argument; it uses the result of the call to deduce the offset of that last byte. - Upon completion, iff the call has actullay been instrumented, this + Upon completion, iff the call has actually been instrumented, this function returns TRUE and *ITER points to the statement logically following the built-in strlen function call *ITER was initially pointing to. Otherwise, the function returns FALSE and *ITER @@ -1706,10 +1706,10 @@ /* Instrument the access to the first byte of str_arg. i.e: _1 = str_arg; instrument (_1); */ + tree cptr_type = build_pointer_type (char_type_node); gimple str_arg_ssa = gimple_build_assign_with_ops (NOP_EXPR, - make_ssa_name (build_pointer_type - (char_type_node), NULL), + make_ssa_name (cptr_type, NULL), str_arg, NULL); gimple_set_location (str_arg_ssa, loc); gimple_stmt_iterator gsi = *iter; @@ -1728,8 +1728,7 @@ pointer_plus expr: (_1 + len). */ gimple stmt = gimple_build_assign_with_ops (POINTER_PLUS_EXPR, - make_ssa_name (TREE_TYPE (str_arg), - NULL), + make_ssa_name (cptr_type, NULL), gimple_assign_lhs (str_arg_ssa), len); gimple_set_location (stmt, loc); diff -Naur gcc-4.8.1.orig/gcc/c-family/c-ada-spec.c gcc-4.8.1/gcc/c-family/c-ada-spec.c --- gcc-4.8.1.orig/gcc/c-family/c-ada-spec.c 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/c-family/c-ada-spec.c 2013-08-09 05:53:01.541722000 -0500 @@ -2900,7 +2900,7 @@ pp_string (buffer, " -- "); dump_sloc (buffer, t); - if (is_abstract) + if (is_abstract || !DECL_ASSEMBLER_NAME (t)) return 1; newline_and_indent (buffer, spc); diff -Naur gcc-4.8.1.orig/gcc/collect2.c gcc-4.8.1/gcc/collect2.c --- gcc-4.8.1.orig/gcc/collect2.c 2013-02-06 20:53:13.000000000 -0600 +++ gcc-4.8.1/gcc/collect2.c 2013-06-20 12:12:17.412846000 -0500 @@ -366,8 +366,8 @@ /* Delete tempfiles and exit function. */ -void -collect_exit (int status) +static void +collect_atexit (void) { if (c_file != 0 && c_file[0]) maybe_unlink (c_file); @@ -395,13 +395,8 @@ maybe_unlink (lderrout); } - if (status != 0 && output_file != 0 && output_file[0]) - maybe_unlink (output_file); - if (response_file) maybe_unlink (response_file); - - exit (status); } @@ -970,6 +965,9 @@ signal (SIGCHLD, SIG_DFL); #endif + if (atexit (collect_atexit) != 0) + fatal_error ("atexit failed"); + /* Unlock the stdio streams. */ unlock_std_streams (); @@ -1110,55 +1108,55 @@ if (ld_file_name == 0) #endif #ifdef REAL_LD_FILE_NAME - ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME); + ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME, X_OK); if (ld_file_name == 0) #endif /* Search the (target-specific) compiler dirs for ld'. */ - ld_file_name = find_a_file (&cpath, real_ld_suffix); + ld_file_name = find_a_file (&cpath, real_ld_suffix, X_OK); /* Likewise for `collect-ld'. */ if (ld_file_name == 0) { - ld_file_name = find_a_file (&cpath, collect_ld_suffix); + ld_file_name = find_a_file (&cpath, collect_ld_suffix, X_OK); use_collect_ld = ld_file_name != 0; } /* Search the compiler directories for `ld'. We have protection against recursive calls in find_a_file. */ if (ld_file_name == 0) - ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker]); + ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker], X_OK); /* Search the ordinary system bin directories for `ld' (if native linking) or `TARGET-ld' (if cross). */ if (ld_file_name == 0) - ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker]); + ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker], X_OK); #ifdef REAL_NM_FILE_NAME - nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME); + nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME, X_OK); if (nm_file_name == 0) #endif - nm_file_name = find_a_file (&cpath, gnm_suffix); + nm_file_name = find_a_file (&cpath, gnm_suffix, X_OK); if (nm_file_name == 0) - nm_file_name = find_a_file (&path, full_gnm_suffix); + nm_file_name = find_a_file (&path, full_gnm_suffix, X_OK); if (nm_file_name == 0) - nm_file_name = find_a_file (&cpath, nm_suffix); + nm_file_name = find_a_file (&cpath, nm_suffix, X_OK); if (nm_file_name == 0) - nm_file_name = find_a_file (&path, full_nm_suffix); + nm_file_name = find_a_file (&path, full_nm_suffix, X_OK); #ifdef LDD_SUFFIX - ldd_file_name = find_a_file (&cpath, ldd_suffix); + ldd_file_name = find_a_file (&cpath, ldd_suffix, X_OK); if (ldd_file_name == 0) - ldd_file_name = find_a_file (&path, full_ldd_suffix); + ldd_file_name = find_a_file (&path, full_ldd_suffix, X_OK); #endif #ifdef REAL_STRIP_FILE_NAME - strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME); + strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME, X_OK); if (strip_file_name == 0) #endif - strip_file_name = find_a_file (&cpath, gstrip_suffix); + strip_file_name = find_a_file (&cpath, gstrip_suffix, X_OK); if (strip_file_name == 0) - strip_file_name = find_a_file (&path, full_gstrip_suffix); + strip_file_name = find_a_file (&path, full_gstrip_suffix, X_OK); if (strip_file_name == 0) - strip_file_name = find_a_file (&cpath, strip_suffix); + strip_file_name = find_a_file (&cpath, strip_suffix, X_OK); if (strip_file_name == 0) - strip_file_name = find_a_file (&path, full_strip_suffix); + strip_file_name = find_a_file (&path, full_strip_suffix, X_OK); /* Determine the full path name of the C compiler to use. */ c_file_name = getenv ("COLLECT_GCC"); @@ -1171,12 +1169,12 @@ #endif } - p = find_a_file (&cpath, c_file_name); + p = find_a_file (&cpath, c_file_name, X_OK); /* Here it should be safe to use the system search path since we should have already qualified the name of the compiler when it is needed. */ if (p == 0) - p = find_a_file (&path, c_file_name); + p = find_a_file (&path, c_file_name, X_OK); if (p) c_file_name = p; @@ -1813,7 +1811,7 @@ error ("%s terminated with signal %d [%s]%s", prog, sig, strsignal(sig), WCOREDUMP(status) ? ", core dumped" : ""); - collect_exit (FATAL_EXIT_CODE); + exit (FATAL_EXIT_CODE); } if (WIFEXITED (status)) @@ -1829,7 +1827,7 @@ if (ret != 0) { error ("%s returned %d exit status", prog, ret); - collect_exit (ret); + exit (ret); } if (response_file) diff -Naur gcc-4.8.1.orig/gcc/collect2.h gcc-4.8.1/gcc/collect2.h --- gcc-4.8.1.orig/gcc/collect2.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/collect2.h 2013-06-20 12:12:17.412846000 -0500 @@ -25,8 +25,6 @@ extern struct pex_obj *collect_execute (const char *, char **, const char *, const char *, int flags); -extern void collect_exit (int) ATTRIBUTE_NORETURN; - extern int collect_wait (const char *, struct pex_obj *); extern void dump_ld_file (const char *, FILE *); diff -Naur gcc-4.8.1.orig/gcc/common/config/s390/s390-common.c gcc-4.8.1/gcc/common/config/s390/s390-common.c --- gcc-4.8.1.orig/gcc/common/config/s390/s390-common.c 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/common/config/s390/s390-common.c 2013-08-02 10:41:10.548493000 -0500 @@ -42,7 +42,7 @@ /* z196 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT | PF_EXTIMM | PF_DFP | PF_Z10 | PF_Z196, /* zEC12 */ PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT - | PF_EXTIMM | PF_DFP | PF_Z10 | PF_Z196 | PF_ZEC12 + | PF_EXTIMM | PF_DFP | PF_Z10 | PF_Z196 | PF_ZEC12 | PF_TX }; /* Change optimizations to be performed, depending on the diff -Naur gcc-4.8.1.orig/gcc/config/aarch64/aarch64-builtins.c gcc-4.8.1/gcc/config/aarch64/aarch64-builtins.c --- gcc-4.8.1.orig/gcc/config/aarch64/aarch64-builtins.c 2013-02-28 11:19:33.000000000 -0600 +++ gcc-4.8.1/gcc/config/aarch64/aarch64-builtins.c 2013-07-17 04:06:21.894684000 -0500 @@ -1154,6 +1154,7 @@ return aarch64_simd_expand_args (target, icode, 1, exp, SIMD_ARG_COPY_TO_REG, SIMD_ARG_STOP); + case AARCH64_SIMD_STORE1: case AARCH64_SIMD_STORESTRUCT: return aarch64_simd_expand_args (target, icode, 0, exp, SIMD_ARG_COPY_TO_REG, diff -Naur gcc-4.8.1.orig/gcc/config/aarch64/aarch64.c gcc-4.8.1/gcc/config/aarch64/aarch64.c --- gcc-4.8.1.orig/gcc/config/aarch64/aarch64.c 2013-05-02 12:00:00.000000000 -0500 +++ gcc-4.8.1/gcc/config/aarch64/aarch64.c 2013-06-03 10:33:09.355099000 -0500 @@ -3373,7 +3373,7 @@ output_operand_lossage ("invalid operand for '%%%c'", code); return; } - asm_fprintf (f, "0x%x", UINTVAL (x)); + asm_fprintf (f, "0x%wx", UINTVAL (x)); break; case 'w': diff -Naur gcc-4.8.1.orig/gcc/config/aarch64/aarch64-linux.h gcc-4.8.1/gcc/config/aarch64/aarch64-linux.h --- gcc-4.8.1.orig/gcc/config/aarch64/aarch64-linux.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/aarch64/aarch64-linux.h 2013-08-13 08:22:18.234270000 -0500 @@ -23,6 +23,8 @@ #define GLIBC_DYNAMIC_LINKER "/lib/ld-linux-aarch64.so.1" +#define CPP_SPEC "%{pthread:-D_REENTRANT}" + #define LINUX_TARGET_LINK_SPEC "%{h*} \ %{static:-Bstatic} \ %{shared:-shared} \ diff -Naur gcc-4.8.1.orig/gcc/config/aarch64/aarch64.md gcc-4.8.1/gcc/config/aarch64/aarch64.md --- gcc-4.8.1.orig/gcc/config/aarch64/aarch64.md 2013-04-25 12:00:44.000000000 -0500 +++ gcc-4.8.1/gcc/config/aarch64/aarch64.md 2013-06-07 06:00:38.802083000 -0500 @@ -834,7 +834,8 @@ movi\\t%d0, %1" [(set_attr "v8type" "move,move,move,alu,load1,store1,adr,adr,fmov,fmov,fmov,fmov") (set_attr "mode" "DI") - (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,yes")] + (set_attr "fp" "*,*,*,*,*,*,*,*,yes,yes,yes,*") + (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,yes")] ) (define_insn "insv_imm" diff -Naur gcc-4.8.1.orig/gcc/config/aarch64/aarch64-simd-builtins.def gcc-4.8.1/gcc/config/aarch64/aarch64-simd-builtins.def --- gcc-4.8.1.orig/gcc/config/aarch64/aarch64-simd-builtins.def 2013-02-22 10:39:45.000000000 -0600 +++ gcc-4.8.1/gcc/config/aarch64/aarch64-simd-builtins.def 2013-07-17 04:06:21.894684000 -0500 @@ -256,3 +256,10 @@ BUILTIN_VALL (BINOP, uzp2) BUILTIN_VALL (BINOP, trn1) BUILTIN_VALL (BINOP, trn2) + + /* Implemented by aarch64_ld1. */ + BUILTIN_VALL (LOAD1, ld1) + + /* Implemented by aarch64_st1. */ + BUILTIN_VALL (STORE1, st1) + diff -Naur gcc-4.8.1.orig/gcc/config/aarch64/aarch64-simd.md gcc-4.8.1/gcc/config/aarch64/aarch64-simd.md --- gcc-4.8.1.orig/gcc/config/aarch64/aarch64-simd.md 2013-04-11 09:14:56.000000000 -0500 +++ gcc-4.8.1/gcc/config/aarch64/aarch64-simd.md 2013-07-17 04:06:21.894684000 -0500 @@ -3457,6 +3457,17 @@ DONE; }) +(define_expand "aarch64_ld1" + [(match_operand:VALL 0 "register_operand") + (match_operand:DI 1 "register_operand")] + "TARGET_SIMD" +{ + enum machine_mode mode = mode; + rtx mem = gen_rtx_MEM (mode, operands[1]); + emit_move_insn (operands[0], mem); + DONE; +}) + (define_expand "aarch64_ld" [(match_operand:VSTRUCT 0 "register_operand" "=w") (match_operand:DI 1 "register_operand" "r") @@ -3673,6 +3684,17 @@ DONE; }) +(define_expand "aarch64_st1" + [(match_operand:DI 0 "register_operand") + (match_operand:VALL 1 "register_operand")] + "TARGET_SIMD" +{ + enum machine_mode mode = mode; + rtx mem = gen_rtx_MEM (mode, operands[0]); + emit_move_insn (mem, operands[1]); + DONE; +}) + ;; Expander for builtins to insert vector registers into large ;; opaque integer modes. diff -Naur gcc-4.8.1.orig/gcc/config/aarch64/arm_neon.h gcc-4.8.1/gcc/config/aarch64/arm_neon.h --- gcc-4.8.1.orig/gcc/config/aarch64/arm_neon.h 2013-04-24 10:47:21.000000000 -0500 +++ gcc-4.8.1/gcc/config/aarch64/arm_neon.h 2013-07-17 04:06:21.894684000 -0500 @@ -8518,28 +8518,6 @@ return result; } -__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) -vld1_f32 (const float32_t * a) -{ - float32x2_t result; - __asm__ ("ld1 {%0.2s}, %1" - : "=w"(result) - : "Utv"(({const float32x2_t *_a = (float32x2_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) -vld1_f64 (const float64_t * a) -{ - float64x1_t result; - __asm__ ("ld1 {%0.1d}, %1" - : "=w"(result) - : "Utv"(*a) - : /* No clobbers */); - return result; -} - #define vld1_lane_f32(a, b, c) \ __extension__ \ ({ \ @@ -8696,116 +8674,6 @@ result; \ }) -__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) -vld1_p8 (const poly8_t * a) -{ - poly8x8_t result; - __asm__ ("ld1 {%0.8b}, %1" - : "=w"(result) - : "Utv"(({const poly8x8_t *_a = (poly8x8_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) -vld1_p16 (const poly16_t * a) -{ - poly16x4_t result; - __asm__ ("ld1 {%0.4h}, %1" - : "=w"(result) - : "Utv"(({const poly16x4_t *_a = (poly16x4_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) -vld1_s8 (const int8_t * a) -{ - int8x8_t result; - __asm__ ("ld1 {%0.8b}, %1" - : "=w"(result) - : "Utv"(({const int8x8_t *_a = (int8x8_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) -vld1_s16 (const int16_t * a) -{ - int16x4_t result; - __asm__ ("ld1 {%0.4h}, %1" - : "=w"(result) - : "Utv"(({const int16x4_t *_a = (int16x4_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) -vld1_s32 (const int32_t * a) -{ - int32x2_t result; - __asm__ ("ld1 {%0.2s}, %1" - : "=w"(result) - : "Utv"(({const int32x2_t *_a = (int32x2_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) -vld1_s64 (const int64_t * a) -{ - int64x1_t result; - __asm__ ("ld1 {%0.1d}, %1" - : "=w"(result) - : "Utv"(*a) - : /* No clobbers */); - return result; -} - -__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) -vld1_u8 (const uint8_t * a) -{ - uint8x8_t result; - __asm__ ("ld1 {%0.8b}, %1" - : "=w"(result) - : "Utv"(({const uint8x8_t *_a = (uint8x8_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) -vld1_u16 (const uint16_t * a) -{ - uint16x4_t result; - __asm__ ("ld1 {%0.4h}, %1" - : "=w"(result) - : "Utv"(({const uint16x4_t *_a = (uint16x4_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) -vld1_u32 (const uint32_t * a) -{ - uint32x2_t result; - __asm__ ("ld1 {%0.2s}, %1" - : "=w"(result) - : "Utv"(({const uint32x2_t *_a = (uint32x2_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -vld1_u64 (const uint64_t * a) -{ - uint64x1_t result; - __asm__ ("ld1 {%0.1d}, %1" - : "=w"(result) - : "Utv"(*a) - : /* No clobbers */); - return result; -} - __extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) vld1q_dup_f32 (const float32_t * a) { @@ -8938,28 +8806,6 @@ return result; } -__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) -vld1q_f32 (const float32_t * a) -{ - float32x4_t result; - __asm__ ("ld1 {%0.4s}, %1" - : "=w"(result) - : "Utv"(({const float32x4_t *_a = (float32x4_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) -vld1q_f64 (const float64_t * a) -{ - float64x2_t result; - __asm__ ("ld1 {%0.2d}, %1" - : "=w"(result) - : "Utv"(({const float64x2_t *_a = (float64x2_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - #define vld1q_lane_f32(a, b, c) \ __extension__ \ ({ \ @@ -9116,116 +8962,6 @@ result; \ }) -__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) -vld1q_p8 (const poly8_t * a) -{ - poly8x16_t result; - __asm__ ("ld1 {%0.16b}, %1" - : "=w"(result) - : "Utv"(({const poly8x16_t *_a = (poly8x16_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) -vld1q_p16 (const poly16_t * a) -{ - poly16x8_t result; - __asm__ ("ld1 {%0.16b}, %1" - : "=w"(result) - : "Utv"(({const poly16x8_t *_a = (poly16x8_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) -vld1q_s8 (const int8_t * a) -{ - int8x16_t result; - __asm__ ("ld1 {%0.16b}, %1" - : "=w"(result) - : "Utv"(({const int8x16_t *_a = (int8x16_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) -vld1q_s16 (const int16_t * a) -{ - int16x8_t result; - __asm__ ("ld1 {%0.8h}, %1" - : "=w"(result) - : "Utv"(({const int16x8_t *_a = (int16x8_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) -vld1q_s32 (const int32_t * a) -{ - int32x4_t result; - __asm__ ("ld1 {%0.4s}, %1" - : "=w"(result) - : "Utv"(({const int32x4_t *_a = (int32x4_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) -vld1q_s64 (const int64_t * a) -{ - int64x2_t result; - __asm__ ("ld1 {%0.2d}, %1" - : "=w"(result) - : "Utv"(({const int64x2_t *_a = (int64x2_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) -vld1q_u8 (const uint8_t * a) -{ - uint8x16_t result; - __asm__ ("ld1 {%0.16b}, %1" - : "=w"(result) - : "Utv"(({const uint8x16_t *_a = (uint8x16_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) -vld1q_u16 (const uint16_t * a) -{ - uint16x8_t result; - __asm__ ("ld1 {%0.8h}, %1" - : "=w"(result) - : "Utv"(({const uint16x8_t *_a = (uint16x8_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) -vld1q_u32 (const uint32_t * a) -{ - uint32x4_t result; - __asm__ ("ld1 {%0.4s}, %1" - : "=w"(result) - : "Utv"(({const uint32x4_t *_a = (uint32x4_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - -__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) -vld1q_u64 (const uint64_t * a) -{ - uint64x2_t result; - __asm__ ("ld1 {%0.2d}, %1" - : "=w"(result) - : "Utv"(({const uint64x2_t *_a = (uint64x2_t *) a; *_a;})) - : /* No clobbers */); - return result; -} - __extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) vmaxnm_f32 (float32x2_t a, float32x2_t b) { @@ -16285,24 +16021,6 @@ result; \ }) -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_f32 (float32_t * a, float32x2_t b) -{ - __asm__ ("st1 {%1.2s},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_f64 (float64_t * a, float64x1_t b) -{ - __asm__ ("st1 {%1.1d},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - #define vst1_lane_f32(a, b, c) \ __extension__ \ ({ \ @@ -16435,113 +16153,6 @@ : "memory"); \ }) -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_p8 (poly8_t * a, poly8x8_t b) -{ - __asm__ ("st1 {%1.8b},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_p16 (poly16_t * a, poly16x4_t b) -{ - __asm__ ("st1 {%1.4h},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_s8 (int8_t * a, int8x8_t b) -{ - __asm__ ("st1 {%1.8b},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_s16 (int16_t * a, int16x4_t b) -{ - __asm__ ("st1 {%1.4h},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_s32 (int32_t * a, int32x2_t b) -{ - __asm__ ("st1 {%1.2s},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_s64 (int64_t * a, int64x1_t b) -{ - __asm__ ("st1 {%1.1d},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_u8 (uint8_t * a, uint8x8_t b) -{ - __asm__ ("st1 {%1.8b},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_u16 (uint16_t * a, uint16x4_t b) -{ - __asm__ ("st1 {%1.4h},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_u32 (uint32_t * a, uint32x2_t b) -{ - __asm__ ("st1 {%1.2s},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1_u64 (uint64_t * a, uint64x1_t b) -{ - __asm__ ("st1 {%1.1d},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_f32 (float32_t * a, float32x4_t b) -{ - __asm__ ("st1 {%1.4s},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_f64 (float64_t * a, float64x2_t b) -{ - __asm__ ("st1 {%1.2d},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} #define vst1q_lane_f32(a, b, c) \ __extension__ \ @@ -16675,96 +16286,6 @@ : "memory"); \ }) -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_p8 (poly8_t * a, poly8x16_t b) -{ - __asm__ ("st1 {%1.16b},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_p16 (poly16_t * a, poly16x8_t b) -{ - __asm__ ("st1 {%1.8h},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_s8 (int8_t * a, int8x16_t b) -{ - __asm__ ("st1 {%1.16b},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_s16 (int16_t * a, int16x8_t b) -{ - __asm__ ("st1 {%1.8h},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_s32 (int32_t * a, int32x4_t b) -{ - __asm__ ("st1 {%1.4s},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_s64 (int64_t * a, int64x2_t b) -{ - __asm__ ("st1 {%1.2d},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_u8 (uint8_t * a, uint8x16_t b) -{ - __asm__ ("st1 {%1.16b},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_u16 (uint16_t * a, uint16x8_t b) -{ - __asm__ ("st1 {%1.8h},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_u32 (uint32_t * a, uint32x4_t b) -{ - __asm__ ("st1 {%1.4s},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - -__extension__ static __inline void __attribute__ ((__always_inline__)) -vst1q_u64 (uint64_t * a, uint64x2_t b) -{ - __asm__ ("st1 {%1.2d},[%0]" - : - : "r"(a), "w"(b) - : "memory"); -} - __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) vsubhn_high_s16 (int8x8_t a, int16x8_t b, int16x8_t c) { @@ -20537,6 +20058,165 @@ return (uint64x1_t) __builtin_aarch64_dup_lanedi ((int64x2_t) a, b); } +/* vld1 */ + +__extension__ static __inline float32x2_t __attribute__ ((__always_inline__)) +vld1_f32 (const float32_t *a) +{ + return __builtin_aarch64_ld1v2sf ((const __builtin_aarch64_simd_sf *) a); +} + +__extension__ static __inline float64x1_t __attribute__ ((__always_inline__)) +vld1_f64 (const float64_t *a) +{ + return *a; +} + +__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__)) +vld1_p8 (const poly8_t *a) +{ + return (poly8x8_t) + __builtin_aarch64_ld1v8qi ((const __builtin_aarch64_simd_qi *) a); +} + +__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__)) +vld1_p16 (const poly16_t *a) +{ + return (poly16x4_t) + __builtin_aarch64_ld1v4hi ((const __builtin_aarch64_simd_hi *) a); +} + +__extension__ static __inline int8x8_t __attribute__ ((__always_inline__)) +vld1_s8 (const int8_t *a) +{ + return __builtin_aarch64_ld1v8qi ((const __builtin_aarch64_simd_qi *) a); +} + +__extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) +vld1_s16 (const int16_t *a) +{ + return __builtin_aarch64_ld1v4hi ((const __builtin_aarch64_simd_hi *) a); +} + +__extension__ static __inline int32x2_t __attribute__ ((__always_inline__)) +vld1_s32 (const int32_t *a) +{ + return __builtin_aarch64_ld1v2si ((const __builtin_aarch64_simd_si *) a); +} + +__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) +vld1_s64 (const int64_t *a) +{ + return *a; +} + +__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) +vld1_u8 (const uint8_t *a) +{ + return (uint8x8_t) + __builtin_aarch64_ld1v8qi ((const __builtin_aarch64_simd_qi *) a); +} + +__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__)) +vld1_u16 (const uint16_t *a) +{ + return (uint16x4_t) + __builtin_aarch64_ld1v4hi ((const __builtin_aarch64_simd_hi *) a); +} + +__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__)) +vld1_u32 (const uint32_t *a) +{ + return (uint32x2_t) + __builtin_aarch64_ld1v2si ((const __builtin_aarch64_simd_si *) a); +} + +__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) +vld1_u64 (const uint64_t *a) +{ + return *a; +} + +/* vld1q */ + +__extension__ static __inline float32x4_t __attribute__ ((__always_inline__)) +vld1q_f32 (const float32_t *a) +{ + return __builtin_aarch64_ld1v4sf ((const __builtin_aarch64_simd_sf *) a); +} + +__extension__ static __inline float64x2_t __attribute__ ((__always_inline__)) +vld1q_f64 (const float64_t *a) +{ + return __builtin_aarch64_ld1v2df ((const __builtin_aarch64_simd_df *) a); +} + +__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__)) +vld1q_p8 (const poly8_t *a) +{ + return (poly8x16_t) + __builtin_aarch64_ld1v16qi ((const __builtin_aarch64_simd_qi *) a); +} + +__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) +vld1q_p16 (const poly16_t *a) +{ + return (poly16x8_t) + __builtin_aarch64_ld1v8hi ((const __builtin_aarch64_simd_hi *) a); +} + +__extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) +vld1q_s8 (const int8_t *a) +{ + return __builtin_aarch64_ld1v16qi ((const __builtin_aarch64_simd_qi *) a); +} + +__extension__ static __inline int16x8_t __attribute__ ((__always_inline__)) +vld1q_s16 (const int16_t *a) +{ + return __builtin_aarch64_ld1v8hi ((const __builtin_aarch64_simd_hi *) a); +} + +__extension__ static __inline int32x4_t __attribute__ ((__always_inline__)) +vld1q_s32 (const int32_t *a) +{ + return __builtin_aarch64_ld1v4si ((const __builtin_aarch64_simd_si *) a); +} + +__extension__ static __inline int64x2_t __attribute__ ((__always_inline__)) +vld1q_s64 (const int64_t *a) +{ + return __builtin_aarch64_ld1v2di ((const __builtin_aarch64_simd_di *) a); +} + +__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__)) +vld1q_u8 (const uint8_t *a) +{ + return (uint8x16_t) + __builtin_aarch64_ld1v16qi ((const __builtin_aarch64_simd_qi *) a); +} + +__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__)) +vld1q_u16 (const uint16_t *a) +{ + return (uint16x8_t) + __builtin_aarch64_ld1v8hi ((const __builtin_aarch64_simd_hi *) a); +} + +__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__)) +vld1q_u32 (const uint32_t *a) +{ + return (uint32x4_t) + __builtin_aarch64_ld1v4si ((const __builtin_aarch64_simd_si *) a); +} + +__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__)) +vld1q_u64 (const uint64_t *a) +{ + return (uint64x2_t) + __builtin_aarch64_ld1v2di ((const __builtin_aarch64_simd_di *) a); +} + /* vldn */ __extension__ static __inline int64x1x2_t __attribute__ ((__always_inline__)) @@ -24307,6 +23987,165 @@ return (uint64x1_t) __builtin_aarch64_usri_ndi (__a, __b, __c); } +/* vst1 */ + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_f32 (float32_t *a, float32x2_t b) +{ + __builtin_aarch64_st1v2sf ((__builtin_aarch64_simd_sf *) a, b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_f64 (float64_t *a, float64x1_t b) +{ + *a = b; +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_p8 (poly8_t *a, poly8x8_t b) +{ + __builtin_aarch64_st1v8qi ((__builtin_aarch64_simd_qi *) a, + (int8x8_t) b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_p16 (poly16_t *a, poly16x4_t b) +{ + __builtin_aarch64_st1v4hi ((__builtin_aarch64_simd_hi *) a, + (int16x4_t) b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_s8 (int8_t *a, int8x8_t b) +{ + __builtin_aarch64_st1v8qi ((__builtin_aarch64_simd_qi *) a, b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_s16 (int16_t *a, int16x4_t b) +{ + __builtin_aarch64_st1v4hi ((__builtin_aarch64_simd_hi *) a, b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_s32 (int32_t *a, int32x2_t b) +{ + __builtin_aarch64_st1v2si ((__builtin_aarch64_simd_si *) a, b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_s64 (int64_t *a, int64x1_t b) +{ + *a = b; +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_u8 (uint8_t *a, uint8x8_t b) +{ + __builtin_aarch64_st1v8qi ((__builtin_aarch64_simd_qi *) a, + (int8x8_t) b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_u16 (uint16_t *a, uint16x4_t b) +{ + __builtin_aarch64_st1v4hi ((__builtin_aarch64_simd_hi *) a, + (int16x4_t) b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_u32 (uint32_t *a, uint32x2_t b) +{ + __builtin_aarch64_st1v2si ((__builtin_aarch64_simd_si *) a, + (int32x2_t) b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1_u64 (uint64_t *a, uint64x1_t b) +{ + *a = b; +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_f32 (float32_t *a, float32x4_t b) +{ + __builtin_aarch64_st1v4sf ((__builtin_aarch64_simd_sf *) a, b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_f64 (float64_t *a, float64x2_t b) +{ + __builtin_aarch64_st1v2df ((__builtin_aarch64_simd_df *) a, b); +} + +/* vst1q */ + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_p8 (poly8_t *a, poly8x16_t b) +{ + __builtin_aarch64_st1v16qi ((__builtin_aarch64_simd_qi *) a, + (int8x16_t) b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_p16 (poly16_t *a, poly16x8_t b) +{ + __builtin_aarch64_st1v8hi ((__builtin_aarch64_simd_hi *) a, + (int16x8_t) b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_s8 (int8_t *a, int8x16_t b) +{ + __builtin_aarch64_st1v16qi ((__builtin_aarch64_simd_qi *) a, b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_s16 (int16_t *a, int16x8_t b) +{ + __builtin_aarch64_st1v8hi ((__builtin_aarch64_simd_hi *) a, b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_s32 (int32_t *a, int32x4_t b) +{ + __builtin_aarch64_st1v4si ((__builtin_aarch64_simd_si *) a, b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_s64 (int64_t *a, int64x2_t b) +{ + __builtin_aarch64_st1v2di ((__builtin_aarch64_simd_di *) a, b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_u8 (uint8_t *a, uint8x16_t b) +{ + __builtin_aarch64_st1v16qi ((__builtin_aarch64_simd_qi *) a, + (int8x16_t) b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_u16 (uint16_t *a, uint16x8_t b) +{ + __builtin_aarch64_st1v8hi ((__builtin_aarch64_simd_hi *) a, + (int16x8_t) b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_u32 (uint32_t *a, uint32x4_t b) +{ + __builtin_aarch64_st1v4si ((__builtin_aarch64_simd_si *) a, + (int32x4_t) b); +} + +__extension__ static __inline void __attribute__ ((__always_inline__)) +vst1q_u64 (uint64_t *a, uint64x2_t b) +{ + __builtin_aarch64_st1v2di ((__builtin_aarch64_simd_di *) a, + (int64x2_t) b); +} + /* vstn */ __extension__ static __inline void diff -Naur gcc-4.8.1.orig/gcc/config/alpha/alpha.c gcc-4.8.1/gcc/config/alpha/alpha.c --- gcc-4.8.1.orig/gcc/config/alpha/alpha.c 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/alpha/alpha.c 2013-06-10 13:36:16.739030000 -0500 @@ -2700,12 +2700,12 @@ break; case GE: case GT: case GEU: case GTU: - /* These must be swapped. */ - if (op1 != CONST0_RTX (cmp_mode)) - { - code = swap_condition (code); - tem = op0, op0 = op1, op1 = tem; - } + /* These normally need swapping, but for integer zero we have + special patterns that recognize swapped operands. */ + if (cmp_mode == DImode && op1 == const0_rtx) + break; + code = swap_condition (code); + tem = op0, op0 = op1, op1 = tem; break; default: @@ -3067,12 +3067,9 @@ operands[1] = op1; out = gen_reg_rtx (DImode); - /* What's actually returned is -1,0,1, not a proper boolean value, - so use an EXPR_LIST as with a generic libcall instead of a - comparison type expression. */ - note = gen_rtx_EXPR_LIST (VOIDmode, op1, NULL_RTX); - note = gen_rtx_EXPR_LIST (VOIDmode, op0, note); - note = gen_rtx_EXPR_LIST (VOIDmode, func, note); + /* What's actually returned is -1,0,1, not a proper boolean value. */ + note = gen_rtx_fmt_ee (cmp_code, VOIDmode, op0, op1); + note = gen_rtx_UNSPEC (DImode, gen_rtvec (1, note), UNSPEC_XFLT_COMPARE); alpha_emit_xfloating_libcall (func, out, operands, 2, note); return out; diff -Naur gcc-4.8.1.orig/gcc/config/alpha/alpha.md gcc-4.8.1/gcc/config/alpha/alpha.md --- gcc-4.8.1.orig/gcc/config/alpha/alpha.md 2013-02-01 10:34:28.000000000 -0600 +++ gcc-4.8.1/gcc/config/alpha/alpha.md 2013-06-07 01:26:42.097053000 -0500 @@ -23,6 +23,7 @@ ;; Uses of UNSPEC in this file: (define_c_enum "unspec" [ + UNSPEC_XFLT_COMPARE UNSPEC_ARG_HOME UNSPEC_LDGP1 UNSPEC_INSXH diff -Naur gcc-4.8.1.orig/gcc/config/arm/arm.c gcc-4.8.1/gcc/config/arm/arm.c --- gcc-4.8.1.orig/gcc/config/arm/arm.c 2013-05-24 10:15:44.000000000 -0500 +++ gcc-4.8.1/gcc/config/arm/arm.c 2013-08-21 10:57:02.753791000 -0500 @@ -4459,7 +4459,9 @@ if (((pcum->aapcs_vfp_regs_free >> regno) & mask) == mask) { pcum->aapcs_vfp_reg_alloc = mask << regno; - if (mode == BLKmode || (mode == TImode && !TARGET_NEON)) + if (mode == BLKmode + || (mode == TImode && ! TARGET_NEON) + || ! arm_hard_regno_mode_ok (FIRST_VFP_REGNUM + regno, mode)) { int i; int rcount = pcum->aapcs_vfp_rcount; @@ -7094,7 +7096,7 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer) { enum machine_mode mode = GET_MODE (x); - int total; + int total, words; switch (code) { @@ -7102,6 +7104,8 @@ case ASHIFTRT: case LSHIFTRT: case ROTATERT: + return (mode == SImode) ? COSTS_N_INSNS (1) : COSTS_N_INSNS (2); + case PLUS: case MINUS: case COMPARE: @@ -7125,7 +7129,10 @@ return COSTS_N_INSNS (1) + 16; case SET: - return (COSTS_N_INSNS (1) + /* A SET doesn't have a mode, so let's look at the SET_DEST to get + the mode. */ + words = ARM_NUM_INTS (GET_MODE_SIZE (GET_MODE (SET_DEST (x)))); + return (COSTS_N_INSNS (words) + 4 * ((MEM_P (SET_SRC (x))) + MEM_P (SET_DEST (x)))); @@ -7822,6 +7829,7 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer) { enum machine_mode mode = GET_MODE (x); + int words; switch (code) { @@ -7829,8 +7837,19 @@ case ASHIFTRT: case LSHIFTRT: case ROTATERT: + return (mode == SImode) ? COSTS_N_INSNS (1) : COSTS_N_INSNS (2); + case PLUS: case MINUS: + /* Thumb-1 needs two instructions to fulfill shiftadd/shiftsub0/shiftsub1 + defined by RTL expansion, especially for the expansion of + multiplication. */ + if ((GET_CODE (XEXP (x, 0)) == MULT + && power_of_two_operand (XEXP (XEXP (x,0),1), SImode)) + || (GET_CODE (XEXP (x, 1)) == MULT + && power_of_two_operand (XEXP (XEXP (x, 1), 1), SImode))) + return COSTS_N_INSNS (2); + /* On purpose fall through for normal RTX. */ case COMPARE: case NEG: case NOT: @@ -7847,7 +7866,10 @@ return COSTS_N_INSNS (1); case SET: - return (COSTS_N_INSNS (1) + /* A SET doesn't have a mode, so let's look at the SET_DEST to get + the mode. */ + words = ARM_NUM_INTS (GET_MODE_SIZE (GET_MODE (SET_DEST (x)))); + return (COSTS_N_INSNS (words) + 4 * ((MEM_P (SET_SRC (x))) + MEM_P (SET_DEST (x)))); diff -Naur gcc-4.8.1.orig/gcc/config/arm/neon.md gcc-4.8.1/gcc/config/arm/neon.md --- gcc-4.8.1.orig/gcc/config/arm/neon.md 2013-04-04 09:34:01.000000000 -0500 +++ gcc-4.8.1/gcc/config/arm/neon.md 2013-08-09 01:59:01.329587000 -0500 @@ -244,7 +244,7 @@ [(set (match_operand:VDQX 0 "neon_struct_or_register_operand") (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_or_register_operand")] UNSPEC_MISALIGNED_ACCESS))] - "TARGET_NEON && !BYTES_BIG_ENDIAN" + "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access" { /* This pattern is not permitted to fail during expansion: if both arguments are non-registers (e.g. memory := constant, which can be created by the @@ -258,7 +258,7 @@ [(set (match_operand:VDX 0 "neon_struct_operand" "=Um") (unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")] UNSPEC_MISALIGNED_ACCESS))] - "TARGET_NEON && !BYTES_BIG_ENDIAN" + "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access" "vst1.\t{%P1}, %A0" [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]) @@ -266,7 +266,7 @@ [(set (match_operand:VDX 0 "s_register_operand" "=w") (unspec:VDX [(match_operand:VDX 1 "neon_struct_operand" " Um")] UNSPEC_MISALIGNED_ACCESS))] - "TARGET_NEON && !BYTES_BIG_ENDIAN" + "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access" "vld1.\t{%P0}, %A1" [(set_attr "neon_type" "neon_vld1_1_2_regs")]) @@ -274,7 +274,7 @@ [(set (match_operand:VQX 0 "neon_struct_operand" "=Um") (unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")] UNSPEC_MISALIGNED_ACCESS))] - "TARGET_NEON && !BYTES_BIG_ENDIAN" + "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access" "vst1.\t{%q1}, %A0" [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]) @@ -282,7 +282,7 @@ [(set (match_operand:VQX 0 "s_register_operand" "=w") (unspec:VQX [(match_operand:VQX 1 "neon_struct_operand" " Um")] UNSPEC_MISALIGNED_ACCESS))] - "TARGET_NEON && !BYTES_BIG_ENDIAN" + "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access" "vld1.\t{%q0}, %A1" [(set_attr "neon_type" "neon_vld1_1_2_regs")]) @@ -1732,6 +1732,7 @@ ? 3 : 1; rtx magic_rtx = GEN_INT (magic_word); int inverse = 0; + int use_zero_form = 0; int swap_bsl_operands = 0; rtx mask = gen_reg_rtx (mode); rtx tmp = gen_reg_rtx (mode); @@ -1742,12 +1743,16 @@ switch (GET_CODE (operands[3])) { case GE: + case GT: case LE: + case LT: case EQ: - if (!REG_P (operands[5]) - && (operands[5] != CONST0_RTX (mode))) - operands[5] = force_reg (mode, operands[5]); - break; + if (operands[5] == CONST0_RTX (mode)) + { + use_zero_form = 1; + break; + } + /* Fall through. */ default: if (!REG_P (operands[5])) operands[5] = force_reg (mode, operands[5]); @@ -1798,7 +1803,26 @@ a GT b -> a GT b a LE b -> b GE a a LT b -> b GT a - a EQ b -> a EQ b */ + a EQ b -> a EQ b + Note that there also exist direct comparison against 0 forms, + so catch those as a special case. */ + if (use_zero_form) + { + inverse = 0; + switch (GET_CODE (operands[3])) + { + case LT: + base_comparison = gen_neon_vclt; + break; + case LE: + base_comparison = gen_neon_vcle; + break; + default: + /* Do nothing, other zero form cases already have the correct + base_comparison. */ + break; + } + } if (!inverse) emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx)); diff -Naur gcc-4.8.1.orig/gcc/config/avr/avr.c gcc-4.8.1/gcc/config/avr/avr.c --- gcc-4.8.1.orig/gcc/config/avr/avr.c 2013-03-12 06:42:26.000000000 -0500 +++ gcc-4.8.1/gcc/config/avr/avr.c 2013-07-19 06:15:26.382992000 -0500 @@ -584,7 +584,12 @@ { tree args = TYPE_ARG_TYPES (TREE_TYPE (decl)); tree ret = TREE_TYPE (TREE_TYPE (decl)); - const char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); + const char *name; + + name = DECL_ASSEMBLER_NAME_SET_P (decl) + /* Remove the leading '*' added in set_user_assembler_name. */ + ? 1 + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)) + : IDENTIFIER_POINTER (DECL_NAME (decl)); /* Silently ignore 'signal' if 'interrupt' is present. AVR-LibC startet using this when it switched from SIGNAL and INTERRUPT to ISR. */ @@ -1112,7 +1117,7 @@ leaf function and thus X has already been saved. */ int irq_state = -1; - HOST_WIDE_INT size_cfa = size; + HOST_WIDE_INT size_cfa = size, neg_size; rtx fp_plus_insns, fp, my_fp; gcc_assert (frame_pointer_needed @@ -1151,6 +1156,7 @@ } size = trunc_int_for_mode (size, GET_MODE (my_fp)); + neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp)); /************ Method 1: Adjust frame pointer ************/ @@ -1171,7 +1177,8 @@ } insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), - my_fp, -size)); + my_fp, neg_size)); + if (frame_pointer_needed) { RTX_FRAME_RELATED_P (insn) = 1; @@ -6225,11 +6232,14 @@ the subtrahend in the original insn, provided it is a compile time constant. In all other cases, SIGN is 0. - Return "". */ + If OUT_LABEL is true, print the final 0: label which is needed for + saturated addition / subtraction. The only case where OUT_LABEL = false + is useful is for saturated addition / subtraction performed during + fixed-point rounding, cf. `avr_out_round'. */ static void avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc, - enum rtx_code code_sat = UNKNOWN, int sign = 0) + enum rtx_code code_sat, int sign, bool out_label) { /* MODE of the operation. */ enum machine_mode mode = GET_MODE (xop[0]); @@ -6668,7 +6678,8 @@ "mov %r0+5,%0", xop, plen, 4); } - avr_asm_len ("0:", op, plen, 0); + if (out_label) + avr_asm_len ("0:", op, plen, 0); } @@ -6706,8 +6717,8 @@ /* Prepare operands of addition/subtraction to be used with avr_out_plus_1. - INSN is a single_set insn with a binary operation as SET_SRC that is - one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS. + INSN is a single_set insn or an insn pattern with a binary operation as + SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS. XOP are the operands of INSN. In the case of 64-bit operations with constant XOP[] has just one element: The summand/subtrahend in XOP[0]. @@ -6722,19 +6733,22 @@ PLEN and PCC default to NULL. + OUT_LABEL defaults to TRUE. For a description, see AVR_OUT_PLUS_1. + Return "" */ const char* -avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc) +avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc, bool out_label) { int cc_plus, cc_minus, cc_dummy; int len_plus, len_minus; rtx op[4]; - rtx xdest = SET_DEST (single_set (insn)); + rtx xpattern = INSN_P (insn) ? single_set (insn) : insn; + rtx xdest = SET_DEST (xpattern); enum machine_mode mode = GET_MODE (xdest); enum machine_mode imode = int_mode_for_mode (mode); int n_bytes = GET_MODE_SIZE (mode); - enum rtx_code code_sat = GET_CODE (SET_SRC (single_set (insn))); + enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern)); enum rtx_code code = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat ? PLUS : MINUS); @@ -6749,7 +6763,7 @@ if (n_bytes <= 4 && REG_P (xop[2])) { - avr_out_plus_1 (xop, plen, code, pcc, code_sat); + avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label); return ""; } @@ -6776,7 +6790,8 @@ /* Saturations and 64-bit operations don't have a clobber operand. For the other cases, the caller will provide a proper XOP[3]. */ - op[3] = PARALLEL == GET_CODE (PATTERN (insn)) ? xop[3] : NULL_RTX; + xpattern = INSN_P (insn) ? PATTERN (insn) : insn; + op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX; /* Saturation will need the sign of the original operand. */ @@ -6791,8 +6806,8 @@ /* Work out the shortest sequence. */ - avr_out_plus_1 (op, &len_minus, MINUS, &cc_plus, code_sat, sign); - avr_out_plus_1 (op, &len_plus, PLUS, &cc_minus, code_sat, sign); + avr_out_plus_1 (op, &len_minus, MINUS, &cc_plus, code_sat, sign, out_label); + avr_out_plus_1 (op, &len_plus, PLUS, &cc_minus, code_sat, sign, out_label); if (plen) { @@ -6800,9 +6815,9 @@ *pcc = (len_minus <= len_plus) ? cc_minus : cc_plus; } else if (len_minus <= len_plus) - avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign); + avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign, out_label); else - avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign); + avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign, out_label); return ""; } @@ -6816,13 +6831,15 @@ and return "". If PLEN == NULL, print assembler instructions to perform the operation; otherwise, set *PLEN to the length of the instruction sequence (in words) printed with PLEN == NULL. XOP[3] is either an 8-bit clobber - register or SCRATCH if no clobber register is needed for the operation. */ + register or SCRATCH if no clobber register is needed for the operation. + INSN is an INSN_P or a pattern of an insn. */ const char* avr_out_bitop (rtx insn, rtx *xop, int *plen) { /* CODE and MODE of the operation. */ - enum rtx_code code = GET_CODE (SET_SRC (single_set (insn))); + rtx xpattern = INSN_P (insn) ? single_set (insn) : insn; + enum rtx_code code = GET_CODE (SET_SRC (xpattern)); enum machine_mode mode = GET_MODE (xop[0]); /* Number of bytes to operate on. */ @@ -7325,6 +7342,67 @@ } +/* Output fixed-point rounding. XOP[0] = XOP[1] is the operand to round. + XOP[2] is the rounding point, a CONST_INT. The function prints the + instruction sequence if PLEN = NULL and computes the length in words + of the sequence if PLEN != NULL. Most of this function deals with + preparing operands for calls to `avr_out_plus' and `avr_out_bitop'. */ + +const char* +avr_out_round (rtx insn ATTRIBUTE_UNUSED, rtx *xop, int *plen) +{ + enum machine_mode mode = GET_MODE (xop[0]); + enum machine_mode imode = int_mode_for_mode (mode); + // The smallest fractional bit not cleared by the rounding is 2^(-RP). + int fbit = (int) GET_MODE_FBIT (mode); + double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2])); + // Lengths of PLUS and AND parts. + int len_add = 0, *plen_add = plen ? &len_add : NULL; + int len_and = 0, *plen_and = plen ? &len_and : NULL; + + // Add-Saturate 1/2 * 2^(-RP). Don't print the label "0:" when printing + // the saturated addition so that we can emit the "rjmp 1f" before the + // "0:" below. + + rtx xadd = const_fixed_from_double_int (i_add, mode); + rtx xpattern, xsrc, op[4]; + + xsrc = SIGNED_FIXED_POINT_MODE_P (mode) + ? gen_rtx_SS_PLUS (mode, xop[1], xadd) + : gen_rtx_US_PLUS (mode, xop[1], xadd); + xpattern = gen_rtx_SET (VOIDmode, xop[0], xsrc); + + op[0] = xop[0]; + op[1] = xop[1]; + op[2] = xadd; + avr_out_plus (xpattern, op, plen_add, NULL, false /* Don't print "0:" */); + + avr_asm_len ("rjmp 1f" CR_TAB + "0:", NULL, plen_add, 1); + + // Keep all bits from RP and higher: ... 2^(-RP) + // Clear all bits from RP+1 and lower: 2^(-RP-1) ... + // Rounding point ^^^^^^^ + // Added above ^^^^^^^^^ + rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0); + rtx xmask = immed_double_int_const (-i_add - i_add, imode); + + xpattern = gen_rtx_SET (VOIDmode, xreg, gen_rtx_AND (imode, xreg, xmask)); + + op[0] = xreg; + op[1] = xreg; + op[2] = xmask; + op[3] = gen_rtx_SCRATCH (QImode); + avr_out_bitop (xpattern, op, plen_and); + avr_asm_len ("1:", NULL, plen, 0); + + if (plen) + *plen = len_add + len_and; + + return ""; +} + + /* Create RTL split patterns for byte sized rotate expressions. This produces a series of move instructions and considers overlap situations. Overlapping non-HImode operands need a scratch register. */ @@ -7533,6 +7611,7 @@ case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break; case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break; + case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break; case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break; case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break; diff -Naur gcc-4.8.1.orig/gcc/config/avr/avr-fixed.md gcc-4.8.1/gcc/config/avr/avr-fixed.md --- gcc-4.8.1.orig/gcc/config/avr/avr-fixed.md 2013-02-08 04:13:37.000000000 -0600 +++ gcc-4.8.1/gcc/config/avr/avr-fixed.md 2013-07-19 06:15:26.382992000 -0500 @@ -447,49 +447,18 @@ ;; "roundqq3_const" "rounduqq3_const" ;; "roundhq3_const" "rounduhq3_const" "roundha3_const" "rounduha3_const" ;; "roundsq3_const" "roundusq3_const" "roundsa3_const" "roundusa3_const" -(define_expand "round3_const" - [(parallel [(match_operand:ALL124QA 0 "register_operand" "") - (match_operand:ALL124QA 1 "register_operand" "") - (match_operand:HI 2 "const_int_operand" "")])] +(define_insn "round3_const" + [(set (match_operand:ALL124QA 0 "register_operand" "=d") + (unspec:ALL124QA [(match_operand:ALL124QA 1 "register_operand" "0") + (match_operand:HI 2 "const_int_operand" "n") + (const_int 0)] + UNSPEC_ROUND))] "" { - // The rounding point RP is $2. The smallest fractional - // bit that is not cleared by the rounding is 2^(-RP). - - enum machine_mode imode = int_mode_for_mode (mode); - int fbit = (int) GET_MODE_FBIT (mode); - - // Add-Saturate 1/2 * 2^(-RP) - - double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (operands[2])); - rtx x_add = const_fixed_from_double_int (i_add, mode); - - if (SIGNED_FIXED_POINT_MODE_P (mode)) - emit_move_insn (operands[0], - gen_rtx_SS_PLUS (mode, operands[1], x_add)); - else - emit_move_insn (operands[0], - gen_rtx_US_PLUS (mode, operands[1], x_add)); - - // Keep all bits from RP and higher: ... 2^(-RP) - // Clear all bits from RP+1 and lower: 2^(-RP-1) ... - // Rounding point ^^^^^^^ - // Added above ^^^^^^^^^ - - rtx xreg = simplify_gen_subreg (imode, operands[0], mode, 0); - rtx xmask = immed_double_int_const (-i_add - i_add, imode); - - if (SImode == imode) - emit_insn (gen_andsi3 (xreg, xreg, xmask)); - else if (HImode == imode) - emit_insn (gen_andhi3 (xreg, xreg, xmask)); - else if (QImode == imode) - emit_insn (gen_andqi3 (xreg, xreg, xmask)); - else - gcc_unreachable(); - - DONE; - }) + return avr_out_round (insn, operands); + } + [(set_attr "cc" "clobber") + (set_attr "adjust_len" "round")]) ;; "*roundqq3.libgcc" "*rounduqq3.libgcc" diff -Naur gcc-4.8.1.orig/gcc/config/avr/avr-mcus.def gcc-4.8.1/gcc/config/avr/avr-mcus.def --- gcc-4.8.1.orig/gcc/config/avr/avr-mcus.def 2013-02-28 03:03:09.000000000 -0600 +++ gcc-4.8.1/gcc/config/avr/avr-mcus.def 2013-07-10 07:36:36.732157000 -0500 @@ -168,7 +168,6 @@ AVR_MCU ("atmega169a", ARCH_AVR5, "__AVR_ATmega169A__", 0, 0, 0x0100, 1, "m169a") AVR_MCU ("atmega169p", ARCH_AVR5, "__AVR_ATmega169P__", 0, 0, 0x0100, 1, "m169p") AVR_MCU ("atmega169pa", ARCH_AVR5, "__AVR_ATmega169PA__", 0, 0, 0x0100, 1, "m169pa") -AVR_MCU ("atmega16hva", ARCH_AVR5, "__AVR_ATmega16HVA__", 0, 0, 0x0100, 1, "m16hva") AVR_MCU ("atmega16hvb", ARCH_AVR5, "__AVR_ATmega16HVB__", 0, 0, 0x0100, 1, "m16hvb") AVR_MCU ("atmega16hvbrevb", ARCH_AVR5, "__AVR_ATmega16HVBREVB__", 0, 0, 0x0100, 1, "m16hvbrevb") AVR_MCU ("atmega16m1", ARCH_AVR5, "__AVR_ATmega16M1__", 0, 0, 0x0100, 1, "m16m1") @@ -176,7 +175,6 @@ AVR_MCU ("atmega26hvg", ARCH_AVR5, "__AVR_ATmega26HVG__", 0, 0, 0x0100, 1, "m26hvg") AVR_MCU ("atmega32a", ARCH_AVR5, "__AVR_ATmega32A__", 0, 0, 0x0060, 1, "m32a") AVR_MCU ("atmega32", ARCH_AVR5, "__AVR_ATmega32__", 0, 0, 0x0060, 1, "m32") -AVR_MCU ("atmega32a", ARCH_AVR5, "__AVR_ATmega32A__", 0, 0, 0x0060, 1, "m32a") AVR_MCU ("atmega323", ARCH_AVR5, "__AVR_ATmega323__", 0, 0, 0x0060, 1, "m323") AVR_MCU ("atmega324a", ARCH_AVR5, "__AVR_ATmega324A__", 0, 0, 0x0100, 1, "m324a") AVR_MCU ("atmega324p", ARCH_AVR5, "__AVR_ATmega324P__", 0, 0, 0x0100, 1, "m324p") @@ -222,7 +220,6 @@ AVR_MCU ("atmega6490", ARCH_AVR5, "__AVR_ATmega6490__", 0, 0, 0x0100, 1, "m6490") AVR_MCU ("atmega16hva", ARCH_AVR5, "__AVR_ATmega16HVA__", 0, 0, 0x0100, 1, "m16hva") AVR_MCU ("atmega16hva2", ARCH_AVR5, "__AVR_ATmega16HVA2__", 0, 0, 0x0100, 1, "m16hva2") -AVR_MCU ("atmega16hvb", ARCH_AVR5, "__AVR_ATmega16HVB__", 0, 0, 0x0100, 1, "m16hvb") AVR_MCU ("atmega32hvb", ARCH_AVR5, "__AVR_ATmega32HVB__", 0, 0, 0x0100, 1, "m32hvb") AVR_MCU ("atmega6490a", ARCH_AVR5, "__AVR_ATmega6490A__", 0, 0, 0x0100, 1, "m6490a") AVR_MCU ("atmega6490p", ARCH_AVR5, "__AVR_ATmega6490P__", 0, 0, 0x0100, 1, "m6490p") @@ -231,23 +228,13 @@ AVR_MCU ("atmega64hve", ARCH_AVR5, "__AVR_ATmega64HVE__", 0, 0, 0x0100, 1, "m64hve") AVR_MCU ("atmega64rfa2", ARCH_AVR5, "__AVR_ATmega64RFA2__", 0, 0, 0x0200, 1, "m64rfa2") AVR_MCU ("atmega64rfr2", ARCH_AVR5, "__AVR_ATmega64RFR2__", 0, 0, 0x0200, 1, "m64rfr2") -AVR_MCU ("atmega32hvb", ARCH_AVR5, "__AVR_ATmega32HVB__", 0, 0, 0x0100, 1, "m32hvb") AVR_MCU ("atmega32hvbrevb", ARCH_AVR5, "__AVR_ATmega32HVBREVB__", 0, 0, 0x0100, 1, "m32hvbrevb") -AVR_MCU ("atmega16hva2", ARCH_AVR5, "__AVR_ATmega16HVA2__", 0, 0, 0x0100, 1, "m16hva2") AVR_MCU ("atmega48hvf", ARCH_AVR5, "__AVR_ATmega48HVF__", 0, 0, 0x0100, 1, "m48hvf") AVR_MCU ("at90can32", ARCH_AVR5, "__AVR_AT90CAN32__", 0, 0, 0x0100, 1, "can32") AVR_MCU ("at90can64", ARCH_AVR5, "__AVR_AT90CAN64__", 0, 0, 0x0100, 1, "can64") AVR_MCU ("at90pwm161", ARCH_AVR5, "__AVR_AT90PWM161__", 0, 0, 0x0100, 1, "90pwm161") AVR_MCU ("at90pwm216", ARCH_AVR5, "__AVR_AT90PWM216__", 0, 0, 0x0100, 1, "90pwm216") AVR_MCU ("at90pwm316", ARCH_AVR5, "__AVR_AT90PWM316__", 0, 0, 0x0100, 1, "90pwm316") -AVR_MCU ("atmega32c1", ARCH_AVR5, "__AVR_ATmega32C1__", 0, 0, 0x0100, 1, "m32c1") -AVR_MCU ("atmega64c1", ARCH_AVR5, "__AVR_ATmega64C1__", 0, 0, 0x0100, 1, "m64c1") -AVR_MCU ("atmega16m1", ARCH_AVR5, "__AVR_ATmega16M1__", 0, 0, 0x0100, 1, "m16m1") -AVR_MCU ("atmega32m1", ARCH_AVR5, "__AVR_ATmega32M1__", 0, 0, 0x0100, 1, "m32m1") -AVR_MCU ("atmega64m1", ARCH_AVR5, "__AVR_ATmega64M1__", 0, 0, 0x0100, 1, "m64m1") -AVR_MCU ("atmega16u4", ARCH_AVR5, "__AVR_ATmega16U4__", 0, 0, 0x0100, 1, "m16u4") -AVR_MCU ("atmega32u4", ARCH_AVR5, "__AVR_ATmega32U4__", 0, 0, 0x0100, 1, "m32u4") -AVR_MCU ("atmega32u6", ARCH_AVR5, "__AVR_ATmega32U6__", 0, 0, 0x0100, 1, "m32u6") AVR_MCU ("at90scr100", ARCH_AVR5, "__AVR_AT90SCR100__", 0, 0, 0x0100, 1, "90scr100") AVR_MCU ("at90usb646", ARCH_AVR5, "__AVR_AT90USB646__", 0, 0, 0x0100, 1, "usb646") AVR_MCU ("at90usb647", ARCH_AVR5, "__AVR_AT90USB647__", 0, 0, 0x0100, 1, "usb647") diff -Naur gcc-4.8.1.orig/gcc/config/avr/avr.md gcc-4.8.1/gcc/config/avr/avr.md --- gcc-4.8.1.orig/gcc/config/avr/avr.md 2013-02-08 04:13:37.000000000 -0600 +++ gcc-4.8.1/gcc/config/avr/avr.md 2013-07-19 06:15:26.382992000 -0500 @@ -140,7 +140,7 @@ "out_bitop, plus, addto_sp, tsthi, tstpsi, tstsi, compare, compare64, call, mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32, - ufract, sfract, + ufract, sfract, round, xload, lpm, movmem, ashlqi, ashrqi, lshrqi, ashlhi, ashrhi, lshrhi, diff -Naur gcc-4.8.1.orig/gcc/config/avr/avr.opt gcc-4.8.1/gcc/config/avr/avr.opt --- gcc-4.8.1.orig/gcc/config/avr/avr.opt 2013-03-12 06:42:26.000000000 -0500 +++ gcc-4.8.1/gcc/config/avr/avr.opt 2013-07-10 06:20:18.855155000 -0500 @@ -77,4 +77,4 @@ Waddr-space-convert Warning C Report Var(avr_warn_addr_space_convert) Init(0) -Warn if the address space of an address is change. +Warn if the address space of an address is changed. diff -Naur gcc-4.8.1.orig/gcc/config/avr/avr-protos.h gcc-4.8.1/gcc/config/avr/avr-protos.h --- gcc-4.8.1.orig/gcc/config/avr/avr-protos.h 2013-01-14 09:08:45.000000000 -0600 +++ gcc-4.8.1/gcc/config/avr/avr-protos.h 2013-07-19 06:15:26.382992000 -0500 @@ -86,7 +86,8 @@ extern void avr_output_addr_vec_elt (FILE *stream, int value); extern const char *avr_out_sbxx_branch (rtx insn, rtx operands[]); extern const char* avr_out_bitop (rtx, rtx*, int*); -extern const char* avr_out_plus (rtx, rtx*, int* =NULL, int* =NULL); +extern const char* avr_out_plus (rtx, rtx*, int* =NULL, int* =NULL, bool =true); +extern const char* avr_out_round (rtx, rtx*, int* =NULL); extern const char* avr_out_addto_sp (rtx*, int*); extern const char* avr_out_xload (rtx, rtx*, int*); extern const char* avr_out_movmem (rtx, rtx*, int*); diff -Naur gcc-4.8.1.orig/gcc/config/avr/avr-tables.opt gcc-4.8.1/gcc/config/avr/avr-tables.opt --- gcc-4.8.1.orig/gcc/config/avr/avr-tables.opt 2013-02-28 03:03:09.000000000 -0600 +++ gcc-4.8.1/gcc/config/avr/avr-tables.opt 2013-07-10 07:36:36.732157000 -0500 @@ -330,479 +330,440 @@ Enum(avr_mcu) String(atmega169pa) Value(101) EnumValue -Enum(avr_mcu) String(atmega16hva) Value(102) +Enum(avr_mcu) String(atmega16hvb) Value(102) EnumValue -Enum(avr_mcu) String(atmega16hvb) Value(103) +Enum(avr_mcu) String(atmega16hvbrevb) Value(103) EnumValue -Enum(avr_mcu) String(atmega16hvbrevb) Value(104) +Enum(avr_mcu) String(atmega16m1) Value(104) EnumValue -Enum(avr_mcu) String(atmega16m1) Value(105) +Enum(avr_mcu) String(atmega16u4) Value(105) EnumValue -Enum(avr_mcu) String(atmega16u4) Value(106) +Enum(avr_mcu) String(atmega26hvg) Value(106) EnumValue -Enum(avr_mcu) String(atmega26hvg) Value(107) +Enum(avr_mcu) String(atmega32a) Value(107) EnumValue -Enum(avr_mcu) String(atmega32a) Value(108) +Enum(avr_mcu) String(atmega32) Value(108) EnumValue -Enum(avr_mcu) String(atmega32) Value(109) +Enum(avr_mcu) String(atmega323) Value(109) EnumValue -Enum(avr_mcu) String(atmega32a) Value(110) +Enum(avr_mcu) String(atmega324a) Value(110) EnumValue -Enum(avr_mcu) String(atmega323) Value(111) +Enum(avr_mcu) String(atmega324p) Value(111) EnumValue -Enum(avr_mcu) String(atmega324a) Value(112) +Enum(avr_mcu) String(atmega324pa) Value(112) EnumValue -Enum(avr_mcu) String(atmega324p) Value(113) +Enum(avr_mcu) String(atmega325) Value(113) EnumValue -Enum(avr_mcu) String(atmega324pa) Value(114) +Enum(avr_mcu) String(atmega325a) Value(114) EnumValue -Enum(avr_mcu) String(atmega325) Value(115) +Enum(avr_mcu) String(atmega325p) Value(115) EnumValue -Enum(avr_mcu) String(atmega325a) Value(116) +Enum(avr_mcu) String(atmega3250) Value(116) EnumValue -Enum(avr_mcu) String(atmega325p) Value(117) +Enum(avr_mcu) String(atmega3250a) Value(117) EnumValue -Enum(avr_mcu) String(atmega3250) Value(118) +Enum(avr_mcu) String(atmega3250p) Value(118) EnumValue -Enum(avr_mcu) String(atmega3250a) Value(119) +Enum(avr_mcu) String(atmega3250pa) Value(119) EnumValue -Enum(avr_mcu) String(atmega3250p) Value(120) +Enum(avr_mcu) String(atmega328) Value(120) EnumValue -Enum(avr_mcu) String(atmega3250pa) Value(121) +Enum(avr_mcu) String(atmega328p) Value(121) EnumValue -Enum(avr_mcu) String(atmega328) Value(122) +Enum(avr_mcu) String(atmega329) Value(122) EnumValue -Enum(avr_mcu) String(atmega328p) Value(123) +Enum(avr_mcu) String(atmega329a) Value(123) EnumValue -Enum(avr_mcu) String(atmega329) Value(124) +Enum(avr_mcu) String(atmega329p) Value(124) EnumValue -Enum(avr_mcu) String(atmega329a) Value(125) +Enum(avr_mcu) String(atmega329pa) Value(125) EnumValue -Enum(avr_mcu) String(atmega329p) Value(126) +Enum(avr_mcu) String(atmega3290) Value(126) EnumValue -Enum(avr_mcu) String(atmega329pa) Value(127) +Enum(avr_mcu) String(atmega3290a) Value(127) EnumValue -Enum(avr_mcu) String(atmega3290) Value(128) +Enum(avr_mcu) String(atmega3290p) Value(128) EnumValue -Enum(avr_mcu) String(atmega3290a) Value(129) +Enum(avr_mcu) String(atmega3290pa) Value(129) EnumValue -Enum(avr_mcu) String(atmega3290p) Value(130) +Enum(avr_mcu) String(atmega32c1) Value(130) EnumValue -Enum(avr_mcu) String(atmega3290pa) Value(131) +Enum(avr_mcu) String(atmega32m1) Value(131) EnumValue -Enum(avr_mcu) String(atmega32c1) Value(132) +Enum(avr_mcu) String(atmega32u4) Value(132) EnumValue -Enum(avr_mcu) String(atmega32m1) Value(133) +Enum(avr_mcu) String(atmega32u6) Value(133) EnumValue -Enum(avr_mcu) String(atmega32u4) Value(134) +Enum(avr_mcu) String(atmega406) Value(134) EnumValue -Enum(avr_mcu) String(atmega32u6) Value(135) +Enum(avr_mcu) String(atmega64) Value(135) EnumValue -Enum(avr_mcu) String(atmega406) Value(136) +Enum(avr_mcu) String(atmega64a) Value(136) EnumValue -Enum(avr_mcu) String(atmega64) Value(137) +Enum(avr_mcu) String(atmega640) Value(137) EnumValue -Enum(avr_mcu) String(atmega64a) Value(138) +Enum(avr_mcu) String(atmega644) Value(138) EnumValue -Enum(avr_mcu) String(atmega640) Value(139) +Enum(avr_mcu) String(atmega644a) Value(139) EnumValue -Enum(avr_mcu) String(atmega644) Value(140) +Enum(avr_mcu) String(atmega644p) Value(140) EnumValue -Enum(avr_mcu) String(atmega644a) Value(141) +Enum(avr_mcu) String(atmega644pa) Value(141) EnumValue -Enum(avr_mcu) String(atmega644p) Value(142) +Enum(avr_mcu) String(atmega645) Value(142) EnumValue -Enum(avr_mcu) String(atmega644pa) Value(143) +Enum(avr_mcu) String(atmega645a) Value(143) EnumValue -Enum(avr_mcu) String(atmega645) Value(144) +Enum(avr_mcu) String(atmega645p) Value(144) EnumValue -Enum(avr_mcu) String(atmega645a) Value(145) +Enum(avr_mcu) String(atmega6450) Value(145) EnumValue -Enum(avr_mcu) String(atmega645p) Value(146) +Enum(avr_mcu) String(atmega6450a) Value(146) EnumValue -Enum(avr_mcu) String(atmega6450) Value(147) +Enum(avr_mcu) String(atmega6450p) Value(147) EnumValue -Enum(avr_mcu) String(atmega6450a) Value(148) +Enum(avr_mcu) String(atmega649) Value(148) EnumValue -Enum(avr_mcu) String(atmega6450p) Value(149) +Enum(avr_mcu) String(atmega649a) Value(149) EnumValue -Enum(avr_mcu) String(atmega649) Value(150) +Enum(avr_mcu) String(atmega649p) Value(150) EnumValue -Enum(avr_mcu) String(atmega649a) Value(151) +Enum(avr_mcu) String(atmega6490) Value(151) EnumValue -Enum(avr_mcu) String(atmega649p) Value(152) +Enum(avr_mcu) String(atmega16hva) Value(152) EnumValue -Enum(avr_mcu) String(atmega6490) Value(153) +Enum(avr_mcu) String(atmega16hva2) Value(153) EnumValue -Enum(avr_mcu) String(atmega16hva) Value(154) +Enum(avr_mcu) String(atmega32hvb) Value(154) EnumValue -Enum(avr_mcu) String(atmega16hva2) Value(155) +Enum(avr_mcu) String(atmega6490a) Value(155) EnumValue -Enum(avr_mcu) String(atmega16hvb) Value(156) +Enum(avr_mcu) String(atmega6490p) Value(156) EnumValue -Enum(avr_mcu) String(atmega32hvb) Value(157) +Enum(avr_mcu) String(atmega64c1) Value(157) EnumValue -Enum(avr_mcu) String(atmega6490a) Value(158) +Enum(avr_mcu) String(atmega64m1) Value(158) EnumValue -Enum(avr_mcu) String(atmega6490p) Value(159) +Enum(avr_mcu) String(atmega64hve) Value(159) EnumValue -Enum(avr_mcu) String(atmega64c1) Value(160) +Enum(avr_mcu) String(atmega64rfa2) Value(160) EnumValue -Enum(avr_mcu) String(atmega64m1) Value(161) +Enum(avr_mcu) String(atmega64rfr2) Value(161) EnumValue -Enum(avr_mcu) String(atmega64hve) Value(162) +Enum(avr_mcu) String(atmega32hvbrevb) Value(162) EnumValue -Enum(avr_mcu) String(atmega64rfa2) Value(163) +Enum(avr_mcu) String(atmega48hvf) Value(163) EnumValue -Enum(avr_mcu) String(atmega64rfr2) Value(164) +Enum(avr_mcu) String(at90can32) Value(164) EnumValue -Enum(avr_mcu) String(atmega32hvb) Value(165) +Enum(avr_mcu) String(at90can64) Value(165) EnumValue -Enum(avr_mcu) String(atmega32hvbrevb) Value(166) +Enum(avr_mcu) String(at90pwm161) Value(166) EnumValue -Enum(avr_mcu) String(atmega16hva2) Value(167) +Enum(avr_mcu) String(at90pwm216) Value(167) EnumValue -Enum(avr_mcu) String(atmega48hvf) Value(168) +Enum(avr_mcu) String(at90pwm316) Value(168) EnumValue -Enum(avr_mcu) String(at90can32) Value(169) +Enum(avr_mcu) String(at90scr100) Value(169) EnumValue -Enum(avr_mcu) String(at90can64) Value(170) +Enum(avr_mcu) String(at90usb646) Value(170) EnumValue -Enum(avr_mcu) String(at90pwm161) Value(171) +Enum(avr_mcu) String(at90usb647) Value(171) EnumValue -Enum(avr_mcu) String(at90pwm216) Value(172) +Enum(avr_mcu) String(at94k) Value(172) EnumValue -Enum(avr_mcu) String(at90pwm316) Value(173) +Enum(avr_mcu) String(m3000) Value(173) EnumValue -Enum(avr_mcu) String(atmega32c1) Value(174) +Enum(avr_mcu) String(avr51) Value(174) EnumValue -Enum(avr_mcu) String(atmega64c1) Value(175) +Enum(avr_mcu) String(atmega128) Value(175) EnumValue -Enum(avr_mcu) String(atmega16m1) Value(176) +Enum(avr_mcu) String(atmega128a) Value(176) EnumValue -Enum(avr_mcu) String(atmega32m1) Value(177) +Enum(avr_mcu) String(atmega1280) Value(177) EnumValue -Enum(avr_mcu) String(atmega64m1) Value(178) +Enum(avr_mcu) String(atmega1281) Value(178) EnumValue -Enum(avr_mcu) String(atmega16u4) Value(179) +Enum(avr_mcu) String(atmega1284) Value(179) EnumValue -Enum(avr_mcu) String(atmega32u4) Value(180) +Enum(avr_mcu) String(atmega1284p) Value(180) EnumValue -Enum(avr_mcu) String(atmega32u6) Value(181) +Enum(avr_mcu) String(atmega128rfa1) Value(181) EnumValue -Enum(avr_mcu) String(at90scr100) Value(182) +Enum(avr_mcu) String(at90can128) Value(182) EnumValue -Enum(avr_mcu) String(at90usb646) Value(183) +Enum(avr_mcu) String(at90usb1286) Value(183) EnumValue -Enum(avr_mcu) String(at90usb647) Value(184) +Enum(avr_mcu) String(at90usb1287) Value(184) EnumValue -Enum(avr_mcu) String(at94k) Value(185) +Enum(avr_mcu) String(avr6) Value(185) EnumValue -Enum(avr_mcu) String(m3000) Value(186) +Enum(avr_mcu) String(atmega2560) Value(186) EnumValue -Enum(avr_mcu) String(avr51) Value(187) +Enum(avr_mcu) String(atmega2561) Value(187) EnumValue -Enum(avr_mcu) String(atmega128) Value(188) +Enum(avr_mcu) String(avrxmega2) Value(188) EnumValue -Enum(avr_mcu) String(atmega128a) Value(189) +Enum(avr_mcu) String(atxmega16a4) Value(189) EnumValue -Enum(avr_mcu) String(atmega1280) Value(190) +Enum(avr_mcu) String(atxmega16d4) Value(190) EnumValue -Enum(avr_mcu) String(atmega1281) Value(191) +Enum(avr_mcu) String(atxmega16x1) Value(191) EnumValue -Enum(avr_mcu) String(atmega1284) Value(192) +Enum(avr_mcu) String(atxmega32a4) Value(192) EnumValue -Enum(avr_mcu) String(atmega1284p) Value(193) +Enum(avr_mcu) String(atxmega32d4) Value(193) EnumValue -Enum(avr_mcu) String(atmega128rfa1) Value(194) +Enum(avr_mcu) String(atxmega32x1) Value(194) EnumValue -Enum(avr_mcu) String(at90can128) Value(195) +Enum(avr_mcu) String(atmxt112sl) Value(195) EnumValue -Enum(avr_mcu) String(at90usb1286) Value(196) +Enum(avr_mcu) String(atmxt224) Value(196) EnumValue -Enum(avr_mcu) String(at90usb1287) Value(197) +Enum(avr_mcu) String(atmxt224e) Value(197) EnumValue -Enum(avr_mcu) String(avr6) Value(198) +Enum(avr_mcu) String(atmxt336s) Value(198) EnumValue -Enum(avr_mcu) String(atmega2560) Value(199) +Enum(avr_mcu) String(atxmega16a4u) Value(199) EnumValue -Enum(avr_mcu) String(atmega2561) Value(200) +Enum(avr_mcu) String(atxmega16c4) Value(200) EnumValue -Enum(avr_mcu) String(avrxmega2) Value(201) +Enum(avr_mcu) String(atxmega32a4u) Value(201) EnumValue -Enum(avr_mcu) String(atxmega16a4) Value(202) +Enum(avr_mcu) String(atxmega32c4) Value(202) EnumValue -Enum(avr_mcu) String(atxmega16d4) Value(203) +Enum(avr_mcu) String(atxmega32e5) Value(203) EnumValue -Enum(avr_mcu) String(atxmega16x1) Value(204) +Enum(avr_mcu) String(avrxmega4) Value(204) EnumValue -Enum(avr_mcu) String(atxmega32a4) Value(205) +Enum(avr_mcu) String(atxmega64a3) Value(205) EnumValue -Enum(avr_mcu) String(atxmega32d4) Value(206) +Enum(avr_mcu) String(atxmega64d3) Value(206) EnumValue -Enum(avr_mcu) String(atxmega32x1) Value(207) +Enum(avr_mcu) String(atxmega64a3u) Value(207) EnumValue -Enum(avr_mcu) String(atmxt112sl) Value(208) +Enum(avr_mcu) String(atxmega64a4u) Value(208) EnumValue -Enum(avr_mcu) String(atmxt224) Value(209) +Enum(avr_mcu) String(atxmega64b1) Value(209) EnumValue -Enum(avr_mcu) String(atmxt224e) Value(210) +Enum(avr_mcu) String(atxmega64b3) Value(210) EnumValue -Enum(avr_mcu) String(atmxt336s) Value(211) +Enum(avr_mcu) String(atxmega64c3) Value(211) EnumValue -Enum(avr_mcu) String(atxmega16a4u) Value(212) +Enum(avr_mcu) String(atxmega64d4) Value(212) EnumValue -Enum(avr_mcu) String(atxmega16c4) Value(213) +Enum(avr_mcu) String(avrxmega5) Value(213) EnumValue -Enum(avr_mcu) String(atxmega32a4u) Value(214) +Enum(avr_mcu) String(atxmega64a1) Value(214) EnumValue -Enum(avr_mcu) String(atxmega32c4) Value(215) +Enum(avr_mcu) String(atxmega64a1u) Value(215) EnumValue -Enum(avr_mcu) String(atxmega32e5) Value(216) +Enum(avr_mcu) String(avrxmega6) Value(216) EnumValue -Enum(avr_mcu) String(avrxmega4) Value(217) +Enum(avr_mcu) String(atxmega128a3) Value(217) EnumValue -Enum(avr_mcu) String(atxmega64a3) Value(218) +Enum(avr_mcu) String(atxmega128d3) Value(218) EnumValue -Enum(avr_mcu) String(atxmega64d3) Value(219) +Enum(avr_mcu) String(atxmega192a3) Value(219) EnumValue -Enum(avr_mcu) String(atxmega64a3u) Value(220) +Enum(avr_mcu) String(atxmega192d3) Value(220) EnumValue -Enum(avr_mcu) String(atxmega64a4u) Value(221) +Enum(avr_mcu) String(atxmega256a3) Value(221) EnumValue -Enum(avr_mcu) String(atxmega64b1) Value(222) +Enum(avr_mcu) String(atxmega256a3b) Value(222) EnumValue -Enum(avr_mcu) String(atxmega64b3) Value(223) +Enum(avr_mcu) String(atxmega256a3bu) Value(223) EnumValue -Enum(avr_mcu) String(atxmega64c3) Value(224) +Enum(avr_mcu) String(atxmega256d3) Value(224) EnumValue -Enum(avr_mcu) String(atxmega64d4) Value(225) +Enum(avr_mcu) String(atxmega128a3u) Value(225) EnumValue -Enum(avr_mcu) String(avrxmega5) Value(226) +Enum(avr_mcu) String(atxmega128b1) Value(226) EnumValue -Enum(avr_mcu) String(atxmega64a1) Value(227) +Enum(avr_mcu) String(atxmega128b3) Value(227) EnumValue -Enum(avr_mcu) String(atxmega64a1u) Value(228) +Enum(avr_mcu) String(atxmega128c3) Value(228) EnumValue -Enum(avr_mcu) String(avrxmega6) Value(229) +Enum(avr_mcu) String(atxmega128d4) Value(229) EnumValue -Enum(avr_mcu) String(atxmega128a3) Value(230) +Enum(avr_mcu) String(atmxt540s) Value(230) EnumValue -Enum(avr_mcu) String(atxmega128d3) Value(231) +Enum(avr_mcu) String(atmxt540sreva) Value(231) EnumValue -Enum(avr_mcu) String(atxmega192a3) Value(232) +Enum(avr_mcu) String(atxmega192a3u) Value(232) EnumValue -Enum(avr_mcu) String(atxmega192d3) Value(233) +Enum(avr_mcu) String(atxmega192c3) Value(233) EnumValue -Enum(avr_mcu) String(atxmega256a3) Value(234) +Enum(avr_mcu) String(atxmega256a3u) Value(234) EnumValue -Enum(avr_mcu) String(atxmega256a3b) Value(235) +Enum(avr_mcu) String(atxmega256c3) Value(235) EnumValue -Enum(avr_mcu) String(atxmega256a3bu) Value(236) +Enum(avr_mcu) String(atxmega384c3) Value(236) EnumValue -Enum(avr_mcu) String(atxmega256d3) Value(237) +Enum(avr_mcu) String(atxmega384d3) Value(237) EnumValue -Enum(avr_mcu) String(atxmega128a3u) Value(238) +Enum(avr_mcu) String(avrxmega7) Value(238) EnumValue -Enum(avr_mcu) String(atxmega128b1) Value(239) +Enum(avr_mcu) String(atxmega128a1) Value(239) EnumValue -Enum(avr_mcu) String(atxmega128b3) Value(240) +Enum(avr_mcu) String(atxmega128a1u) Value(240) EnumValue -Enum(avr_mcu) String(atxmega128c3) Value(241) +Enum(avr_mcu) String(atxmega128a4u) Value(241) EnumValue -Enum(avr_mcu) String(atxmega128d4) Value(242) +Enum(avr_mcu) String(avr1) Value(242) EnumValue -Enum(avr_mcu) String(atmxt540s) Value(243) +Enum(avr_mcu) String(at90s1200) Value(243) EnumValue -Enum(avr_mcu) String(atmxt540sreva) Value(244) +Enum(avr_mcu) String(attiny11) Value(244) EnumValue -Enum(avr_mcu) String(atxmega192a3u) Value(245) +Enum(avr_mcu) String(attiny12) Value(245) EnumValue -Enum(avr_mcu) String(atxmega192c3) Value(246) +Enum(avr_mcu) String(attiny15) Value(246) EnumValue -Enum(avr_mcu) String(atxmega256a3u) Value(247) - -EnumValue -Enum(avr_mcu) String(atxmega256c3) Value(248) - -EnumValue -Enum(avr_mcu) String(atxmega384c3) Value(249) - -EnumValue -Enum(avr_mcu) String(atxmega384d3) Value(250) - -EnumValue -Enum(avr_mcu) String(avrxmega7) Value(251) - -EnumValue -Enum(avr_mcu) String(atxmega128a1) Value(252) - -EnumValue -Enum(avr_mcu) String(atxmega128a1u) Value(253) - -EnumValue -Enum(avr_mcu) String(atxmega128a4u) Value(254) - -EnumValue -Enum(avr_mcu) String(avr1) Value(255) - -EnumValue -Enum(avr_mcu) String(at90s1200) Value(256) - -EnumValue -Enum(avr_mcu) String(attiny11) Value(257) - -EnumValue -Enum(avr_mcu) String(attiny12) Value(258) - -EnumValue -Enum(avr_mcu) String(attiny15) Value(259) - -EnumValue -Enum(avr_mcu) String(attiny28) Value(260) +Enum(avr_mcu) String(attiny28) Value(247) diff -Naur gcc-4.8.1.orig/gcc/config/avr/gen-avr-mmcu-texi.c gcc-4.8.1/gcc/config/avr/gen-avr-mmcu-texi.c --- gcc-4.8.1.orig/gcc/config/avr/gen-avr-mmcu-texi.c 2013-01-14 12:09:34.000000000 -0600 +++ gcc-4.8.1/gcc/config/avr/gen-avr-mmcu-texi.c 2013-07-10 07:36:36.732157000 -0500 @@ -68,6 +68,7 @@ static void print_mcus (size_t n_mcus) { + int duplicate = 0; size_t i; if (!n_mcus) @@ -78,7 +79,20 @@ printf ("@*@var{mcu}@tie{}="); for (i = 0; i < n_mcus; i++) - printf (" @code{%s}%s", mcu_name[i], i == n_mcus-1 ? ".\n\n" : ","); + { + printf (" @code{%s}%s", mcu_name[i], i == n_mcus-1 ? ".\n\n" : ","); + + if (i && !strcmp (mcu_name[i], mcu_name[i-1])) + { + /* Sanity-check: Fail on devices that are present more than once. */ + + duplicate = 1; + fprintf (stderr, "error: duplicate device: %s\n", mcu_name[i]); + } + } + + if (duplicate) + exit (1); } int main (void) diff -Naur gcc-4.8.1.orig/gcc/config/avr/t-multilib gcc-4.8.1/gcc/config/avr/t-multilib --- gcc-4.8.1.orig/gcc/config/avr/t-multilib 2013-02-28 03:03:09.000000000 -0600 +++ gcc-4.8.1/gcc/config/avr/t-multilib 2013-07-10 07:36:36.732157000 -0500 @@ -135,7 +135,6 @@ mmcu?avr5=mmcu?atmega169a \ mmcu?avr5=mmcu?atmega169p \ mmcu?avr5=mmcu?atmega169pa \ - mmcu?avr5=mmcu?atmega16hva \ mmcu?avr5=mmcu?atmega16hvb \ mmcu?avr5=mmcu?atmega16hvbrevb \ mmcu?avr5=mmcu?atmega16m1 \ @@ -143,7 +142,6 @@ mmcu?avr5=mmcu?atmega26hvg \ mmcu?avr5=mmcu?atmega32a \ mmcu?avr5=mmcu?atmega32 \ - mmcu?avr5=mmcu?atmega32a \ mmcu?avr5=mmcu?atmega323 \ mmcu?avr5=mmcu?atmega324a \ mmcu?avr5=mmcu?atmega324p \ @@ -189,7 +187,6 @@ mmcu?avr5=mmcu?atmega6490 \ mmcu?avr5=mmcu?atmega16hva \ mmcu?avr5=mmcu?atmega16hva2 \ - mmcu?avr5=mmcu?atmega16hvb \ mmcu?avr5=mmcu?atmega32hvb \ mmcu?avr5=mmcu?atmega6490a \ mmcu?avr5=mmcu?atmega6490p \ @@ -198,23 +195,13 @@ mmcu?avr5=mmcu?atmega64hve \ mmcu?avr5=mmcu?atmega64rfa2 \ mmcu?avr5=mmcu?atmega64rfr2 \ - mmcu?avr5=mmcu?atmega32hvb \ mmcu?avr5=mmcu?atmega32hvbrevb \ - mmcu?avr5=mmcu?atmega16hva2 \ mmcu?avr5=mmcu?atmega48hvf \ mmcu?avr5=mmcu?at90can32 \ mmcu?avr5=mmcu?at90can64 \ mmcu?avr5=mmcu?at90pwm161 \ mmcu?avr5=mmcu?at90pwm216 \ mmcu?avr5=mmcu?at90pwm316 \ - mmcu?avr5=mmcu?atmega32c1 \ - mmcu?avr5=mmcu?atmega64c1 \ - mmcu?avr5=mmcu?atmega16m1 \ - mmcu?avr5=mmcu?atmega32m1 \ - mmcu?avr5=mmcu?atmega64m1 \ - mmcu?avr5=mmcu?atmega16u4 \ - mmcu?avr5=mmcu?atmega32u4 \ - mmcu?avr5=mmcu?atmega32u6 \ mmcu?avr5=mmcu?at90scr100 \ mmcu?avr5=mmcu?at90usb646 \ mmcu?avr5=mmcu?at90usb647 \ diff -Naur gcc-4.8.1.orig/gcc/config/darwin.c gcc-4.8.1/gcc/config/darwin.c --- gcc-4.8.1.orig/gcc/config/darwin.c 2013-02-11 16:36:23.000000000 -0600 +++ gcc-4.8.1/gcc/config/darwin.c 2013-07-22 03:57:41.322517000 -0500 @@ -369,14 +369,13 @@ static GTY(()) const char * function_base_func_name; static GTY(()) int current_pic_label_num; +static GTY(()) int emitted_pic_label_num; -void -machopic_output_function_base_name (FILE *file) +static void +update_pic_label_number_if_needed (void) { const char *current_name; - /* If dynamic-no-pic is on, we should not get here. */ - gcc_assert (!MACHO_DYNAMIC_NO_PIC_P); /* When we are generating _get_pc thunks within stubs, there is no current function. */ if (current_function_decl) @@ -394,7 +393,28 @@ ++current_pic_label_num; function_base_func_name = "L_machopic_stub_dummy"; } - fprintf (file, "L%011d$pb", current_pic_label_num); +} + +void +machopic_output_function_base_name (FILE *file) +{ + /* If dynamic-no-pic is on, we should not get here. */ + gcc_assert (!MACHO_DYNAMIC_NO_PIC_P); + + update_pic_label_number_if_needed (); + fprintf (file, "L%d$pb", current_pic_label_num); +} + +bool +machopic_should_output_picbase_label (void) +{ + update_pic_label_number_if_needed (); + + if (current_pic_label_num == emitted_pic_label_num) + return false; + + emitted_pic_label_num = current_pic_label_num; + return true; } /* The suffix attached to non-lazy pointer symbols. */ diff -Naur gcc-4.8.1.orig/gcc/config/darwin-protos.h gcc-4.8.1/gcc/config/darwin-protos.h --- gcc-4.8.1.orig/gcc/config/darwin-protos.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/darwin-protos.h 2013-07-22 03:57:41.322517000 -0500 @@ -25,6 +25,7 @@ extern void machopic_output_function_base_name (FILE *); extern const char *machopic_indirection_name (rtx, bool); extern const char *machopic_mcount_stub_name (void); +extern bool machopic_should_output_picbase_label (void); #ifdef RTX_CODE diff -Naur gcc-4.8.1.orig/gcc/config/i386/bmiintrin.h gcc-4.8.1/gcc/config/i386/bmiintrin.h --- gcc-4.8.1.orig/gcc/config/i386/bmiintrin.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/i386/bmiintrin.h 2013-07-19 02:38:07.333150000 -0500 @@ -38,7 +38,6 @@ return __builtin_ctzs (__X); } - extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __andn_u32 (unsigned int __X, unsigned int __Y) { @@ -52,23 +51,46 @@ } extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_bextr_u32 (unsigned int __X, unsigned int __Y, unsigned __Z) +{ + return __builtin_ia32_bextr_u32 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8))); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __blsi_u32 (unsigned int __X) { return __X & -__X; } extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsi_u32 (unsigned int __X) +{ + return __blsi_u32 (__X); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __blsmsk_u32 (unsigned int __X) { return __X ^ (__X - 1); } extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsmsk_u32 (unsigned int __X) +{ + return __blsmsk_u32 (__X); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __blsr_u32 (unsigned int __X) { return __X & (__X - 1); } +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsr_u32 (unsigned int __X) +{ + return __blsr_u32 (__X); +} extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __tzcnt_u32 (unsigned int __X) @@ -76,6 +98,12 @@ return __builtin_ctz (__X); } +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_tzcnt_u32 (unsigned int __X) +{ + return __builtin_ctz (__X); +} + #ifdef __x86_64__ extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -91,28 +119,58 @@ } extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_bextr_u64 (unsigned long long __X, unsigned int __Y, unsigned int __Z) +{ + return __builtin_ia32_bextr_u64 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8))); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __blsi_u64 (unsigned long long __X) { return __X & -__X; } extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsi_u64 (unsigned long long __X) +{ + return __blsi_u64 (__X); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __blsmsk_u64 (unsigned long long __X) { return __X ^ (__X - 1); } extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsmsk_u64 (unsigned long long __X) +{ + return __blsmsk_u64 (__X); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __blsr_u64 (unsigned long long __X) { return __X & (__X - 1); } extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsr_u64 (unsigned long long __X) +{ + return __blsr_u64 (__X); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __tzcnt_u64 (unsigned long long __X) { return __builtin_ctzll (__X); } + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_tzcnt_u64 (unsigned long long __X) +{ + return __builtin_ctzll (__X); +} #endif /* __x86_64__ */ diff -Naur gcc-4.8.1.orig/gcc/config/i386/driver-i386.c gcc-4.8.1/gcc/config/i386/driver-i386.c --- gcc-4.8.1.orig/gcc/config/i386/driver-i386.c 2013-05-17 10:06:36.000000000 -0500 +++ gcc-4.8.1/gcc/config/i386/driver-i386.c 2013-08-28 03:25:13.429539000 -0500 @@ -520,8 +520,7 @@ if (vendor == signature_AMD_ebx || vendor == signature_CENTAUR_ebx || vendor == signature_CYRIX_ebx - || vendor == signature_NSC_ebx - || vendor == signature_TM2_ebx) + || vendor == signature_NSC_ebx) cache = detect_caches_amd (ext_level); else if (vendor == signature_INTEL_ebx) { @@ -639,13 +638,18 @@ /* Atom. */ cpu = "atom"; break; + case 0x0f: + /* Merom. */ + case 0x17: + case 0x1d: + /* Penryn. */ + cpu = "core2"; + break; case 0x1a: case 0x1e: case 0x1f: case 0x2e: /* Nehalem. */ - cpu = "corei7"; - break; case 0x25: case 0x2c: case 0x2f: @@ -657,20 +661,25 @@ /* Sandy Bridge. */ cpu = "corei7-avx"; break; - case 0x17: - case 0x1d: - /* Penryn. */ - cpu = "core2"; - break; - case 0x0f: - /* Merom. */ - cpu = "core2"; + case 0x3a: + case 0x3e: + /* Ivy Bridge. */ + cpu = "core-avx-i"; + break; + case 0x3c: + case 0x45: + case 0x46: + /* Haswell. */ + cpu = "core-avx2"; break; default: if (arch) { /* This is unknown family 0x6 CPU. */ - if (has_avx) + if (has_avx2) + /* Assume Haswell. */ + cpu = "core-avx2"; + else if (has_avx) /* Assume Sandy Bridge. */ cpu = "corei7-avx"; else if (has_sse4_2) diff -Naur gcc-4.8.1.orig/gcc/config/i386/i386.c gcc-4.8.1/gcc/config/i386/i386.c --- gcc-4.8.1.orig/gcc/config/i386/i386.c 2013-05-17 10:06:36.000000000 -0500 +++ gcc-4.8.1/gcc/config/i386/i386.c 2013-08-23 05:01:34.440607000 -0500 @@ -2438,11 +2438,11 @@ {&generic32_cost, 16, 7, 16, 7, 16}, {&generic64_cost, 16, 10, 16, 10, 16}, {&amdfam10_cost, 32, 24, 32, 7, 32}, - {&bdver1_cost, 32, 24, 32, 7, 32}, - {&bdver2_cost, 32, 24, 32, 7, 32}, - {&bdver3_cost, 32, 24, 32, 7, 32}, - {&btver1_cost, 32, 24, 32, 7, 32}, - {&btver2_cost, 32, 24, 32, 7, 32}, + {&bdver1_cost, 16, 10, 16, 7, 11}, + {&bdver2_cost, 16, 10, 16, 7, 11}, + {&bdver3_cost, 16, 10, 16, 7, 11}, + {&btver1_cost, 16, 10, 16, 7, 11}, + {&btver2_cost, 16, 10, 16, 7, 11}, {&atom_cost, 16, 15, 16, 7, 16} }; @@ -3768,24 +3768,19 @@ ix86_gen_leave = gen_leave_rex64; if (Pmode == DImode) { - ix86_gen_monitor = gen_sse3_monitor64_di; ix86_gen_tls_global_dynamic_64 = gen_tls_global_dynamic_64_di; ix86_gen_tls_local_dynamic_base_64 = gen_tls_local_dynamic_base_64_di; } else { - ix86_gen_monitor = gen_sse3_monitor64_si; ix86_gen_tls_global_dynamic_64 = gen_tls_global_dynamic_64_si; ix86_gen_tls_local_dynamic_base_64 = gen_tls_local_dynamic_base_64_si; } } else - { - ix86_gen_leave = gen_leave; - ix86_gen_monitor = gen_sse3_monitor; - } + ix86_gen_leave = gen_leave; if (Pmode == DImode) { @@ -3797,6 +3792,7 @@ ix86_gen_allocate_stack_worker = gen_allocate_stack_worker_probe_di; ix86_gen_adjust_stack_and_probe = gen_adjust_stack_and_probedi; ix86_gen_probe_stack_range = gen_probe_stack_rangedi; + ix86_gen_monitor = gen_sse3_monitor_di; } else { @@ -3808,6 +3804,7 @@ ix86_gen_allocate_stack_worker = gen_allocate_stack_worker_probe_si; ix86_gen_adjust_stack_and_probe = gen_adjust_stack_and_probesi; ix86_gen_probe_stack_range = gen_probe_stack_rangesi; + ix86_gen_monitor = gen_sse3_monitor_si; } #ifdef USE_IX86_CLD @@ -4691,6 +4688,28 @@ return default_elf_select_section (decl, reloc, align); } +/* Select a set of attributes for section NAME based on the properties + of DECL and whether or not RELOC indicates that DECL's initializer + might contain runtime relocations. */ + +static unsigned int ATTRIBUTE_UNUSED +x86_64_elf_section_type_flags (tree decl, const char *name, int reloc) +{ + unsigned int flags = default_section_type_flags (decl, name, reloc); + + if (decl == NULL_TREE + && (strcmp (name, ".ldata.rel.ro") == 0 + || strcmp (name, ".ldata.rel.ro.local") == 0)) + flags |= SECTION_RELRO; + + if (strcmp (name, ".lbss") == 0 + || strncmp (name, ".lbss.", 5) == 0 + || strncmp (name, ".gnu.linkonce.lb.", 16) == 0) + flags |= SECTION_BSS; + + return flags; +} + /* Build up a unique section name, expressed as a STRING_CST node, and assign it to DECL_SECTION_NAME (decl). RELOC indicates whether the initial value of EXP requires @@ -6396,7 +6415,7 @@ /* Likewise, error if the ABI requires us to return values in the x87 registers and the user specified -mno-80387. */ - if (!TARGET_80387 && in_return) + if (in_return && !TARGET_FLOAT_RETURNS_IN_80387) for (i = 0; i < n; i++) if (regclass[i] == X86_64_X87_CLASS || regclass[i] == X86_64_X87UP_CLASS @@ -8721,17 +8740,12 @@ if (!flag_pic) { - xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ()); + if (TARGET_MACHO) + /* We don't need a pic base, we're not producing pic. */ + gcc_unreachable (); + xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ()); output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops); - -#if TARGET_MACHO - /* Output the Mach-O "canonical" label name ("Lxx$pb") here too. This - is what will be referenced by the Mach-O PIC subsystem. */ - if (!label) - ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME); -#endif - targetm.asm_out.internal_label (asm_out_file, "L", CODE_LABEL_NUMBER (XEXP (xops[2], 0))); } @@ -8744,12 +8758,18 @@ xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); xops[2] = gen_rtx_MEM (QImode, xops[2]); output_asm_insn ("call\t%X2", xops); - /* Output the Mach-O "canonical" label name ("Lxx$pb") here too. This - is what will be referenced by the Mach-O PIC subsystem. */ + #if TARGET_MACHO - if (!label) + /* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here. + This is what will be referenced by the Mach-O PIC subsystem. */ + if (machopic_should_output_picbase_label () || !label) ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME); - else + + /* When we are restoring the pic base at the site of a nonlocal label, + and we decided to emit the pic base above, we will still output a + local label used for calculating the correction offset (even though + the offset will be 0 in that case). */ + if (label) targetm.asm_out.internal_label (asm_out_file, "L", CODE_LABEL_NUMBER (label)); #endif @@ -8831,7 +8851,8 @@ && (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM) || crtl->profile || crtl->calls_eh_return - || crtl->uses_const_pool)) + || crtl->uses_const_pool + || cfun->has_nonlocal_label)) return ix86_select_alt_pic_regnum () == INVALID_REGNUM; if (crtl->calls_eh_return && maybe_eh_return) @@ -13596,21 +13617,29 @@ x = replace_equiv_address_nv (orig_x, x); return x; } - if (GET_CODE (x) != CONST - || GET_CODE (XEXP (x, 0)) != UNSPEC - || (XINT (XEXP (x, 0), 1) != UNSPEC_GOTPCREL - && XINT (XEXP (x, 0), 1) != UNSPEC_PCREL) - || (!MEM_P (orig_x) && XINT (XEXP (x, 0), 1) != UNSPEC_PCREL)) - return ix86_delegitimize_tls_address (orig_x); - x = XVECEXP (XEXP (x, 0), 0, 0); - if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x)) - { - x = simplify_gen_subreg (GET_MODE (orig_x), x, - GET_MODE (x), 0); - if (x == NULL_RTX) - return orig_x; + + if (GET_CODE (x) == CONST + && GET_CODE (XEXP (x, 0)) == UNSPEC + && (XINT (XEXP (x, 0), 1) == UNSPEC_GOTPCREL + || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL) + && (MEM_P (orig_x) || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL)) + { + x = XVECEXP (XEXP (x, 0), 0, 0); + if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x)) + { + x = simplify_gen_subreg (GET_MODE (orig_x), x, + GET_MODE (x), 0); + if (x == NULL_RTX) + return orig_x; + } + return x; } - return x; + + if (ix86_cmodel != CM_MEDIUM_PIC && ix86_cmodel != CM_LARGE_PIC) + return ix86_delegitimize_tls_address (orig_x); + + /* Fall thru into the code shared with -m32 for -mcmodel=large -fpic + and -mcmodel=medium -fpic. */ } if (GET_CODE (x) != PLUS @@ -13647,10 +13676,12 @@ if (GET_CODE (x) == UNSPEC && ((XINT (x, 1) == UNSPEC_GOT && MEM_P (orig_x) && !addend) - || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x)))) + || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x)) + || (XINT (x, 1) == UNSPEC_PLTOFF && ix86_cmodel == CM_LARGE_PIC + && !MEM_P (orig_x) && !addend))) result = XVECEXP (x, 0, 0); - if (TARGET_MACHO && darwin_local_data_pic (x) + if (!TARGET_64BIT && TARGET_MACHO && darwin_local_data_pic (x) && !MEM_P (orig_x)) result = XVECEXP (x, 0, 0); @@ -28935,10 +28966,11 @@ if (predicate_chain == NULL_TREE) continue; + function_version_info [actual_versions].version_decl = version_decl; + function_version_info [actual_versions].predicate_chain + = predicate_chain; + function_version_info [actual_versions].dispatch_priority = priority; actual_versions++; - function_version_info [ix - 1].version_decl = version_decl; - function_version_info [ix - 1].predicate_chain = predicate_chain; - function_version_info [ix - 1].dispatch_priority = priority; } /* Sort the versions according to descending order of dispatch priority. The @@ -31780,7 +31812,13 @@ } if (target == 0) - target = gen_reg_rtx (mode); + { + /* mode is VOIDmode if __builtin_rd* has been called + without lhs. */ + if (mode == VOIDmode) + return target; + target = gen_reg_rtx (mode); + } if (TARGET_64BIT) { @@ -35444,6 +35482,46 @@ } } +/* Fix up a Windows system unwinder issue. If an EH region falls thru into + the epilogue, the Windows system unwinder will apply epilogue logic and + produce incorrect offsets. This can be avoided by adding a nop between + the last insn that can throw and the first insn of the epilogue. */ + +static void +ix86_seh_fixup_eh_fallthru (void) +{ + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) + { + rtx insn, next; + + /* Find the beginning of the epilogue. */ + for (insn = BB_END (e->src); insn != NULL; insn = PREV_INSN (insn)) + if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG) + break; + if (insn == NULL) + continue; + + /* We only care about preceeding insns that can throw. */ + insn = prev_active_insn (insn); + if (insn == NULL || !can_throw_internal (insn)) + continue; + + /* Do not separate calls from their debug information. */ + for (next = NEXT_INSN (insn); next != NULL; next = NEXT_INSN (next)) + if (NOTE_P (next) + && (NOTE_KIND (next) == NOTE_INSN_VAR_LOCATION + || NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)) + insn = next; + else + break; + + emit_insn_after (gen_nops (const1_rtx), insn); + } +} + /* Implement machine specific optimizations. We implement padding of returns for K8 CPUs and pass to avoid 4 jumps in the single 16 byte window. */ static void @@ -35453,6 +35531,9 @@ with old MDEP_REORGS that are not CFG based. Recompute it now. */ compute_bb_for_insn (); + if (TARGET_SEH && current_function_has_exception_handlers ()) + ix86_seh_fixup_eh_fallthru (); + if (optimize && optimize_function_for_speed_p (cfun)) { if (TARGET_PAD_SHORT_FUNCTION) @@ -42205,6 +42286,8 @@ #undef TARGET_ATTRIBUTE_TABLE #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table +#undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P +#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true #if TARGET_DLLIMPORT_DECL_ATTRIBUTES # undef TARGET_MERGE_DECL_ATTRIBUTES # define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes diff -Naur gcc-4.8.1.orig/gcc/config/i386/i386.md gcc-4.8.1/gcc/config/i386/i386.md --- gcc-4.8.1.orig/gcc/config/i386/i386.md 2013-05-22 07:16:41.000000000 -0500 +++ gcc-4.8.1/gcc/config/i386/i386.md 2013-08-13 07:45:06.811510000 -0500 @@ -222,6 +222,8 @@ UNSPECV_XEND UNSPECV_XABORT UNSPECV_XTEST + + UNSPECV_NLGR ]) ;; Constants to represent rounding modes in the ROUND instruction @@ -2314,7 +2316,7 @@ "TARGET_LP64 && ix86_check_movabs (insn, 0)" "@ movabs{}\t{%1, %P0|[%P0], %1} - mov{}\t{%1, %a0|%a0, %1}" + mov{}\t{%1, %a0| PTR %a0, %1}" [(set_attr "type" "imov") (set_attr "modrm" "0,*") (set_attr "length_address" "8,0") @@ -2328,7 +2330,7 @@ "TARGET_LP64 && ix86_check_movabs (insn, 1)" "@ movabs{}\t{%P1, %0|%0, [%P1]} - mov{}\t{%a1, %0|%0, %a1}" + mov{}\t{%a1, %0|%0, PTR %a1}" [(set_attr "type" "imov") (set_attr "modrm" "0,*") (set_attr "length_address" "8,0") @@ -12120,8 +12122,8 @@ (define_insn "bmi_bextr_" [(set (match_operand:SWI48 0 "register_operand" "=r,r") - (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r,r") - (match_operand:SWI48 2 "nonimmediate_operand" "r,m")] + (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m") + (match_operand:SWI48 2 "register_operand" "r,r")] UNSPEC_BEXTR)) (clobber (reg:CC FLAGS_REG))] "TARGET_BMI" @@ -12174,9 +12176,9 @@ ;; BMI2 instructions. (define_insn "bmi2_bzhi_3" [(set (match_operand:SWI48 0 "register_operand" "=r") - (and:SWI48 (match_operand:SWI48 1 "register_operand" "r") - (lshiftrt:SWI48 (const_int -1) - (match_operand:SWI48 2 "nonimmediate_operand" "rm")))) + (and:SWI48 (lshiftrt:SWI48 (const_int -1) + (match_operand:SWI48 2 "register_operand" "r")) + (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) (clobber (reg:CC FLAGS_REG))] "TARGET_BMI2" "bzhi\t{%2, %1, %0|%0, %1, %2}" @@ -16646,7 +16648,37 @@ emit_insn (gen_set_got (pic_offset_table_rtx)); DONE; }) - + +(define_insn_and_split "nonlocal_goto_receiver" + [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)] + "TARGET_MACHO && !TARGET_64BIT && flag_pic" + "#" + "&& reload_completed" + [(const_int 0)] +{ + if (crtl->uses_pic_offset_table) + { + rtx xops[3]; + rtx label_rtx = gen_label_rtx (); + rtx tmp; + + /* Get a new pic base. */ + emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); + /* Correct this with the offset from the new to the old. */ + xops[0] = xops[1] = pic_offset_table_rtx; + label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx); + tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx), + UNSPEC_MACHOPIC_OFFSET); + xops[2] = gen_rtx_CONST (Pmode, tmp); + ix86_expand_binary_operator (MINUS, SImode, xops); + } + else + /* No pic reg restore needed. */ + emit_note (NOTE_INSN_DELETED); + + DONE; +}) + ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. (define_split @@ -17043,6 +17075,7 @@ "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) && peep2_reg_dead_p (4, operands[0]) && !reg_overlap_mentioned_p (operands[0], operands[1]) + && !reg_overlap_mentioned_p (operands[0], operands[2]) && (mode != QImode || immediate_operand (operands[2], QImode) || q_regs_operand (operands[2], QImode)) @@ -17107,6 +17140,7 @@ || immediate_operand (operands[2], SImode) || q_regs_operand (operands[2], SImode)) && !reg_overlap_mentioned_p (operands[0], operands[1]) + && !reg_overlap_mentioned_p (operands[0], operands[2]) && ix86_match_ccmode (peep2_next_insn (3), (GET_CODE (operands[3]) == PLUS || GET_CODE (operands[3]) == MINUS) diff -Naur gcc-4.8.1.orig/gcc/config/i386/predicates.md gcc-4.8.1/gcc/config/i386/predicates.md --- gcc-4.8.1.orig/gcc/config/i386/predicates.md 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/i386/predicates.md 2013-07-03 15:24:19.796040000 -0500 @@ -835,19 +835,28 @@ return false; /* VSIB addressing doesn't support (%rip). */ - if (parts.disp && GET_CODE (parts.disp) == CONST) + if (parts.disp) { - disp = XEXP (parts.disp, 0); - if (GET_CODE (disp) == PLUS) - disp = XEXP (disp, 0); - if (GET_CODE (disp) == UNSPEC) - switch (XINT (disp, 1)) - { - case UNSPEC_GOTPCREL: - case UNSPEC_PCREL: - case UNSPEC_GOTNTPOFF: - return false; - } + disp = parts.disp; + if (GET_CODE (disp) == CONST) + { + disp = XEXP (disp, 0); + if (GET_CODE (disp) == PLUS) + disp = XEXP (disp, 0); + if (GET_CODE (disp) == UNSPEC) + switch (XINT (disp, 1)) + { + case UNSPEC_GOTPCREL: + case UNSPEC_PCREL: + case UNSPEC_GOTNTPOFF: + return false; + } + } + if (TARGET_64BIT + && flag_pic + && (GET_CODE (disp) == SYMBOL_REF + || GET_CODE (disp) == LABEL_REF)) + return false; } return true; diff -Naur gcc-4.8.1.orig/gcc/config/i386/sse.md gcc-4.8.1/gcc/config/i386/sse.md --- gcc-4.8.1.orig/gcc/config/i386/sse.md 2013-04-29 17:16:04.000000000 -0500 +++ gcc-4.8.1/gcc/config/i386/sse.md 2013-08-14 09:09:59.468272000 -0500 @@ -3603,7 +3603,7 @@ (vec_select:V4SF (vec_concat:V8SF (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0") - (match_operand:V4SF 2 "nonimmediate_operand" " x,x,m,x,x")) + (match_operand:V4SF 2 "nonimmediate_operand" " x,x,m,m,x")) (parallel [(const_int 0) (const_int 1) (const_int 4) @@ -7758,9 +7758,17 @@ (mem:V16QI (match_dup 0))] UNSPEC_MASKMOV))] "TARGET_SSE2" - "%vmaskmovdqu\t{%2, %1|%1, %2}" +{ + /* We can't use %^ here due to ASM_OUTPUT_OPCODE processing + that requires %v to be at the beginning of the opcode name. */ + if (Pmode != word_mode) + fputs ("\taddr32", asm_out_file); + return "%vmaskmovdqu\t{%2, %1|%1, %2}"; +} [(set_attr "type" "ssemov") (set_attr "prefix_data16" "1") + (set (attr "length_address") + (symbol_ref ("Pmode != word_mode"))) ;; The implicit %rdi operand confuses default length_vex computation. (set (attr "length_vex") (symbol_ref ("3 + REX_SSE_REGNO_P (REGNO (operands[2]))"))) @@ -7808,26 +7816,18 @@ "mwait" [(set_attr "length" "3")]) -(define_insn "sse3_monitor" - [(unspec_volatile [(match_operand:SI 0 "register_operand" "a") - (match_operand:SI 1 "register_operand" "c") - (match_operand:SI 2 "register_operand" "d")] - UNSPECV_MONITOR)] - "TARGET_SSE3 && !TARGET_64BIT" - "monitor\t%0, %1, %2" - [(set_attr "length" "3")]) - -(define_insn "sse3_monitor64_" +(define_insn "sse3_monitor_" [(unspec_volatile [(match_operand:P 0 "register_operand" "a") (match_operand:SI 1 "register_operand" "c") (match_operand:SI 2 "register_operand" "d")] UNSPECV_MONITOR)] - "TARGET_SSE3 && TARGET_64BIT" + "TARGET_SSE3" ;; 64bit version is "monitor %rax,%rcx,%rdx". But only lower 32bits in ;; RCX and RDX are used. Since 32bit register operands are implicitly ;; zero extended to 64bit, we only need to set up 32bit registers. - "monitor" - [(set_attr "length" "3")]) + "%^monitor" + [(set (attr "length") + (symbol_ref ("(Pmode != word_mode) + 3")))]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; diff -Naur gcc-4.8.1.orig/gcc/config/i386/x86-64.h gcc-4.8.1/gcc/config/i386/x86-64.h --- gcc-4.8.1.orig/gcc/config/i386/x86-64.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/i386/x86-64.h 2013-08-23 05:01:34.440607000 -0500 @@ -103,3 +103,6 @@ #undef TARGET_ASM_UNIQUE_SECTION #define TARGET_ASM_UNIQUE_SECTION x86_64_elf_unique_section + +#undef TARGET_SECTION_TYPE_FLAGS +#define TARGET_SECTION_TYPE_FLAGS x86_64_elf_section_type_flags diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/default64.h gcc-4.8.1/gcc/config/rs6000/default64.h --- gcc-4.8.1.orig/gcc/config/rs6000/default64.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/default64.h 2013-06-18 20:18:38.348158000 -0500 @@ -18,5 +18,10 @@ along with GCC; see the file COPYING3. If not see . */ +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_64BIT | MASK_LITTLE_ENDIAN) +#else #undef TARGET_DEFAULT #define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_64BIT) +#endif diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/dfp.md gcc-4.8.1/gcc/config/rs6000/dfp.md --- gcc-4.8.1.orig/gcc/config/rs6000/dfp.md 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/dfp.md 2013-08-19 12:55:50.687548000 -0500 @@ -394,11 +394,14 @@ "") (define_insn "*negtd2_fpr" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d") + (neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))] "TARGET_HARD_FLOAT && TARGET_FPRS" - "fneg %0,%1" - [(set_attr "type" "fp")]) + "@ + fneg %0,%1 + fneg %0,%1\;fmr %L0,%L1" + [(set_attr "type" "fp") + (set_attr "length" "4,8")]) (define_expand "abstd2" [(set (match_operand:TD 0 "gpc_reg_operand" "") diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/linux64.h gcc-4.8.1/gcc/config/rs6000/linux64.h --- gcc-4.8.1.orig/gcc/config/rs6000/linux64.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/linux64.h 2013-06-18 20:18:38.348158000 -0500 @@ -180,20 +180,14 @@ #endif #define ASM_SPEC32 "-a32 \ -%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \ -%{memb} %{!memb: %{msdata=eabi: -memb}} \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{mcall-freebsd: -mbig} \ - %{mcall-i960-old: -mlittle} \ - %{mcall-linux: -mbig} \ - %{mcall-netbsd: -mbig} \ -}}}}" +%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \ +%{memb|msdata=eabi: -memb}" #define ASM_SPEC64 "-a64" #define ASM_SPEC_COMMON "%(asm_cpu) \ -%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \ -%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}" +%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \ + ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN) #undef SUBSUBTARGET_EXTRA_SPECS #define SUBSUBTARGET_EXTRA_SPECS \ @@ -212,10 +206,6 @@ #ifndef RS6000_BI_ARCH -/* 64-bit PowerPC Linux is always big-endian. */ -#undef OPTION_LITTLE_ENDIAN -#define OPTION_LITTLE_ENDIAN 0 - /* 64-bit PowerPC Linux always has a TOC. */ #undef TARGET_TOC #define TARGET_TOC 1 @@ -376,12 +366,30 @@ #define GNU_USER_DYNAMIC_LINKER64 \ CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64) +#undef DEFAULT_ASM_ENDIAN +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#define DEFAULT_ASM_ENDIAN " -mlittle" +#define LINK_OS_LINUX_EMUL32 ENDIAN_SELECT(" -m elf32ppclinux", \ + " -m elf32lppclinux", \ + " -m elf32lppclinux") +#define LINK_OS_LINUX_EMUL64 ENDIAN_SELECT(" -m elf64ppc", \ + " -m elf64lppc", \ + " -m elf64lppc") +#else +#define DEFAULT_ASM_ENDIAN " -mbig" +#define LINK_OS_LINUX_EMUL32 ENDIAN_SELECT(" -m elf32ppclinux", \ + " -m elf32lppclinux", \ + " -m elf32ppclinux") +#define LINK_OS_LINUX_EMUL64 ENDIAN_SELECT(" -m elf64ppc", \ + " -m elf64lppc", \ + " -m elf64ppc") +#endif -#define LINK_OS_LINUX_SPEC32 "-m elf32ppclinux %{!shared: %{!static: \ +#define LINK_OS_LINUX_SPEC32 LINK_OS_LINUX_EMUL32 " %{!shared: %{!static: \ %{rdynamic:-export-dynamic} \ -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}}" -#define LINK_OS_LINUX_SPEC64 "-m elf64ppc %{!shared: %{!static: \ +#define LINK_OS_LINUX_SPEC64 LINK_OS_LINUX_EMUL64 " %{!shared: %{!static: \ %{rdynamic:-export-dynamic} \ -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "}}" diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/linuxaltivec.h gcc-4.8.1/gcc/config/rs6000/linuxaltivec.h --- gcc-4.8.1.orig/gcc/config/rs6000/linuxaltivec.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/linuxaltivec.h 2013-06-18 20:18:38.348158000 -0500 @@ -20,8 +20,13 @@ . */ /* Override rs6000.h and sysv4.h definition. */ +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_ALTIVEC | MASK_LITTLE_ENDIAN) +#else #undef TARGET_DEFAULT #define TARGET_DEFAULT MASK_ALTIVEC +#endif #undef SUBSUBTARGET_OVERRIDE_OPTIONS #define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1 diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/linux.h gcc-4.8.1/gcc/config/rs6000/linux.h --- gcc-4.8.1.orig/gcc/config/rs6000/linux.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/linux.h 2013-06-18 20:18:38.348158000 -0500 @@ -79,6 +79,24 @@ #undef LINK_OS_DEFAULT_SPEC #define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" +#undef DEFAULT_ASM_ENDIAN +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#define DEFAULT_ASM_ENDIAN " -mlittle" +#define LINK_OS_LINUX_EMUL ENDIAN_SELECT(" -m elf32ppclinux", \ + " -m elf32lppclinux", \ + " -m elf32lppclinux") +#else +#define DEFAULT_ASM_ENDIAN " -mbig" +#define LINK_OS_LINUX_EMUL ENDIAN_SELECT(" -m elf32ppclinux", \ + " -m elf32lppclinux", \ + " -m elf32ppclinux") +#endif + +#undef LINK_OS_LINUX_SPEC +#define LINK_OS_LINUX_SPEC LINK_OS_LINUX_EMUL " %{!shared: %{!static: \ + %{rdynamic:-export-dynamic} \ + -dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}" + #define LINK_GCC_C_SEQUENCE_SPEC \ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/linuxspe.h gcc-4.8.1/gcc/config/rs6000/linuxspe.h --- gcc-4.8.1.orig/gcc/config/rs6000/linuxspe.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/linuxspe.h 2013-06-18 20:18:38.348158000 -0500 @@ -20,8 +20,13 @@ . */ /* Override rs6000.h and sysv4.h definition. */ +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_STRICT_ALIGN | MASK_LITTLE_ENDIAN) +#else #undef TARGET_DEFAULT #define TARGET_DEFAULT MASK_STRICT_ALIGN +#endif #undef ASM_DEFAULT_SPEC #define ASM_DEFAULT_SPEC "-mppc -mspe -me500" diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/predicates.md gcc-4.8.1/gcc/config/rs6000/predicates.md --- gcc-4.8.1.orig/gcc/config/rs6000/predicates.md 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/predicates.md 2013-06-23 19:59:24.817984000 -0500 @@ -464,9 +464,11 @@ (match_test "easy_altivec_constant (op, mode)"))) { HOST_WIDE_INT val; + int elt; if (mode == V2DImode || mode == V2DFmode) return 0; - val = const_vector_elt_as_int (op, GET_MODE_NUNITS (mode) - 1); + elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0; + val = const_vector_elt_as_int (op, elt); val = ((val & 0xff) ^ 0x80) - 0x80; return EASY_VECTOR_15_ADD_SELF (val); }) @@ -478,9 +480,11 @@ (match_test "easy_altivec_constant (op, mode)"))) { HOST_WIDE_INT val; + int elt; if (mode == V2DImode || mode == V2DFmode) return 0; - val = const_vector_elt_as_int (op, GET_MODE_NUNITS (mode) - 1); + elt = BYTES_BIG_ENDIAN ? GET_MODE_NUNITS (mode) - 1 : 0; + val = const_vector_elt_as_int (op, elt); return EASY_VECTOR_MSB (val, GET_MODE_INNER (mode)); }) diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/rs6000.c gcc-4.8.1/gcc/config/rs6000/rs6000.c --- gcc-4.8.1.orig/gcc/config/rs6000/rs6000.c 2013-05-09 20:54:06.000000000 -0500 +++ gcc-4.8.1/gcc/config/rs6000/rs6000.c 2013-08-19 20:05:10.274596000 -0500 @@ -2190,7 +2190,8 @@ int reg_size2 = reg_size; /* TFmode/TDmode always takes 2 registers, even in VSX. */ - if (m == TDmode || m == TFmode) + if (TARGET_VSX && VSX_REG_CLASS_P (c) + && (m == TDmode || m == TFmode)) reg_size2 = UNITS_PER_FP_WORD; rs6000_class_max_nregs[m][c] @@ -4239,7 +4240,7 @@ bitsize = GET_MODE_BITSIZE (inner); mask = GET_MODE_MASK (inner); - val = const_vector_elt_as_int (op, nunits - 1); + val = const_vector_elt_as_int (op, BYTES_BIG_ENDIAN ? nunits - 1 : 0); splat_val = val; msb_val = val > 0 ? 0 : -1; @@ -4279,7 +4280,7 @@ for (i = 0; i < nunits - 1; ++i) { HOST_WIDE_INT desired_val; - if (((i + 1) & (step - 1)) == 0) + if (((BYTES_BIG_ENDIAN ? i + 1 : i) & (step - 1)) == 0) desired_val = val; else desired_val = msb_val; @@ -4364,13 +4365,13 @@ { enum machine_mode mode = GET_MODE (op); int nunits = GET_MODE_NUNITS (mode); - rtx last = CONST_VECTOR_ELT (op, nunits - 1); + rtx val = CONST_VECTOR_ELT (op, BYTES_BIG_ENDIAN ? nunits - 1 : 0); unsigned step = nunits / 4; unsigned copies = 1; /* Start with a vspltisw. */ if (vspltis_constant (op, step, copies)) - return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last)); + return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, val)); /* Then try with a vspltish. */ if (step == 1) @@ -4379,7 +4380,7 @@ step >>= 1; if (vspltis_constant (op, step, copies)) - return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last)); + return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, val)); /* And finally a vspltisb. */ if (step == 1) @@ -4388,7 +4389,7 @@ step >>= 1; if (vspltis_constant (op, step, copies)) - return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last)); + return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, val)); gcc_unreachable (); } @@ -9066,19 +9067,20 @@ && cfun->va_list_gpr_size) { int nregs = GP_ARG_NUM_REG - first_reg_offset; + int n_gpr; if (va_list_gpr_counter_field) { /* V4 va_list_gpr_size counts number of registers needed. */ - if (nregs > cfun->va_list_gpr_size) - nregs = cfun->va_list_gpr_size; + n_gpr = cfun->va_list_gpr_size; } else { /* char * va_list instead counts number of bytes needed. */ - if (nregs > cfun->va_list_gpr_size / reg_size) - nregs = cfun->va_list_gpr_size / reg_size; + n_gpr = (cfun->va_list_gpr_size + reg_size - 1) / reg_size; } + if (nregs > n_gpr) + nregs = n_gpr; mem = gen_rtx_MEM (BLKmode, plus_constant (Pmode, save_area, @@ -16900,8 +16902,9 @@ shift = gen_reg_rtx (SImode); addr = gen_lowpart (SImode, addr); emit_insn (gen_rlwinm (shift, addr, GEN_INT (3), GEN_INT (shift_mask))); - shift = expand_simple_binop (SImode, XOR, shift, GEN_INT (shift_mask), - shift, 1, OPTAB_LIB_WIDEN); + if (WORDS_BIG_ENDIAN) + shift = expand_simple_binop (SImode, XOR, shift, GEN_INT (shift_mask), + shift, 1, OPTAB_LIB_WIDEN); *pshift = shift; /* Mask for insertion. */ @@ -19957,8 +19960,7 @@ HOST_WIDE_INT offset; if (!(strategy & SAVE_INLINE_GPRS)) - ool_adjust = 8 * (info->first_gp_reg_save - - (FIRST_SAVRES_REGISTER + 1)); + ool_adjust = 8 * (info->first_gp_reg_save - FIRST_SAVED_GP_REGNO); offset = info->spe_gp_save_offset + frame_off - ool_adjust; spe_save_area_ptr = gen_rtx_REG (Pmode, 11); save_off = frame_off - offset; @@ -21200,8 +21202,7 @@ anew to every function. */ if (!restoring_GPRs_inline) - ool_adjust = 8 * (info->first_gp_reg_save - - (FIRST_SAVRES_REGISTER + 1)); + ool_adjust = 8 * (info->first_gp_reg_save - FIRST_SAVED_GP_REGNO); frame_reg_rtx = gen_rtx_REG (Pmode, 11); emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx, GEN_INT (info->spe_gp_save_offset @@ -22151,20 +22152,22 @@ if (TARGET_64BIT) { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs (DOUBLE_INT_ASM_OP, file); else fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],", k[0] & 0xffffffff, k[1] & 0xffffffff, k[2] & 0xffffffff, k[3] & 0xffffffff); fprintf (file, "0x%lx%08lx,0x%lx%08lx\n", - k[0] & 0xffffffff, k[1] & 0xffffffff, - k[2] & 0xffffffff, k[3] & 0xffffffff); + k[WORDS_BIG_ENDIAN ? 0 : 1] & 0xffffffff, + k[WORDS_BIG_ENDIAN ? 1 : 0] & 0xffffffff, + k[WORDS_BIG_ENDIAN ? 2 : 3] & 0xffffffff, + k[WORDS_BIG_ENDIAN ? 3 : 2] & 0xffffffff); return; } else { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs ("\t.long ", file); else fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],", @@ -22191,18 +22194,19 @@ if (TARGET_64BIT) { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs (DOUBLE_INT_ASM_OP, file); else fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0] & 0xffffffff, k[1] & 0xffffffff); fprintf (file, "0x%lx%08lx\n", - k[0] & 0xffffffff, k[1] & 0xffffffff); + k[WORDS_BIG_ENDIAN ? 0 : 1] & 0xffffffff, + k[WORDS_BIG_ENDIAN ? 1 : 0] & 0xffffffff); return; } else { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs ("\t.long ", file); else fprintf (file, "\t.tc FD_%lx_%lx[TC],", @@ -22226,16 +22230,19 @@ if (TARGET_64BIT) { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs (DOUBLE_INT_ASM_OP, file); else fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff); - fprintf (file, "0x%lx00000000\n", l & 0xffffffff); + if (WORDS_BIG_ENDIAN) + fprintf (file, "0x%lx00000000\n", l & 0xffffffff); + else + fprintf (file, "0x%lx\n", l & 0xffffffff); return; } else { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs ("\t.long ", file); else fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff); @@ -22267,9 +22274,8 @@ } #endif - /* TOC entries are always Pmode-sized, but since this - is a bigendian machine then if we're putting smaller - integer constants in the TOC we have to pad them. + /* TOC entries are always Pmode-sized, so when big-endian + smaller integer constants in the TOC need to be padded. (This is still a win over putting the constants in a separate constant pool, because then we'd have to have both a TOC entry _and_ the actual constant.) @@ -22280,7 +22286,7 @@ /* It would be easy to make this work, but it doesn't now. */ gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode)); - if (POINTER_SIZE > GET_MODE_BITSIZE (mode)) + if (WORDS_BIG_ENDIAN && POINTER_SIZE > GET_MODE_BITSIZE (mode)) { #if HOST_BITS_PER_WIDE_INT == 32 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode), @@ -22295,7 +22301,7 @@ if (TARGET_64BIT) { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs (DOUBLE_INT_ASM_OP, file); else fprintf (file, "\t.tc ID_%lx_%lx[TC],", @@ -22308,7 +22314,7 @@ { if (POINTER_SIZE < GET_MODE_BITSIZE (mode)) { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs ("\t.long ", file); else fprintf (file, "\t.tc ID_%lx_%lx[TC],", @@ -22318,7 +22324,7 @@ } else { - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs ("\t.long ", file); else fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff); @@ -22356,7 +22362,7 @@ gcc_unreachable (); } - if (TARGET_MINIMAL_TOC) + if (TARGET_ELF || TARGET_MINIMAL_TOC) fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file); else { diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/rs6000.h gcc-4.8.1/gcc/config/rs6000/rs6000.h --- gcc-4.8.1.orig/gcc/config/rs6000/rs6000.h 2013-05-06 18:33:49.000000000 -0500 +++ gcc-4.8.1/gcc/config/rs6000/rs6000.h 2013-06-18 20:18:38.348158000 -0500 @@ -662,6 +662,11 @@ instructions for them. Might as well be consistent with bits and bytes. */ #define WORDS_BIG_ENDIAN 1 +/* This says that for the IBM long double the larger magnitude double + comes first. It's really a two element double array, and arrays + don't index differently between little- and big-endian. */ +#define LONG_DOUBLE_LARGE_FIRST 1 + #define MAX_BITS_PER_WORD 64 /* Width of a word, in units (bytes). */ @@ -2289,6 +2294,13 @@ /* How to align the given loop. */ #define LOOP_ALIGN(LABEL) rs6000_loop_align(LABEL) +/* Alignment guaranteed by __builtin_malloc. */ +/* FIXME: 128-bit alignment is guaranteed by glibc for TARGET_64BIT. + However, specifying the stronger guarantee currently leads to + a regression in SPEC CPU2006 437.leslie3d. The stronger + guarantee should be implemented here once that's fixed. */ +#define MALLOC_ABI_ALIGNMENT (64) + /* Pick up the return address upon entry to a procedure. Used for dwarf2 unwind information. This also enables the table driven mechanism. */ diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/rs6000.md gcc-4.8.1/gcc/config/rs6000/rs6000.md --- gcc-4.8.1.orig/gcc/config/rs6000/rs6000.md 2013-02-07 02:04:58.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/rs6000.md 2013-06-18 20:18:38.348158000 -0500 @@ -1990,6 +1990,8 @@ [(set_attr "length" "4,4,12") (set_attr "type" "load,store,*")]) +;; We are always BITS_BIG_ENDIAN, so the (const_int 16) below is +;; correct for -mlittle as well as -mbig. (define_split [(set (match_operand:HI 0 "gpc_reg_operand" "") (bswap:HI (match_operand:HI 1 "gpc_reg_operand" ""))) @@ -2043,6 +2045,8 @@ [(set_attr "length" "4,4,12") (set_attr "type" "load,store,*")]) +;; We are always BITS_BIG_ENDIAN, so the bit positions below in +;; zero_extract insns do not change for -mlittle. (define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") (bswap:SI (match_operand:SI 1 "gpc_reg_operand" "")))] @@ -2125,8 +2129,10 @@ rtx op2 = operands[2]; rtx op3 = operands[3]; rtx op4 = operands[4]; - rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, 4); - rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode, 4); + rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, + BYTES_BIG_ENDIAN ? 4 : 0); + rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode, + BYTES_BIG_ENDIAN ? 4 : 0); rtx addr1; rtx addr2; rtx word_high; @@ -2186,8 +2192,10 @@ rtx src = operands[1]; rtx op2 = operands[2]; rtx op3 = operands[3]; - rtx src_si = simplify_gen_subreg (SImode, src, DImode, 4); - rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 4); + rtx src_si = simplify_gen_subreg (SImode, src, DImode, + BYTES_BIG_ENDIAN ? 4 : 0); + rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, + BYTES_BIG_ENDIAN ? 4 : 0); rtx addr1; rtx addr2; rtx word_high; @@ -2221,16 +2229,14 @@ { word_high = change_address (dest, SImode, addr1); word_low = change_address (dest, SImode, addr2); - emit_insn (gen_bswapsi2 (word_high, src_si)); - emit_insn (gen_bswapsi2 (word_low, op3_si)); } else { word_high = change_address (dest, SImode, addr2); word_low = change_address (dest, SImode, addr1); - emit_insn (gen_bswapsi2 (word_low, src_si)); - emit_insn (gen_bswapsi2 (word_high, op3_si)); } + emit_insn (gen_bswapsi2 (word_high, src_si)); + emit_insn (gen_bswapsi2 (word_low, op3_si)); }") (define_split @@ -2247,10 +2253,11 @@ rtx src = operands[1]; rtx op2 = operands[2]; rtx op3 = operands[3]; - rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, 4); - rtx src_si = simplify_gen_subreg (SImode, src, DImode, 4); - rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, 4); - rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 4); + int lo_off = BYTES_BIG_ENDIAN ? 4 : 0; + rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off); + rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off); + rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off); + rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off); emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32))); emit_insn (gen_bswapsi2 (dest_si, src_si)); @@ -2275,15 +2282,15 @@ [(const_int 0)] " { - rtx dest = operands[0]; - rtx src = operands[1]; - rtx op2 = operands[2]; - rtx dest_hi = simplify_gen_subreg (SImode, dest, DImode, 0); - rtx dest_lo = simplify_gen_subreg (SImode, dest, DImode, 4); + rtx dest = operands[0]; + rtx src = operands[1]; + rtx op2 = operands[2]; + rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); + rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); rtx addr1; rtx addr2; - rtx word_high; - rtx word_low; + rtx word1; + rtx word2; addr1 = XEXP (src, 0); if (GET_CODE (addr1) == PLUS) @@ -2308,19 +2315,11 @@ addr2 = gen_rtx_PLUS (SImode, op2, addr1); } - if (BYTES_BIG_ENDIAN) - { - word_high = change_address (src, SImode, addr1); - word_low = change_address (src, SImode, addr2); - } - else - { - word_high = change_address (src, SImode, addr2); - word_low = change_address (src, SImode, addr1); - } + word1 = change_address (src, SImode, addr1); + word2 = change_address (src, SImode, addr2); - emit_insn (gen_bswapsi2 (dest_hi, word_low)); - emit_insn (gen_bswapsi2 (dest_lo, word_high)); + emit_insn (gen_bswapsi2 (dest2, word1)); + emit_insn (gen_bswapsi2 (dest1, word2)); }") (define_split @@ -2331,15 +2330,15 @@ [(const_int 0)] " { - rtx dest = operands[0]; - rtx src = operands[1]; - rtx op2 = operands[2]; - rtx src_high = simplify_gen_subreg (SImode, src, DImode, 0); - rtx src_low = simplify_gen_subreg (SImode, src, DImode, 4); + rtx dest = operands[0]; + rtx src = operands[1]; + rtx op2 = operands[2]; + rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); + rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); rtx addr1; rtx addr2; - rtx word_high; - rtx word_low; + rtx word1; + rtx word2; addr1 = XEXP (dest, 0); if (GET_CODE (addr1) == PLUS) @@ -2364,19 +2363,11 @@ addr2 = gen_rtx_PLUS (SImode, op2, addr1); } - if (BYTES_BIG_ENDIAN) - { - word_high = change_address (dest, SImode, addr1); - word_low = change_address (dest, SImode, addr2); - } - else - { - word_high = change_address (dest, SImode, addr2); - word_low = change_address (dest, SImode, addr1); - } + word1 = change_address (dest, SImode, addr1); + word2 = change_address (dest, SImode, addr2); - emit_insn (gen_bswapsi2 (word_high, src_low)); - emit_insn (gen_bswapsi2 (word_low, src_high)); + emit_insn (gen_bswapsi2 (word2, src1)); + emit_insn (gen_bswapsi2 (word1, src2)); }") (define_split @@ -2387,15 +2378,15 @@ [(const_int 0)] " { - rtx dest = operands[0]; - rtx src = operands[1]; - rtx src_high = simplify_gen_subreg (SImode, src, DImode, 0); - rtx src_low = simplify_gen_subreg (SImode, src, DImode, 4); - rtx dest_high = simplify_gen_subreg (SImode, dest, DImode, 0); - rtx dest_low = simplify_gen_subreg (SImode, dest, DImode, 4); + rtx dest = operands[0]; + rtx src = operands[1]; + rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); + rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); + rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); + rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); - emit_insn (gen_bswapsi2 (dest_high, src_low)); - emit_insn (gen_bswapsi2 (dest_low, src_high)); + emit_insn (gen_bswapsi2 (dest1, src2)); + emit_insn (gen_bswapsi2 (dest2, src1)); }") (define_insn "mulsi3" @@ -4682,6 +4673,41 @@ "frsqrtes %0,%1" [(set_attr "type" "fp")]) +;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in +;; builtins.c and optabs.c that are not correct for IBM long double +;; when little-endian. +(define_expand "signbittf2" + [(set (match_dup 2) + (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" ""))) + (set (match_dup 3) + (subreg:DI (match_dup 2) 0)) + (set (match_dup 4) + (match_dup 5)) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (match_dup 6))] + "!TARGET_IEEEQUAD + && TARGET_HARD_FLOAT + && (TARGET_FPRS || TARGET_E500_DOUBLE) + && TARGET_LONG_DOUBLE_128" +{ + operands[2] = gen_reg_rtx (DFmode); + operands[3] = gen_reg_rtx (DImode); + if (TARGET_POWERPC64) + { + operands[4] = gen_reg_rtx (DImode); + operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63)); + operands[6] = gen_rtx_SUBREG (SImode, operands[4], + WORDS_BIG_ENDIAN ? 4 : 0); + } + else + { + operands[4] = gen_reg_rtx (SImode); + operands[5] = gen_rtx_SUBREG (SImode, operands[3], + WORDS_BIG_ENDIAN ? 0 : 4); + operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31)); + } +}) + (define_expand "copysign3" [(set (match_dup 3) (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" ""))) @@ -6210,10 +6236,25 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r") (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "M,i")))] - "TARGET_32BIT && !TARGET_POWERPC64 && WORDS_BIG_ENDIAN" - "@ - srawi %0,%1,31\;srawi %L0,%1,%h2 - srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2" + "!TARGET_POWERPC64" + "* +{ + switch (which_alternative) + { + default: + gcc_unreachable (); + case 0: + if (WORDS_BIG_ENDIAN) + return \"srawi %0,%1,31\;srawi %L0,%1,%h2\"; + else + return \"srawi %L0,%L1,31\;srawi %0,%L1,%h2\"; + case 1: + if (WORDS_BIG_ENDIAN) + return \"srwi %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;srawi %0,%1,%h2\"; + else + return \"srwi %0,%1,%h2\;insrwi %0,%L1,%h2,0\;srawi %L0,%L1,%h2\"; + } +}" [(set_attr "type" "two,three") (set_attr "length" "8,12")]) @@ -7064,13 +7105,12 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "") (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")))] - "WORDS_BIG_ENDIAN" + "" " { if (TARGET_POWERPC64) ; - else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT - && WORDS_BIG_ENDIAN) + else if (GET_CODE (operands[2]) == CONST_INT) { emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2])); DONE; @@ -8277,8 +8317,8 @@ "&& reload_completed" [(pc)] { - const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; - const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); + const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; + const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word), operands[1]); emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word), @@ -8507,8 +8547,8 @@ && TARGET_LONG_DOUBLE_128" " { - const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); - const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; + const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); + const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; operands[3] = gen_reg_rtx (DFmode); operands[4] = gen_reg_rtx (CCFPmode); operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word); @@ -11609,8 +11649,8 @@ (match_dup 13)] { REAL_VALUE_TYPE rv; - const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; - const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); + const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; + const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word); operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word); diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/rtems.h gcc-4.8.1/gcc/config/rs6000/rtems.h --- gcc-4.8.1.orig/gcc/config/rs6000/rtems.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/rtems.h 2013-07-31 07:59:09.970550000 -0500 @@ -34,6 +34,9 @@ } \ while (0) +#undef TARGET_LIBGCC_SDATA_SECTION +#define TARGET_LIBGCC_SDATA_SECTION ".sdata" + #undef CPP_OS_DEFAULT_SPEC #define CPP_OS_DEFAULT_SPEC "%(cpp_os_rtems)" diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/spe.md gcc-4.8.1/gcc/config/rs6000/spe.md --- gcc-4.8.1.orig/gcc/config/rs6000/spe.md 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/spe.md 2013-06-18 20:18:38.348158000 -0500 @@ -2604,8 +2604,8 @@ && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128" " { - const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); - const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; + const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); + const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; operands[3] = gen_reg_rtx (DFmode); operands[4] = gen_reg_rtx (CCFPmode); operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word); @@ -2627,8 +2627,8 @@ && TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128" " { - const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); - const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; + const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); + const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; operands[3] = gen_reg_rtx (DFmode); operands[4] = gen_reg_rtx (CCFPmode); operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word); diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/sysv4.h gcc-4.8.1/gcc/config/rs6000/sysv4.h --- gcc-4.8.1.orig/gcc/config/rs6000/sysv4.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/sysv4.h 2013-06-18 20:18:38.348158000 -0500 @@ -187,12 +187,6 @@ rs6000_abi_name); \ } \ \ - if (rs6000_current_abi == ABI_AIX && TARGET_LITTLE_ENDIAN) \ - { \ - rs6000_isa_flags &= ~OPTION_MASK_LITTLE_ENDIAN; \ - error ("-mcall-aixdesc must be big endian"); \ - } \ - \ if (TARGET_SECURE_PLT != secure_plt) \ { \ error ("-msecure-plt not supported by your assembler"); \ @@ -523,19 +517,24 @@ while (0) #endif +/* Select one of BIG_OPT, LITTLE_OPT or DEFAULT_OPT depending + on various -mbig, -mlittle and -mcall- options. */ +#define ENDIAN_SELECT(BIG_OPT, LITTLE_OPT, DEFAULT_OPT) \ +"%{mlittle|mlittle-endian:" LITTLE_OPT ";" \ + "mbig|mbig-endian:" BIG_OPT ";" \ + "mcall-aixdesc|mcall-freebsd|mcall-netbsd|" \ + "mcall-openbsd|mcall-linux:" BIG_OPT ";" \ + "mcall-i960-old:" LITTLE_OPT ";" \ + ":" DEFAULT_OPT "}" + +#define DEFAULT_ASM_ENDIAN " -mbig" + #undef ASM_SPEC #define ASM_SPEC "%(asm_cpu) \ %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \ %{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \ -%{memb|msdata=eabi: -memb} \ -%{mlittle|mlittle-endian:-mlittle; \ - mbig|mbig-endian :-mbig; \ - mcall-aixdesc | \ - mcall-freebsd | \ - mcall-netbsd | \ - mcall-openbsd | \ - mcall-linux :-mbig; \ - mcall-i960-old :-mlittle}" +%{memb|msdata=eabi: -memb}" \ +ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN) #define CC1_ENDIAN_BIG_SPEC "" @@ -553,17 +552,10 @@ #endif /* Pass -G xxx to the compiler and set correct endian mode. */ -#define CC1_SPEC "%{G*} %(cc1_cpu) \ -%{mlittle|mlittle-endian: %(cc1_endian_little); \ - mbig |mbig-endian : %(cc1_endian_big); \ - mcall-aixdesc | \ - mcall-freebsd | \ - mcall-netbsd | \ - mcall-openbsd | \ - mcall-linux : -mbig %(cc1_endian_big); \ - mcall-i960-old : -mlittle %(cc1_endian_little); \ - : %(cc1_endian_default)} \ -%{meabi: %{!mcall-*: -mcall-sysv }} \ +#define CC1_SPEC "%{G*} %(cc1_cpu)" \ + ENDIAN_SELECT(" %(cc1_endian_big)", " %(cc1_endian_little)", \ + " %(cc1_endian_default)") \ +"%{meabi: %{!mcall-*: -mcall-sysv }} \ %{!meabi: %{!mno-eabi: \ %{mrelocatable: -meabi } \ %{mcall-freebsd: -mno-eabi } \ @@ -607,11 +599,8 @@ %{symbolic:-Bsymbolic -G -dy -z text }" /* Override the default target of the linker. */ -#define LINK_TARGET_SPEC "\ -%{mlittle: --oformat elf32-powerpcle } %{mlittle-endian: --oformat elf32-powerpcle } \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{mcall-i960-old: --oformat elf32-powerpcle} \ - }}}}" +#define LINK_TARGET_SPEC \ + ENDIAN_SELECT("", " --oformat elf32-powerpcle", "") /* Any specific OS flags. */ #define LINK_OS_SPEC "\ diff -Naur gcc-4.8.1.orig/gcc/config/rs6000/sysv4le.h gcc-4.8.1/gcc/config/rs6000/sysv4le.h --- gcc-4.8.1.orig/gcc/config/rs6000/sysv4le.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/rs6000/sysv4le.h 2013-06-18 20:18:38.348158000 -0500 @@ -25,12 +25,12 @@ #undef CC1_ENDIAN_DEFAULT_SPEC #define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_little)" +#undef DEFAULT_ASM_ENDIAN +#define DEFAULT_ASM_ENDIAN " -mlittle" + #undef LINK_TARGET_SPEC -#define LINK_TARGET_SPEC "\ -%{mbig: --oformat elf32-powerpc } %{mbig-endian: --oformat elf32-powerpc } \ -%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ - %{mcall-linux: --oformat elf32-powerpc} \ - }}}}" +#define LINK_TARGET_SPEC \ + ENDIAN_SELECT(" --oformat elf32-powerpc", "", "") #undef MULTILIB_DEFAULTS #define MULTILIB_DEFAULTS { "mlittle", "mcall-sysv" } diff -Naur gcc-4.8.1.orig/gcc/config/s390/htmintrin.h gcc-4.8.1/gcc/config/s390/htmintrin.h --- gcc-4.8.1.orig/gcc/config/s390/htmintrin.h 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/config/s390/htmintrin.h 2013-08-14 14:44:27.951575000 -0500 @@ -0,0 +1,57 @@ +/* GNU compiler hardware transactional execution intrinsics + Copyright (C) 2013 Free Software Foundation, Inc. + Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.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 +. */ + +#ifndef _HTMINTRIN_H +#define _HTMINTRIN_H + + +/* Condition codes generated by tbegin */ +#define _HTM_TBEGIN_STARTED 0 +#define _HTM_TBEGIN_INDETERMINATE 1 +#define _HTM_TBEGIN_TRANSIENT 2 +#define _HTM_TBEGIN_PERSISTENT 3 + +/* The abort codes below this threshold are reserved for machine + use. */ +#define _HTM_FIRST_USER_ABORT_CODE 256 + +/* The transaction diagnostic block is it is defined in the Principles + of Operation chapter 5-91. */ + +struct __htm_tdb { + unsigned char format; /* 0 */ + unsigned char flags; + unsigned char reserved1[4]; + unsigned short nesting_depth; + unsigned long long abort_code; /* 8 */ + unsigned long long conflict_token; /* 16 */ + unsigned long long atia; /* 24 */ + unsigned char eaid; /* 32 */ + unsigned char dxc; + unsigned char reserved2[2]; + unsigned int program_int_id; + unsigned long long exception_id; /* 40 */ + unsigned long long bea; /* 48 */ + unsigned char reserved3[72]; /* 56 */ + unsigned long long gprs[16]; /* 128 */ +} __attribute__((__packed__, __aligned__ (8))); + + +#endif /* _HTMINTRIN_H */ diff -Naur gcc-4.8.1.orig/gcc/config/s390/htmxlintrin.h gcc-4.8.1/gcc/config/s390/htmxlintrin.h --- gcc-4.8.1.orig/gcc/config/s390/htmxlintrin.h 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/config/s390/htmxlintrin.h 2013-08-14 14:44:27.951575000 -0500 @@ -0,0 +1,182 @@ +/* XL compiler hardware transactional execution intrinsics + Copyright (C) 2013 Free Software Foundation, Inc. + Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.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 +. */ + +#ifndef _HTMXLINTRIN_H +#define _HTMXLINTRIN_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These intrinsics are being made available for compatibility with + the IBM XL compiler. For documentation please see the "z/OS XL + C/C++ Programming Guide" publically available on the web. */ + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_simple_begin () +{ + return __builtin_tbegin_nofloat (0); +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_begin (void* const tdb) +{ + return __builtin_tbegin_nofloat (tdb); +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_end () +{ + return __builtin_tend (); +} + +extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_abort () +{ + return __builtin_tabort (_HTM_FIRST_USER_ABORT_CODE); +} + +extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_named_abort (unsigned char const code) +{ + return __builtin_tabort ((int)_HTM_FIRST_USER_ABORT_CODE + code); +} + +extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_non_transactional_store (void* const addr, long long const value) +{ + __builtin_non_tx_store ((uint64_t*)addr, (uint64_t)value); +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_nesting_depth (void* const tdb_ptr) +{ + int depth = __builtin_tx_nesting_depth (); + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + if (depth != 0) + return depth; + + if (tdb->format == 0) + return 0; + return tdb->nesting_depth; +} + +/* Transaction failure diagnostics */ + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_user_abort (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + if (tdb->format == 0) + return 0; + + return !!(tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE); +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_named_user_abort (void* const tdb_ptr, unsigned char* code) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + if (tdb->format == 0) + return 0; + + if (tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE) + { + *code = tdb->abort_code - _HTM_FIRST_USER_ABORT_CODE; + return 1; + } + return 0; +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_illegal (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return (tdb->format == 0 + && (tdb->abort_code == 4 /* unfiltered program interruption */ + || tdb->abort_code == 11 /* restricted instruction */)); +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_footprint_exceeded (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return (tdb->format == 0 + && (tdb->abort_code == 7 /* fetch overflow */ + || tdb->abort_code == 8 /* store overflow */)); +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_nested_too_deep (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return tdb->format == 0 && tdb->abort_code == 13; /* depth exceeded */ +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_conflict (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return (tdb->format == 0 + && (tdb->abort_code == 9 /* fetch conflict */ + || tdb->abort_code == 10 /* store conflict */)); +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_failure_persistent (long const result) +{ + return result == _HTM_TBEGIN_PERSISTENT; +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_failure_address (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; +#ifdef __s390x__ + return tdb->atia; +#else + return tdb->atia & 0xffffffff; +#endif +} + +extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__TM_failure_code (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return tdb->abort_code; +} + +#ifdef __cplusplus +} +#endif + +#endif /* _HTMXLINTRIN_H */ diff -Naur gcc-4.8.1.orig/gcc/config/s390/predicates.md gcc-4.8.1/gcc/config/s390/predicates.md --- gcc-4.8.1.orig/gcc/config/s390/predicates.md 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/s390/predicates.md 2013-08-02 10:41:10.548493000 -0500 @@ -176,7 +176,11 @@ { if (GET_CODE (XEXP (op, 0)) != REG || REGNO (XEXP (op, 0)) != CC_REGNUM - || XEXP (op, 1) != const0_rtx) + || (XEXP (op, 1) != const0_rtx + && !(CONST_INT_P (XEXP (op, 1)) + && GET_MODE (XEXP (op, 0)) == CCRAWmode + && INTVAL (XEXP (op, 1)) >= 0 + && INTVAL (XEXP (op, 1)) <= 15))) return false; return (s390_branch_condition_mask (op) >= 0); @@ -224,7 +228,11 @@ if (GET_CODE (XEXP (op, 0)) != REG || REGNO (XEXP (op, 0)) != CC_REGNUM - || XEXP (op, 1) != const0_rtx) + || (XEXP (op, 1) != const0_rtx + && !(CONST_INT_P (XEXP (op, 1)) + && GET_MODE (XEXP (op, 0)) == CCRAWmode + && INTVAL (XEXP (op, 1)) >= 0 + && INTVAL (XEXP (op, 1)) <= 15))) return false; switch (GET_MODE (XEXP (op, 0))) diff -Naur gcc-4.8.1.orig/gcc/config/s390/s390.c gcc-4.8.1/gcc/config/s390/s390.c --- gcc-4.8.1.orig/gcc/config/s390/s390.c 2013-04-08 02:55:57.000000000 -0500 +++ gcc-4.8.1/gcc/config/s390/s390.c 2013-08-02 10:41:10.548493000 -0500 @@ -367,6 +367,10 @@ const char *some_ld_name; bool has_landing_pad_p; + + /* True if the current function may contain a tbegin clobbering + FPRs. */ + bool tbegin_p; }; /* Few accessor macros for struct cfun->machine->s390_frame_layout. */ @@ -824,9 +828,9 @@ *op1 = constm1_rtx; } - /* Remove redundant UNSPEC_CCU_TO_INT conversions if possible. */ + /* Remove redundant UNSPEC_STRCMPCC_TO_INT conversions if possible. */ if (GET_CODE (*op0) == UNSPEC - && XINT (*op0, 1) == UNSPEC_CCU_TO_INT + && XINT (*op0, 1) == UNSPEC_STRCMPCC_TO_INT && XVECLEN (*op0, 0) == 1 && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode && GET_CODE (XVECEXP (*op0, 0, 0)) == REG @@ -852,25 +856,35 @@ } } - /* Remove redundant UNSPEC_CCZ_TO_INT conversions if possible. */ + /* Remove redundant UNSPEC_CC_TO_INT conversions if possible. */ if (GET_CODE (*op0) == UNSPEC - && XINT (*op0, 1) == UNSPEC_CCZ_TO_INT + && XINT (*op0, 1) == UNSPEC_CC_TO_INT && XVECLEN (*op0, 0) == 1 - && GET_MODE (XVECEXP (*op0, 0, 0)) == CCZmode && GET_CODE (XVECEXP (*op0, 0, 0)) == REG && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM - && *op1 == const0_rtx) + && CONST_INT_P (*op1)) { enum rtx_code new_code = UNKNOWN; - switch (*code) + switch (GET_MODE (XVECEXP (*op0, 0, 0))) { - case EQ: new_code = EQ; break; - case NE: new_code = NE; break; - default: break; + case CCZmode: + case CCRAWmode: + switch (*code) + { + case EQ: new_code = EQ; break; + case NE: new_code = NE; break; + default: break; + } + break; + default: break; } if (new_code != UNKNOWN) { + /* For CCRAWmode put the required cc mask into the second + operand. */ + if (GET_MODE (XVECEXP (*op0, 0, 0)) == CCRAWmode) + *op1 = gen_rtx_CONST_INT (VOIDmode, 1 << (3 - INTVAL (*op1))); *op0 = XVECEXP (*op0, 0, 0); *code = new_code; } @@ -942,10 +956,11 @@ const0_rtx); } -/* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an - unconditional jump, else a conditional jump under condition COND. */ +/* Emit a jump instruction to TARGET and return it. If COND is + NULL_RTX, emit an unconditional jump, else a conditional jump under + condition COND. */ -void +rtx s390_emit_jump (rtx target, rtx cond) { rtx insn; @@ -955,7 +970,7 @@ target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, target, pc_rtx); insn = gen_rtx_SET (VOIDmode, pc_rtx, target); - emit_jump_insn (insn); + return emit_jump_insn (insn); } /* Return branch condition mask to implement a branch @@ -971,7 +986,10 @@ gcc_assert (GET_CODE (XEXP (code, 0)) == REG); gcc_assert (REGNO (XEXP (code, 0)) == CC_REGNUM); - gcc_assert (XEXP (code, 1) == const0_rtx); + gcc_assert (XEXP (code, 1) == const0_rtx + || (GET_MODE (XEXP (code, 0)) == CCRAWmode + && CONST_INT_P (XEXP (code, 1)))); + switch (GET_MODE (XEXP (code, 0))) { @@ -1145,6 +1163,17 @@ } break; + case CCRAWmode: + switch (GET_CODE (code)) + { + case EQ: + return INTVAL (XEXP (code, 1)); + case NE: + return (INTVAL (XEXP (code, 1))) ^ 0xf; + default: + gcc_unreachable (); + } + default: return -1; } @@ -1204,7 +1233,9 @@ if (GET_CODE (XEXP (code, 0)) == REG && REGNO (XEXP (code, 0)) == CC_REGNUM - && XEXP (code, 1) == const0_rtx) + && (XEXP (code, 1) == const0_rtx + || (GET_MODE (XEXP (code, 0)) == CCRAWmode + && CONST_INT_P (XEXP (code, 1))))) mask = s390_branch_condition_mask (code); else mask = s390_compare_and_branch_condition_mask (code); @@ -1602,6 +1633,11 @@ if (!(target_flags_explicit & MASK_HARD_DFP) && TARGET_DFP) target_flags |= MASK_HARD_DFP; + /* Enable hardware transactions if available and not explicitly + disabled by user. E.g. with -m31 -march=zEC12 -mzarch */ + if (!(target_flags_explicit & MASK_OPT_HTM) && TARGET_CPU_HTM && TARGET_ZARCH) + target_flags |= MASK_OPT_HTM; + if (TARGET_HARD_DFP && !TARGET_DFP) { if (target_flags_explicit & MASK_HARD_DFP) @@ -7341,11 +7377,11 @@ if (GET_CODE (setreg) == SUBREG) { rtx inner = SUBREG_REG (setreg); - if (!GENERAL_REG_P (inner)) + if (!GENERAL_REG_P (inner) && !FP_REG_P (inner)) return; regno = subreg_regno (setreg); } - else if (GENERAL_REG_P (setreg)) + else if (GENERAL_REG_P (setreg) || FP_REG_P (setreg)) regno = REGNO (setreg); else return; @@ -7368,13 +7404,13 @@ rtx cur_insn; unsigned int i; - memset (regs_ever_clobbered, 0, 16 * sizeof (int)); + memset (regs_ever_clobbered, 0, 32 * sizeof (int)); /* For non-leaf functions we have to consider all call clobbered regs to be clobbered. */ if (!crtl->is_leaf) { - for (i = 0; i < 16; i++) + for (i = 0; i < 32; i++) regs_ever_clobbered[i] = call_really_used_regs[i]; } @@ -7396,7 +7432,7 @@ See expand_builtin_unwind_init. For regs_ever_live this is done by reload. */ if (cfun->has_nonlocal_label) - for (i = 0; i < 16; i++) + for (i = 0; i < 32; i++) if (!call_really_used_regs[i]) regs_ever_clobbered[i] = 1; @@ -7462,17 +7498,6 @@ { int i, j; - /* fprs 8 - 15 are call saved for 64 Bit ABI. */ - cfun_frame_layout.fpr_bitmap = 0; - cfun_frame_layout.high_fprs = 0; - if (TARGET_64BIT) - for (i = 24; i < 32; i++) - if (df_regs_ever_live_p (i) && !global_regs[i]) - { - cfun_set_fpr_bit (i - 16); - cfun_frame_layout.high_fprs++; - } - /* Find first and last gpr to be saved. We trust regs_ever_live data, except that we don't save and restore global registers. @@ -7481,6 +7506,28 @@ s390_regs_ever_clobbered (clobbered_regs); + /* fprs 8 - 15 are call saved for 64 Bit ABI. */ + if (!epilogue_completed) + { + cfun_frame_layout.fpr_bitmap = 0; + cfun_frame_layout.high_fprs = 0; + if (TARGET_64BIT) + for (i = 24; i < 32; i++) + /* During reload we have to use the df_regs_ever_live infos + since reload is marking FPRs used as spill slots there as + live before actually making the code changes. Without + this we fail during elimination offset verification. */ + if ((clobbered_regs[i] + || (df_regs_ever_live_p (i) + && (reload_in_progress + || crtl->saves_all_registers))) + && !global_regs[i]) + { + cfun_set_fpr_bit (i - 16); + cfun_frame_layout.high_fprs++; + } + } + for (i = 0; i < 16; i++) clobbered_regs[i] = clobbered_regs[i] && !global_regs[i] && !fixed_regs[i]; @@ -7731,7 +7778,7 @@ { HOST_WIDE_INT frame_size; int base_used; - int clobbered_regs[16]; + int clobbered_regs[32]; /* On S/390 machines, we may need to perform branch splitting, which will require both base and return address register. We have no @@ -7766,6 +7813,157 @@ while (frame_size != cfun_frame_layout.frame_size); } +/* Remove the FPR clobbers from a tbegin insn if it can be proven that + the TX is nonescaping. A transaction is considered escaping if + there is at least one path from tbegin returning CC0 to the + function exit block without an tend. + + The check so far has some limitations: + - only single tbegin/tend BBs are supported + - the first cond jump after tbegin must separate the CC0 path from ~CC0 + - when CC is copied to a GPR and the CC0 check is done with the GPR + this is not supported +*/ + +static void +s390_optimize_nonescaping_tx (void) +{ + const unsigned int CC0 = 1 << 3; + basic_block tbegin_bb = NULL; + basic_block tend_bb = NULL; + basic_block bb; + rtx insn; + bool result = true; + int bb_index; + rtx tbegin_insn = NULL_RTX; + + if (!cfun->machine->tbegin_p) + return; + + for (bb_index = 0; bb_index < n_basic_blocks; bb_index++) + { + bb = BASIC_BLOCK (bb_index); + + FOR_BB_INSNS (bb, insn) + { + rtx ite, cc, pat, target; + unsigned HOST_WIDE_INT mask; + + if (!INSN_P (insn) || INSN_CODE (insn) <= 0) + continue; + + pat = PATTERN (insn); + + if (GET_CODE (pat) == PARALLEL) + pat = XVECEXP (pat, 0, 0); + + if (GET_CODE (pat) != SET + || GET_CODE (SET_SRC (pat)) != UNSPEC_VOLATILE) + continue; + + if (XINT (SET_SRC (pat), 1) == UNSPECV_TBEGIN) + { + rtx tmp; + + tbegin_insn = insn; + + /* Just return if the tbegin doesn't have clobbers. */ + if (GET_CODE (PATTERN (insn)) != PARALLEL) + return; + + if (tbegin_bb != NULL) + return; + + /* Find the next conditional jump. */ + for (tmp = NEXT_INSN (insn); + tmp != NULL_RTX; + tmp = NEXT_INSN (tmp)) + { + if (reg_set_p (gen_rtx_REG (CCmode, CC_REGNUM), tmp)) + return; + if (!JUMP_P (tmp)) + continue; + + ite = SET_SRC (PATTERN (tmp)); + if (GET_CODE (ite) != IF_THEN_ELSE) + continue; + + cc = XEXP (XEXP (ite, 0), 0); + if (!REG_P (cc) || !CC_REGNO_P (REGNO (cc)) + || GET_MODE (cc) != CCRAWmode + || GET_CODE (XEXP (XEXP (ite, 0), 1)) != CONST_INT) + return; + + if (bb->succs->length () != 2) + return; + + mask = INTVAL (XEXP (XEXP (ite, 0), 1)); + if (GET_CODE (XEXP (ite, 0)) == NE) + mask ^= 0xf; + + if (mask == CC0) + target = XEXP (ite, 1); + else if (mask == (CC0 ^ 0xf)) + target = XEXP (ite, 2); + else + return; + + { + edge_iterator ei; + edge e1, e2; + + ei = ei_start (bb->succs); + e1 = ei_safe_edge (ei); + ei_next (&ei); + e2 = ei_safe_edge (ei); + + if (e2->flags & EDGE_FALLTHRU) + { + e2 = e1; + e1 = ei_safe_edge (ei); + } + + if (!(e1->flags & EDGE_FALLTHRU)) + return; + + tbegin_bb = (target == pc_rtx) ? e1->dest : e2->dest; + } + if (tmp == BB_END (bb)) + break; + } + } + + if (XINT (SET_SRC (pat), 1) == UNSPECV_TEND) + { + if (tend_bb != NULL) + return; + tend_bb = bb; + } + } + } + + /* Either we successfully remove the FPR clobbers here or we are not + able to do anything for this TX. Both cases don't qualify for + another look. */ + cfun->machine->tbegin_p = false; + + if (tbegin_bb == NULL || tend_bb == NULL) + return; + + calculate_dominance_info (CDI_POST_DOMINATORS); + result = dominated_by_p (CDI_POST_DOMINATORS, tbegin_bb, tend_bb); + free_dominance_info (CDI_POST_DOMINATORS); + + if (!result) + return; + + PATTERN (tbegin_insn) = XVECEXP (PATTERN (tbegin_insn), 0, 0); + INSN_CODE (tbegin_insn) = -1; + df_insn_rescan (tbegin_insn); + + return; +} + /* Update frame layout. Recompute actual register save data based on current info and update regs_ever_live for the special registers. May be called multiple times, but may never cause *more* registers @@ -7774,7 +7972,7 @@ static void s390_update_frame_layout (void) { - int clobbered_regs[16]; + int clobbered_regs[32]; s390_register_info (clobbered_regs); @@ -8204,8 +8402,10 @@ int offset; int next_fpr = 0; - /* Complete frame layout. */ + /* Try to get rid of the FPR clobbers. */ + s390_optimize_nonescaping_tx (); + /* Complete frame layout. */ s390_update_frame_layout (); /* Annotate all constant pool references to let the scheduler know @@ -9353,6 +9553,291 @@ return build_va_arg_indirect_ref (addr); } +/* Emit rtl for the tbegin or tbegin_retry (RETRY != NULL_RTX) + expanders. + DEST - Register location where CC will be stored. + TDB - Pointer to a 256 byte area where to store the transaction. + diagnostic block. NULL if TDB is not needed. + RETRY - Retry count value. If non-NULL a retry loop for CC2 + is emitted + CLOBBER_FPRS_P - If true clobbers for all FPRs are emitted as part + of the tbegin instruction pattern. */ + +void +s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p) +{ + const int CC0 = 1 << 3; + const int CC1 = 1 << 2; + const int CC3 = 1 << 0; + rtx abort_label = gen_label_rtx (); + rtx leave_label = gen_label_rtx (); + rtx retry_reg = gen_reg_rtx (SImode); + rtx retry_label = NULL_RTX; + rtx jump; + rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1); + + if (retry != NULL_RTX) + { + emit_move_insn (retry_reg, retry); + retry_label = gen_label_rtx (); + emit_label (retry_label); + } + + if (clobber_fprs_p) + emit_insn (gen_tbegin_1 (tdb, + gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK))); + else + emit_insn (gen_tbegin_nofloat_1 (tdb, + gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK))); + + jump = s390_emit_jump (abort_label, + gen_rtx_NE (VOIDmode, + gen_rtx_REG (CCRAWmode, CC_REGNUM), + gen_rtx_CONST_INT (VOIDmode, CC0))); + + JUMP_LABEL (jump) = abort_label; + LABEL_NUSES (abort_label) = 1; + add_reg_note (jump, REG_BR_PROB, very_unlikely); + + /* Initialize CC return value. */ + emit_move_insn (dest, const0_rtx); + + s390_emit_jump (leave_label, NULL_RTX); + LABEL_NUSES (leave_label) = 1; + emit_barrier (); + + /* Abort handler code. */ + + emit_label (abort_label); + if (retry != NULL_RTX) + { + rtx count = gen_reg_rtx (SImode); + jump = s390_emit_jump (leave_label, + gen_rtx_EQ (VOIDmode, + gen_rtx_REG (CCRAWmode, CC_REGNUM), + gen_rtx_CONST_INT (VOIDmode, CC1 | CC3))); + LABEL_NUSES (leave_label) = 2; + add_reg_note (jump, REG_BR_PROB, very_unlikely); + + /* CC2 - transient failure. Perform retry with ppa. */ + emit_move_insn (count, retry); + emit_insn (gen_subsi3 (count, count, retry_reg)); + emit_insn (gen_tx_assist (count)); + jump = emit_jump_insn (gen_doloop_si64 (retry_label, + retry_reg, + retry_reg)); + JUMP_LABEL (jump) = retry_label; + LABEL_NUSES (retry_label) = 1; + } + + emit_move_insn (dest, gen_rtx_UNSPEC (SImode, + gen_rtvec (1, gen_rtx_REG (CCRAWmode, + CC_REGNUM)), + UNSPEC_CC_TO_INT)); + emit_label (leave_label); +} + +/* Builtins. */ + +enum s390_builtin +{ + S390_BUILTIN_TBEGIN, + S390_BUILTIN_TBEGIN_NOFLOAT, + S390_BUILTIN_TBEGIN_RETRY, + S390_BUILTIN_TBEGIN_RETRY_NOFLOAT, + S390_BUILTIN_TBEGINC, + S390_BUILTIN_TEND, + S390_BUILTIN_TABORT, + S390_BUILTIN_NON_TX_STORE, + S390_BUILTIN_TX_NESTING_DEPTH, + S390_BUILTIN_TX_ASSIST, + + S390_BUILTIN_max +}; + +static enum insn_code const code_for_builtin[S390_BUILTIN_max] = { + CODE_FOR_tbegin, + CODE_FOR_tbegin_nofloat, + CODE_FOR_tbegin_retry, + CODE_FOR_tbegin_retry_nofloat, + CODE_FOR_tbeginc, + CODE_FOR_tend, + CODE_FOR_tabort, + CODE_FOR_ntstg, + CODE_FOR_etnd, + CODE_FOR_tx_assist +}; + +static void +s390_init_builtins (void) +{ + tree ftype, uint64_type; + + /* void foo (void) */ + ftype = build_function_type_list (void_type_node, NULL_TREE); + add_builtin_function ("__builtin_tbeginc", ftype, S390_BUILTIN_TBEGINC, + BUILT_IN_MD, NULL, NULL_TREE); + + /* void foo (int) */ + ftype = build_function_type_list (void_type_node, integer_type_node, + NULL_TREE); + add_builtin_function ("__builtin_tabort", ftype, + S390_BUILTIN_TABORT, BUILT_IN_MD, NULL, NULL_TREE); + add_builtin_function ("__builtin_tx_assist", ftype, + S390_BUILTIN_TX_ASSIST, BUILT_IN_MD, NULL, NULL_TREE); + + /* int foo (void *) */ + ftype = build_function_type_list (integer_type_node, ptr_type_node, NULL_TREE); + add_builtin_function ("__builtin_tbegin", ftype, S390_BUILTIN_TBEGIN, + BUILT_IN_MD, NULL, NULL_TREE); + add_builtin_function ("__builtin_tbegin_nofloat", ftype, + S390_BUILTIN_TBEGIN_NOFLOAT, + BUILT_IN_MD, NULL, NULL_TREE); + + /* int foo (void *, int) */ + ftype = build_function_type_list (integer_type_node, ptr_type_node, + integer_type_node, NULL_TREE); + add_builtin_function ("__builtin_tbegin_retry", ftype, + S390_BUILTIN_TBEGIN_RETRY, + BUILT_IN_MD, + NULL, NULL_TREE); + add_builtin_function ("__builtin_tbegin_retry_nofloat", ftype, + S390_BUILTIN_TBEGIN_RETRY_NOFLOAT, + BUILT_IN_MD, + NULL, NULL_TREE); + + /* int foo (void) */ + ftype = build_function_type_list (integer_type_node, NULL_TREE); + add_builtin_function ("__builtin_tx_nesting_depth", ftype, + S390_BUILTIN_TX_NESTING_DEPTH, + BUILT_IN_MD, NULL, NULL_TREE); + add_builtin_function ("__builtin_tend", ftype, + S390_BUILTIN_TEND, BUILT_IN_MD, NULL, NULL_TREE); + + /* void foo (uint64_t *, uint64_t) */ + if (TARGET_64BIT) + uint64_type = long_unsigned_type_node; + else + uint64_type = long_long_unsigned_type_node; + + ftype = build_function_type_list (void_type_node, + build_pointer_type (uint64_type), + uint64_type, NULL_TREE); + add_builtin_function ("__builtin_non_tx_store", ftype, + S390_BUILTIN_NON_TX_STORE, + BUILT_IN_MD, NULL, NULL_TREE); +} + +/* 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). + SUBTARGET may be used as the target for computing one of EXP's operands. + IGNORE is nonzero if the value is to be ignored. */ + +static rtx +s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + int ignore ATTRIBUTE_UNUSED) +{ +#define MAX_ARGS 2 + + tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); + unsigned int fcode = DECL_FUNCTION_CODE (fndecl); + enum insn_code icode; + rtx op[MAX_ARGS], pat; + int arity; + bool nonvoid; + tree arg; + call_expr_arg_iterator iter; + + if (fcode >= S390_BUILTIN_max) + internal_error ("bad builtin fcode"); + icode = code_for_builtin[fcode]; + if (icode == 0) + internal_error ("bad builtin fcode"); + + if (!TARGET_HTM) + error ("Transactional execution builtins not enabled (-mhtm)\n"); + + /* Set a flag in the machine specific cfun part in order to support + saving/restoring of FPRs. */ + if (fcode == S390_BUILTIN_TBEGIN || fcode == S390_BUILTIN_TBEGIN_RETRY) + cfun->machine->tbegin_p = true; + + nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node; + + arity = 0; + FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) + { + const struct insn_operand_data *insn_op; + + if (arg == error_mark_node) + return NULL_RTX; + if (arity >= MAX_ARGS) + return NULL_RTX; + + insn_op = &insn_data[icode].operand[arity + nonvoid]; + + op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL); + + if (!(*insn_op->predicate) (op[arity], insn_op->mode)) + { + if (insn_op->predicate == memory_operand) + { + /* Don't move a NULL pointer into a register. Otherwise + we have to rely on combine being able to move it back + in order to get an immediate 0 in the instruction. */ + if (op[arity] != const0_rtx) + op[arity] = copy_to_mode_reg (Pmode, op[arity]); + op[arity] = gen_rtx_MEM (insn_op->mode, op[arity]); + } + else + op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]); + } + + arity++; + } + + if (nonvoid) + { + enum machine_mode tmode = insn_data[icode].operand[0].mode; + if (!target + || GET_MODE (target) != tmode + || !(*insn_data[icode].operand[0].predicate) (target, tmode)) + target = gen_reg_rtx (tmode); + } + + switch (arity) + { + case 0: + pat = GEN_FCN (icode) (target); + break; + case 1: + if (nonvoid) + pat = GEN_FCN (icode) (target, op[0]); + else + pat = GEN_FCN (icode) (op[0]); + break; + case 2: + if (nonvoid) + pat = GEN_FCN (icode) (target, op[0], op[1]); + else + pat = GEN_FCN (icode) (op[0], op[1]); + break; + default: + gcc_unreachable (); + } + if (!pat) + return NULL_RTX; + emit_insn (pat); + + if (nonvoid) + return target; + else + return const0_rtx; +} + + /* Output assembly code for the trampoline template to stdio stream FILE. @@ -11008,6 +11493,11 @@ #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY s390_return_in_memory +#undef TARGET_INIT_BUILTINS +#define TARGET_INIT_BUILTINS s390_init_builtins +#undef TARGET_EXPAND_BUILTIN +#define TARGET_EXPAND_BUILTIN s390_expand_builtin + #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA s390_output_addr_const_extra diff -Naur gcc-4.8.1.orig/gcc/config/s390/s390.h gcc-4.8.1/gcc/config/s390/s390.h --- gcc-4.8.1.orig/gcc/config/s390/s390.h 2013-03-05 06:02:06.000000000 -0600 +++ gcc-4.8.1/gcc/config/s390/s390.h 2013-08-02 10:41:10.548493000 -0500 @@ -34,7 +34,8 @@ PF_DFP = 16, PF_Z10 = 32, PF_Z196 = 64, - PF_ZEC12 = 128 + PF_ZEC12 = 128, + PF_TX = 256 }; /* This is necessary to avoid a warning about comparing different enum @@ -61,6 +62,8 @@ (s390_arch_flags & PF_Z196) #define TARGET_CPU_ZEC12 \ (s390_arch_flags & PF_ZEC12) +#define TARGET_CPU_HTM \ + (s390_arch_flags & PF_TX) /* These flags indicate that the generated code should run on a cpu providing the respective hardware facility when run in @@ -78,6 +81,7 @@ (TARGET_ZARCH && TARGET_CPU_Z196) #define TARGET_ZEC12 \ (TARGET_ZARCH && TARGET_CPU_ZEC12) +#define TARGET_HTM (TARGET_OPT_HTM) #define TARGET_AVOID_CMP_AND_BRANCH (s390_tune == PROCESSOR_2817_Z196) @@ -93,23 +97,25 @@ #define TARGET_TPF 0 /* Target CPU builtins. */ -#define TARGET_CPU_CPP_BUILTINS() \ - do \ - { \ - builtin_assert ("cpu=s390"); \ - builtin_assert ("machine=s390"); \ - builtin_define ("__s390__"); \ - if (TARGET_ZARCH) \ - builtin_define ("__zarch__"); \ - if (TARGET_64BIT) \ - builtin_define ("__s390x__"); \ - if (TARGET_LONG_DOUBLE_128) \ - builtin_define ("__LONG_DOUBLE_128__"); \ - } \ +#define TARGET_CPU_CPP_BUILTINS() \ + do \ + { \ + builtin_assert ("cpu=s390"); \ + builtin_assert ("machine=s390"); \ + builtin_define ("__s390__"); \ + if (TARGET_ZARCH) \ + builtin_define ("__zarch__"); \ + if (TARGET_64BIT) \ + builtin_define ("__s390x__"); \ + if (TARGET_LONG_DOUBLE_128) \ + builtin_define ("__LONG_DOUBLE_128__"); \ + if (TARGET_HTM) \ + builtin_define ("__HTM__"); \ + } \ while (0) #ifdef DEFAULT_TARGET_64BIT -#define TARGET_DEFAULT (MASK_64BIT | MASK_ZARCH | MASK_HARD_DFP) +#define TARGET_DEFAULT (MASK_64BIT | MASK_ZARCH | MASK_HARD_DFP | MASK_OPT_HTM) #else #define TARGET_DEFAULT 0 #endif @@ -164,6 +170,11 @@ #define S390_TDC_INFINITY (S390_TDC_POSITIVE_INFINITY \ | S390_TDC_NEGATIVE_INFINITY ) +/* This is used by float.h to define the float_t and double_t data + types. For historical reasons both are double on s390 what cannot + be changed anymore. */ +#define TARGET_FLT_EVAL_METHOD 1 + /* Target machine storage layout. */ /* Everything is big-endian. */ diff -Naur gcc-4.8.1.orig/gcc/config/s390/s390intrin.h gcc-4.8.1/gcc/config/s390/s390intrin.h --- gcc-4.8.1.orig/gcc/config/s390/s390intrin.h 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/config/s390/s390intrin.h 2013-08-14 14:44:27.951575000 -0500 @@ -0,0 +1,33 @@ +/* S/390 System z specific intrinsics + Copyright (C) 2013 Free Software Foundation, Inc. + Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.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 +. */ + +#ifndef _S390INTRIN_H +#define _S390INTRIN_H + +#ifndef __s390__ + #error s390intrin.h included on wrong platform/compiler +#endif + +#ifdef __HTM__ +#include +#endif + + +#endif /* _S390INTRIN_H*/ diff -Naur gcc-4.8.1.orig/gcc/config/s390/s390.md gcc-4.8.1/gcc/config/s390/s390.md --- gcc-4.8.1.orig/gcc/config/s390/s390.md 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/s390/s390.md 2013-08-02 10:41:10.548493000 -0500 @@ -59,11 +59,17 @@ (define_c_enum "unspec" [ ; Miscellaneous UNSPEC_ROUND - UNSPEC_CCU_TO_INT - UNSPEC_CCZ_TO_INT UNSPEC_ICM UNSPEC_TIE + ; Convert CC into a str comparison result and copy it into an + ; integer register + ; cc0->0, cc1->1, cc2->-1, (cc3->-1) + UNSPEC_STRCMPCC_TO_INT + + ; Copy CC as is into the lower 2 bits of an integer register + UNSPEC_CC_TO_INT + ; GOT/PLT and lt-relative accesses UNSPEC_LTREL_OFFSET UNSPEC_LTREL_BASE @@ -138,6 +144,15 @@ ; Atomic Support UNSPECV_CAS UNSPECV_ATOMIC_OP + + ; Transactional Execution support + UNSPECV_TBEGIN + UNSPECV_TBEGINC + UNSPECV_TEND + UNSPECV_TABORT + UNSPECV_ETND + UNSPECV_NTSTG + UNSPECV_PPA ]) ;; @@ -191,6 +206,9 @@ (PFPO_OP1_TYPE_SHIFT 8) ]) +; Immediate operands for tbegin and tbeginc +(define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c +(define_constants [(TBEGINC_MASK 65288)]) ; 0xff08 ;; Instruction operand type as used in the Principles of Operation. ;; Used to determine defaults for length and other attribute values. @@ -2246,19 +2264,19 @@ (define_insn "movcc" [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T") - (match_operand:CC 1 "nonimmediate_operand" "d,d,c,R,T,d,d"))] + (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))] "" "@ lr\t%0,%1 tmh\t%1,12288 ipm\t%0 - st\t%0,%1 - sty\t%0,%1 - l\t%1,%0 - ly\t%1,%0" + l\t%0,%1 + ly\t%0,%1 + st\t%1,%0 + sty\t%1,%0" [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY") - (set_attr "type" "lr,*,*,store,store,load,load") - (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_rec,z10_rec,z10_fwd_A3,z10_fwd_A3") + (set_attr "type" "lr,*,*,load,load,store,store") + (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec") (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")]) ; @@ -2578,7 +2596,7 @@ (use (reg:SI 0))]) (parallel [(set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CCU_TO_INT)) + (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT)) (clobber (reg:CC CC_REGNUM))])] "" { @@ -2820,7 +2838,7 @@ (match_dup 2)] UNSPEC_TDC_INSN)) (set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))] + (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))] "TARGET_HARD_FLOAT" { operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET); @@ -2832,12 +2850,21 @@ (match_dup 2)] UNSPEC_TDC_INSN)) (set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))] + (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))] "TARGET_HARD_FLOAT" { operands[2] = GEN_INT (S390_TDC_INFINITY); }) +(define_insn_and_split "*cc_to_int" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_operand 1 "register_operand" "0")] + UNSPEC_CC_TO_INT))] + "operands != NULL" + "#" + "reload_completed" + [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))]) + ; This insn is used to generate all variants of the Test Data Class ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand ; is the register to be tested and the second one is the bit mask @@ -2853,14 +2880,6 @@ [(set_attr "op_type" "RXE") (set_attr "type" "fsimp")]) -(define_insn_and_split "*ccz_to_int" - [(set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(match_operand:CCZ 1 "register_operand" "0")] - UNSPEC_CCZ_TO_INT))] - "" - "#" - "reload_completed" - [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))]) ; @@ -3205,7 +3224,7 @@ (define_insn_and_split "cmpint" [(set (match_operand:SI 0 "register_operand" "=d") (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CCU_TO_INT)) + UNSPEC_STRCMPCC_TO_INT)) (clobber (reg:CC CC_REGNUM))] "" "#" @@ -3218,10 +3237,10 @@ (define_insn_and_split "*cmpint_cc" [(set (reg CC_REGNUM) (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CCU_TO_INT) + UNSPEC_STRCMPCC_TO_INT) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT))] + (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))] "s390_match_ccmode (insn, CCSmode)" "#" "&& reload_completed" @@ -3238,7 +3257,7 @@ (define_insn_and_split "*cmpint_sign" [(set (match_operand:DI 0 "register_operand" "=d") (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CCU_TO_INT))) + UNSPEC_STRCMPCC_TO_INT))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH" "#" @@ -3252,11 +3271,11 @@ [(set (reg CC_REGNUM) (compare (ashiftrt:DI (ashift:DI (subreg:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CCU_TO_INT) 0) + UNSPEC_STRCMPCC_TO_INT) 0) (const_int 32)) (const_int 32)) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=d") - (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT)))] + (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))] "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH" "#" "&& reload_completed" @@ -5507,7 +5526,7 @@ (if_then_else:GPR (match_operator 1 "s390_comparison" [(match_operand 2 "cc_reg_operand" " c,c, c, c, c, c, c") - (const_int 0)]) + (match_operand 5 "const_int_operand" "")]) (match_operand:GPR 3 "nonimmediate_operand" " d,0,QS, 0, d, 0,QS") (match_operand:GPR 4 "nonimmediate_operand" " 0,d, 0,QS, 0, d,QS")))] "TARGET_Z196" @@ -7907,7 +7926,8 @@ (define_insn "*cjump_64" [(set (pc) (if_then_else - (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) + (match_operator 1 "s390_comparison" [(reg CC_REGNUM) + (match_operand 2 "const_int_operand" "")]) (label_ref (match_operand 0 "" "")) (pc)))] "TARGET_CPU_ZARCH" @@ -7926,7 +7946,8 @@ (define_insn "*cjump_31" [(set (pc) (if_then_else - (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) + (match_operator 1 "s390_comparison" [(reg CC_REGNUM) + (match_operand 2 "const_int_operand" "")]) (label_ref (match_operand 0 "" "")) (pc)))] "!TARGET_CPU_ZARCH" @@ -9795,3 +9816,217 @@ "cpsdr\t%0,%2,%1" [(set_attr "op_type" "RRF") (set_attr "type" "fsimp")]) + + +;; +;;- Transactional execution instructions +;; + +; This splitter helps combine to make use of CC directly when +; comparing the integer result of a tbegin builtin with a constant. +; The unspec is already removed by canonicalize_comparison. So this +; splitters only job is to turn the PARALLEL into separate insns +; again. Unfortunately this only works with the very first cc/int +; compare since combine is not able to deal with data flow across +; basic block boundaries. + +; It needs to be an insn pattern as well since combine does not apply +; the splitter directly. Combine would only use it if it actually +; would reduce the number of instructions. +(define_insn_and_split "*ccraw_to_int" + [(set (pc) + (if_then_else + (match_operator 0 "s390_eqne_operator" + [(reg:CCRAW CC_REGNUM) + (match_operand 1 "const_int_operand" "")]) + (label_ref (match_operand 2 "" "")) + (pc))) + (set (match_operand:SI 3 "register_operand" "=d") + (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] + "" + "#" + "" + [(set (match_dup 3) + (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT)) + (set (pc) + (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)]) + (label_ref (match_dup 2)) + (pc)))] + "") + +; Non-constrained transaction begin + +(define_expand "tbegin" + [(match_operand:SI 0 "register_operand" "=d") + (match_operand:BLK 1 "memory_operand" "=Q")] + "TARGET_HTM" +{ + s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true); + DONE; +}) + +(define_expand "tbegin_nofloat" + [(match_operand:SI 0 "register_operand" "=d") + (match_operand:BLK 1 "memory_operand" "=Q")] + "TARGET_HTM" +{ + s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false); + DONE; +}) + +(define_expand "tbegin_retry" + [(match_operand:SI 0 "register_operand" "=d") + (match_operand:BLK 1 "memory_operand" "=Q") + (match_operand 2 "const_int_operand")] + "TARGET_HTM" +{ + s390_expand_tbegin (operands[0], operands[1], operands[2], true); + DONE; +}) + +(define_expand "tbegin_retry_nofloat" + [(match_operand:SI 0 "register_operand" "=d") + (match_operand:BLK 1 "memory_operand" "=Q") + (match_operand 2 "const_int_operand")] + "TARGET_HTM" +{ + s390_expand_tbegin (operands[0], operands[1], operands[2], false); + DONE; +}) + +(define_insn "tbegin_1" + [(set (reg:CCRAW CC_REGNUM) + (unspec_volatile:CCRAW [(match_operand:BLK 0 "memory_operand" "=Q") + (match_operand 1 "const_int_operand" " D")] + UNSPECV_TBEGIN)) + (clobber (reg:DF 16)) + (clobber (reg:DF 17)) + (clobber (reg:DF 18)) + (clobber (reg:DF 19)) + (clobber (reg:DF 20)) + (clobber (reg:DF 21)) + (clobber (reg:DF 22)) + (clobber (reg:DF 23)) + (clobber (reg:DF 24)) + (clobber (reg:DF 25)) + (clobber (reg:DF 26)) + (clobber (reg:DF 27)) + (clobber (reg:DF 28)) + (clobber (reg:DF 29)) + (clobber (reg:DF 30)) + (clobber (reg:DF 31))] +; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is +; not supposed to be used for immediates (see genpreds.c). + "TARGET_HTM && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 0xffff" + "tbegin\t%0,%x1" + [(set_attr "op_type" "SIL")]) + +; Same as above but without the FPR clobbers +(define_insn "tbegin_nofloat_1" + [(set (reg:CCRAW CC_REGNUM) + (unspec_volatile:CCRAW [(match_operand:BLK 0 "memory_operand" "=Q") + (match_operand 1 "const_int_operand" " D")] + UNSPECV_TBEGIN))] + "TARGET_HTM && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 0xffff" + "tbegin\t%0,%x1" + [(set_attr "op_type" "SIL")]) + + +; Constrained transaction begin + +(define_expand "tbeginc" + [(set (reg:CCRAW CC_REGNUM) + (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)] + UNSPECV_TBEGINC))] + "TARGET_HTM" + "") + +(define_insn "*tbeginc_1" + [(set (reg:CCRAW CC_REGNUM) + (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")] + UNSPECV_TBEGINC))] + "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff" + "tbeginc\t0,%x0" + [(set_attr "op_type" "SIL")]) + +; Transaction end + +(define_expand "tend" + [(set (reg:CCRAW CC_REGNUM) + (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND)) + (set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))] + "TARGET_HTM" + "") + +(define_insn "*tend_1" + [(set (reg:CCRAW CC_REGNUM) + (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))] + "TARGET_HTM" + "tend" + [(set_attr "op_type" "S")]) + +; Transaction abort + +(define_expand "tabort" + [(unspec_volatile [(match_operand 0 "shift_count_or_setmem_operand" "")] + UNSPECV_TABORT)] + "TARGET_HTM && operands != NULL" +{ + if (CONST_INT_P (operands[0]) + && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255) + { + error ("Invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC + ". Values in range 0 through 255 are reserved.", + INTVAL (operands[0])); + FAIL; + } +}) + +(define_insn "*tabort_1" + [(unspec_volatile [(match_operand 0 "shift_count_or_setmem_operand" "")] + UNSPECV_TABORT)] + "TARGET_HTM && operands != NULL" + "tabort\t%Y0" + [(set_attr "op_type" "S")]) + +; Transaction extract nesting depth + +(define_insn "etnd" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))] + "TARGET_HTM" + "etnd\t%0" + [(set_attr "op_type" "RRE")]) + +; Non-transactional store + +(define_insn "ntstg" + [(set (match_operand:DI 0 "memory_operand" "=RT") + (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")] + UNSPECV_NTSTG))] + "TARGET_HTM" + "ntstg\t%1,%0" + [(set_attr "op_type" "RXY")]) + +; Transaction perform processor assist + +(define_expand "tx_assist" + [(set (match_dup 1) (const_int 0)) + (unspec_volatile [(match_operand:SI 0 "register_operand" "d") + (match_dup 1) + (const_int 1)] + UNSPECV_PPA)] + "TARGET_HTM" +{ + operands[1] = gen_reg_rtx (SImode); +}) + +(define_insn "*ppa" + [(unspec_volatile [(match_operand:SI 0 "register_operand" "d") + (match_operand:SI 1 "register_operand" "d") + (match_operand 2 "const_int_operand" "I")] + UNSPECV_PPA)] + "TARGET_HTM && INTVAL (operands[2]) < 16" + "ppa\t%0,%1,1" + [(set_attr "op_type" "RRF")]) diff -Naur gcc-4.8.1.orig/gcc/config/s390/s390-modes.def gcc-4.8.1/gcc/config/s390/s390-modes.def --- gcc-4.8.1.orig/gcc/config/s390/s390-modes.def 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/s390/s390-modes.def 2013-08-02 10:41:10.548493000 -0500 @@ -152,6 +152,14 @@ operands were equal/unequal. The CCZ1 mode ensures the result can be effectively placed into a register. +CCRAW + +The cc mode generated by a non-compare instruction. The condition +code mask for the CC consumer is determined by the comparison operator +(only EQ and NE allowed) and the immediate value given as second +operand to the operator. For the other CC modes this value used to be +0. + */ @@ -172,3 +180,4 @@ CC_MODE (CCT1); CC_MODE (CCT2); CC_MODE (CCT3); +CC_MODE (CCRAW); diff -Naur gcc-4.8.1.orig/gcc/config/s390/s390.opt gcc-4.8.1/gcc/config/s390/s390.opt --- gcc-4.8.1.orig/gcc/config/s390/s390.opt 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/s390/s390.opt 2013-08-02 10:41:10.548493000 -0500 @@ -104,6 +104,10 @@ Target Report RejectNegative Negative(mlong-double-128) InverseMask(LONG_DOUBLE_128) Use 64-bit long double +mhtm +Target Report Mask(OPT_HTM) +Use hardware transactional execution instructions + mpacked-stack Target Report Mask(PACKED_STACK) Use packed stack layout diff -Naur gcc-4.8.1.orig/gcc/config/s390/s390-protos.h gcc-4.8.1/gcc/config/s390/s390-protos.h --- gcc-4.8.1.orig/gcc/config/s390/s390-protos.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/config/s390/s390-protos.h 2013-08-02 10:41:10.548493000 -0500 @@ -58,7 +58,7 @@ extern enum machine_mode s390_tm_ccmode (rtx, rtx, bool); extern enum machine_mode s390_select_ccmode (enum rtx_code, rtx, rtx); extern rtx s390_emit_compare (enum rtx_code, rtx, rtx); -extern void s390_emit_jump (rtx, rtx); +extern rtx s390_emit_jump (rtx, rtx); extern bool symbolic_reference_mentioned_p (rtx); extern bool tls_symbolic_reference_mentioned_p (rtx); extern bool legitimate_la_operand_p (rtx); @@ -87,6 +87,7 @@ rtx, rtx, bool); extern void s390_expand_atomic (enum machine_mode, enum rtx_code, rtx, rtx, rtx, bool); +extern void s390_expand_tbegin (rtx, rtx, rtx, bool); extern rtx s390_return_addr_rtx (int, rtx); extern rtx s390_back_chain_rtx (void); extern rtx s390_emit_call (rtx, rtx, rtx, rtx); diff -Naur gcc-4.8.1.orig/gcc/config/sh/sh.md gcc-4.8.1/gcc/config/sh/sh.md --- gcc-4.8.1.orig/gcc/config/sh/sh.md 2013-05-06 14:53:56.000000000 -0500 +++ gcc-4.8.1/gcc/config/sh/sh.md 2013-06-09 17:02:28.968408000 -0500 @@ -12073,10 +12073,10 @@ ;; FMA (fused multiply-add) patterns (define_expand "fmasf4" - [(set (match_operand:SF 0 "fp_arith_reg_operand" "") - (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "") - (match_operand:SF 2 "fp_arith_reg_operand" "") - (match_operand:SF 3 "fp_arith_reg_operand" "")))] + [(set (match_operand:SF 0 "fp_arith_reg_operand") + (fma:SF (match_operand:SF 1 "fp_arith_reg_operand") + (match_operand:SF 2 "fp_arith_reg_operand") + (match_operand:SF 3 "fp_arith_reg_operand")))] "TARGET_SH2E || TARGET_SHMEDIA_FPU" { if (TARGET_SH2E) @@ -12107,6 +12107,43 @@ "fmac.s %1, %2, %0" [(set_attr "type" "fparith_media")]) +;; For some cases such as 'a * b + a' the FMA pattern is not generated by +;; previous transformations. If FMA is generally allowed, let the combine +;; pass utilize it. +(define_insn_and_split "*fmasf4" + [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") + (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w") + (match_operand:SF 2 "fp_arith_reg_operand" "f")) + (match_operand:SF 3 "arith_reg_operand" "0"))) + (use (match_operand:PSI 4 "fpscr_operand"))] + "TARGET_SH2E && flag_fp_contract_mode != FP_CONTRACT_OFF" + "fmac %1,%2,%0" + "&& can_create_pseudo_p ()" + [(parallel [(set (match_dup 0) + (fma:SF (match_dup 1) (match_dup 2) (match_dup 3))) + (use (match_dup 4))])] +{ + /* Change 'b * a + a' into 'a * b + a'. + This is better for register allocation. */ + if (REGNO (operands[2]) == REGNO (operands[3])) + { + rtx tmp = operands[1]; + operands[1] = operands[2]; + operands[2] = tmp; + } +} + [(set_attr "type" "fp") + (set_attr "fp_mode" "single")]) + +(define_insn "*fmasf4_media" + [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") + (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f") + (match_operand:SF 2 "fp_arith_reg_operand" "f")) + (match_operand:SF 3 "fp_arith_reg_operand" "0")))] + "TARGET_SHMEDIA_FPU && flag_fp_contract_mode != FP_CONTRACT_OFF" + "fmac.s %1, %2, %0" + [(set_attr "type" "fparith_media")]) + (define_expand "divsf3" [(set (match_operand:SF 0 "arith_reg_operand" "") (div:SF (match_operand:SF 1 "arith_reg_operand" "") diff -Naur gcc-4.8.1.orig/gcc/config/sparc/sparc.c gcc-4.8.1/gcc/config/sparc/sparc.c --- gcc-4.8.1.orig/gcc/config/sparc/sparc.c 2013-04-15 03:31:12.000000000 -0500 +++ gcc-4.8.1/gcc/config/sparc/sparc.c 2013-08-02 16:42:26.734213000 -0500 @@ -11174,6 +11174,11 @@ /* Total Store Ordering: all memory transactions with store semantics are followed by an implied StoreStore. */ implied |= StoreStore; + + /* If we're not looking for a raw barrer (before+after), then atomic + operations get the benefit of being both load and store. */ + if (load_store == 3 && before_after == 1) + implied |= StoreLoad; /* FALLTHRU */ case SMM_PSO: diff -Naur gcc-4.8.1.orig/gcc/config.gcc gcc-4.8.1/gcc/config.gcc --- gcc-4.8.1.orig/gcc/config.gcc 2013-03-13 04:47:41.000000000 -0500 +++ gcc-4.8.1/gcc/config.gcc 2013-08-02 10:41:10.548493000 -0500 @@ -452,6 +452,7 @@ cpu_type=s390 need_64bit_hwint=yes extra_options="${extra_options} fused-madd.opt" + extra_headers="s390intrin.h htmintrin.h htmxlintrin.h" ;; # Note the 'l'; we need to be able to match e.g. "shle" or "shl". sh[123456789lbe]*-*-* | sh-*-*) @@ -734,6 +735,7 @@ yes) thread_file='rtems' ;; esac extra_options="${extra_options} rtems.opt" + default_use_cxa_atexit=yes use_gcc_stdint=wrap ;; *-*-uclinux*) @@ -2066,20 +2068,24 @@ extra_options="${extra_options} rs6000/sysv4.opt" tmake_file="rs6000/t-fprules rs6000/t-rtems t-rtems rs6000/t-ppccomm" ;; -powerpc-*-linux* | powerpc64-*-linux*) +powerpc*-*-linux*) tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h rs6000/sysv4.h" extra_options="${extra_options} rs6000/sysv4.opt" tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm" + case ${target} in + powerpc*le-*-*) + tm_file="${tm_file} rs6000/sysv4le.h" ;; + esac maybe_biarch=yes case ${target} in - powerpc64-*-linux*spe* | powerpc64-*-linux*paired*) + powerpc64*-*-linux*spe* | powerpc64*-*-linux*paired*) echo "*** Configuration ${target} not supported" 1>&2 exit 1 ;; - powerpc-*-linux*spe* | powerpc-*-linux*paired*) + powerpc*-*-linux*spe* | powerpc*-*-linux*paired*) maybe_biarch= ;; - powerpc64-*-linux*) + powerpc64*-*-linux*) test x$with_cpu != x || cpu_is_64bit=yes maybe_biarch=always ;; diff -Naur gcc-4.8.1.orig/gcc/config.in gcc-4.8.1/gcc/config.in --- gcc-4.8.1.orig/gcc/config.in 2013-05-31 04:09:26.000000000 -0500 +++ gcc-4.8.1/gcc/config.in 2013-06-18 20:18:38.348158000 -0500 @@ -1228,7 +1228,7 @@ #endif -/* Define if your AIX linker supports a large TOC. */ +/* Define if your PowerPC64 linker supports a large TOC. */ #ifndef USED_FOR_TARGET #undef HAVE_LD_LARGE_TOC #endif diff -Naur gcc-4.8.1.orig/gcc/configure gcc-4.8.1/gcc/configure --- gcc-4.8.1.orig/gcc/configure 2013-05-08 06:36:36.000000000 -0500 +++ gcc-4.8.1/gcc/configure 2013-06-18 20:18:38.348158000 -0500 @@ -23281,33 +23281,7 @@ tls_first_major=0 tls_first_minor=0 ;; - powerpc-*-*) - conftest_s=' - .section ".tdata","awT",@progbits - .align 2 -ld0: .space 4 -ld1: .space 4 -x1: .space 4 -x2: .space 4 -x3: .space 4 - .text - addi 3,31,ld0@got@tlsgd - bl __tls_get_addr - addi 3,31,x1@got@tlsld - bl __tls_get_addr - addi 9,3,x1@dtprel - addis 9,3,x2@dtprel@ha - addi 9,9,x2@dtprel@l - lwz 9,x3@got@tprel(31) - add 9,9,x@tls - addi 9,2,x1@tprel - addis 9,2,x2@tprel@ha - addi 9,9,x2@tprel@l' - tls_first_major=2 - tls_first_minor=14 - tls_as_opt="-a32 --fatal-warnings" - ;; - powerpc64-*-*) + powerpc64*-*-*) conftest_s=' .section ".tdata","awT",@progbits .align 3 @@ -23341,6 +23315,32 @@ tls_first_minor=14 tls_as_opt="-a64 --fatal-warnings" ;; + powerpc*-*-*) + conftest_s=' + .section ".tdata","awT",@progbits + .align 2 +ld0: .space 4 +ld1: .space 4 +x1: .space 4 +x2: .space 4 +x3: .space 4 + .text + addi 3,31,ld0@got@tlsgd + bl __tls_get_addr + addi 3,31,x1@got@tlsld + bl __tls_get_addr + addi 9,3,x1@dtprel + addis 9,3,x2@dtprel@ha + addi 9,9,x2@dtprel@l + lwz 9,x3@got@tprel(31) + add 9,9,x@tls + addi 9,2,x1@tprel + addis 9,2,x2@tprel@ha + addi 9,9,x2@tprel@l' + tls_first_major=2 + tls_first_minor=14 + tls_as_opt="-a32 --fatal-warnings" + ;; s390-*-*) conftest_s=' .section ".tdata","awT",@progbits @@ -26472,6 +26472,9 @@ case "$target:$tm_file" in powerpc64-*-freebsd* | powerpc64*-*-linux* | powerpc*-*-linux*rs6000/biarch64.h*) case "$target" in + *le-*-linux*) + emul_name="-melf64lppc" + ;; *-*-linux*) emul_name="-melf64ppc" ;; diff -Naur gcc-4.8.1.orig/gcc/configure.ac gcc-4.8.1/gcc/configure.ac --- gcc-4.8.1.orig/gcc/configure.ac 2013-05-08 06:36:36.000000000 -0500 +++ gcc-4.8.1/gcc/configure.ac 2013-06-18 20:18:38.348158000 -0500 @@ -3044,33 +3044,7 @@ tls_first_major=0 tls_first_minor=0 ;; - powerpc-*-*) - conftest_s=' - .section ".tdata","awT",@progbits - .align 2 -ld0: .space 4 -ld1: .space 4 -x1: .space 4 -x2: .space 4 -x3: .space 4 - .text - addi 3,31,ld0@got@tlsgd - bl __tls_get_addr - addi 3,31,x1@got@tlsld - bl __tls_get_addr - addi 9,3,x1@dtprel - addis 9,3,x2@dtprel@ha - addi 9,9,x2@dtprel@l - lwz 9,x3@got@tprel(31) - add 9,9,x@tls - addi 9,2,x1@tprel - addis 9,2,x2@tprel@ha - addi 9,9,x2@tprel@l' - tls_first_major=2 - tls_first_minor=14 - tls_as_opt="-a32 --fatal-warnings" - ;; - powerpc64-*-*) + powerpc64*-*-*) conftest_s=' .section ".tdata","awT",@progbits .align 3 @@ -3104,6 +3078,32 @@ tls_first_minor=14 tls_as_opt="-a64 --fatal-warnings" ;; + powerpc*-*-*) + conftest_s=' + .section ".tdata","awT",@progbits + .align 2 +ld0: .space 4 +ld1: .space 4 +x1: .space 4 +x2: .space 4 +x3: .space 4 + .text + addi 3,31,ld0@got@tlsgd + bl __tls_get_addr + addi 3,31,x1@got@tlsld + bl __tls_get_addr + addi 9,3,x1@dtprel + addis 9,3,x2@dtprel@ha + addi 9,9,x2@dtprel@l + lwz 9,x3@got@tprel(31) + add 9,9,x@tls + addi 9,2,x1@tprel + addis 9,2,x2@tprel@ha + addi 9,9,x2@tprel@l' + tls_first_major=2 + tls_first_minor=14 + tls_as_opt="-a32 --fatal-warnings" + ;; s390-*-*) conftest_s=' .section ".tdata","awT",@progbits @@ -4507,6 +4507,9 @@ case "$target:$tm_file" in powerpc64-*-freebsd* | powerpc64*-*-linux* | powerpc*-*-linux*rs6000/biarch64.h*) case "$target" in + *le-*-linux*) + emul_name="-melf64lppc" + ;; *-*-linux*) emul_name="-melf64ppc" ;; @@ -4611,7 +4614,7 @@ ]) if test x"$gcc_cv_ld_large_toc" = xyes; then AC_DEFINE(HAVE_LD_LARGE_TOC, 1, - [Define if your AIX linker supports a large TOC.]) + [Define if your PowerPC64 linker supports a large TOC.]) fi ;; esac diff -Naur gcc-4.8.1.orig/gcc/cp/call.c gcc-4.8.1/gcc/cp/call.c --- gcc-4.8.1.orig/gcc/cp/call.c 2013-05-14 07:51:17.000000000 -0500 +++ gcc-4.8.1/gcc/cp/call.c 2013-07-25 10:07:27.406614000 -0500 @@ -6195,8 +6195,8 @@ if (convs->check_narrowing) check_narrowing (totype, expr); - if (issue_conversion_warnings && (complain & tf_warning)) - expr = convert_and_check (totype, expr); + if (issue_conversion_warnings) + expr = cp_convert_and_check (totype, expr, complain); else expr = convert (totype, expr); @@ -6390,7 +6390,7 @@ push_defarg_context (fn); if (fn && DECL_TEMPLATE_INFO (fn)) - arg = tsubst_default_argument (fn, type, arg); + arg = tsubst_default_argument (fn, type, arg, complain); /* Due to: diff -Naur gcc-4.8.1.orig/gcc/cp/class.c gcc-4.8.1/gcc/cp/class.c --- gcc-4.8.1.orig/gcc/cp/class.c 2013-04-01 14:05:21.000000000 -0500 +++ gcc-4.8.1/gcc/cp/class.c 2013-07-05 05:23:08.653887000 -0500 @@ -4574,15 +4574,20 @@ 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)) + bool saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t); + + /* Avoid early exit from synthesized_method_walk (c++/57645). */ + TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = true; + + for (tree fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns)) deduce_noexcept_on_destructor (OVL_CURRENT (fns)); + + TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = saved_nontrivial_dtor; } /* Subroutine of set_one_vmethod_tm_attributes. Search base classes @@ -4833,6 +4838,44 @@ return false; } +/* TYPE is being used as a virtual base, and has a non-trivial move + assignment. Return true if this is due to there being a user-provided + move assignment in TYPE or one of its subobjects; if there isn't, then + multiple move assignment can't cause any harm. */ + +bool +vbase_has_user_provided_move_assign (tree type) +{ + /* Does the type itself have a user-provided move assignment operator? */ + for (tree fns + = lookup_fnfields_slot_nolazy (type, ansi_assopname (NOP_EXPR)); + fns; fns = OVL_NEXT (fns)) + { + tree fn = OVL_CURRENT (fns); + if (move_fn_p (fn) && user_provided_p (fn)) + return true; + } + + /* Do any of its bases? */ + tree binfo = TYPE_BINFO (type); + tree base_binfo; + for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) + if (vbase_has_user_provided_move_assign (BINFO_TYPE (base_binfo))) + return true; + + /* Or non-static data members? */ + for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) + { + if (TREE_CODE (field) == FIELD_DECL + && CLASS_TYPE_P (TREE_TYPE (field)) + && vbase_has_user_provided_move_assign (TREE_TYPE (field))) + return true; + } + + /* Seems not. */ + return false; +} + /* If default-initialization leaves part of TYPE uninitialized, returns a DECL for the field or TYPE itself (DR 253). */ diff -Naur gcc-4.8.1.orig/gcc/cp/cp-tree.h gcc-4.8.1/gcc/cp/cp-tree.h --- gcc-4.8.1.orig/gcc/cp/cp-tree.h 2013-04-24 10:42:20.000000000 -0500 +++ gcc-4.8.1/gcc/cp/cp-tree.h 2013-08-20 07:59:37.559809000 -0500 @@ -1211,17 +1211,20 @@ /* The _DECL for this _TYPE. */ #define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE))) -/* Nonzero if T is a class (or struct or union) type. Also nonzero - for template type parameters, typename types, and instantiated - template template parameters. Keep these checks in ascending code - order. */ -#define MAYBE_CLASS_TYPE_P(T) \ +/* Nonzero if T is a type that could resolve to any kind of concrete type + at instantiation time. */ +#define WILDCARD_TYPE_P(T) \ (TREE_CODE (T) == TEMPLATE_TYPE_PARM \ || TREE_CODE (T) == TYPENAME_TYPE \ || TREE_CODE (T) == TYPEOF_TYPE \ || TREE_CODE (T) == BOUND_TEMPLATE_TEMPLATE_PARM \ - || TREE_CODE (T) == DECLTYPE_TYPE \ - || CLASS_TYPE_P (T)) + || TREE_CODE (T) == DECLTYPE_TYPE) + +/* Nonzero if T is a class (or struct or union) type. Also nonzero + for template type parameters, typename types, and instantiated + template template parameters. Keep these checks in ascending code + order. */ +#define MAYBE_CLASS_TYPE_P(T) (WILDCARD_TYPE_P (T) || CLASS_TYPE_P (T)) /* Set CLASS_TYPE_P for T to VAL. T must be a class, struct, or union type. */ @@ -5057,6 +5060,7 @@ extern bool user_provided_p (tree); extern bool type_has_user_provided_constructor (tree); extern bool type_has_user_provided_default_constructor (tree); +extern bool vbase_has_user_provided_move_assign (tree); extern tree default_init_uninitialized_part (tree); extern bool trivial_default_constructor_is_constexpr (tree); extern bool type_has_constexpr_default_constructor (tree); @@ -5177,7 +5181,7 @@ extern void revert_static_member_fn (tree); extern void fixup_anonymous_aggr (tree); extern tree compute_array_index_type (tree, tree, tsubst_flags_t); -extern tree check_default_argument (tree, tree); +extern tree check_default_argument (tree, tree, tsubst_flags_t); typedef int (*walk_namespaces_fn) (tree, void *); extern int walk_namespaces (walk_namespaces_fn, void *); @@ -5452,7 +5456,8 @@ extern tree most_specialized_instantiation (tree); extern void print_candidates (tree); extern void instantiate_pending_templates (int); -extern tree tsubst_default_argument (tree, tree, tree); +extern tree tsubst_default_argument (tree, tree, tree, + tsubst_flags_t); extern tree tsubst (tree, tree, tsubst_flags_t, tree); extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree, bool, bool); @@ -5585,6 +5590,7 @@ extern void stop_deferring_access_checks (void); extern void pop_deferring_access_checks (void); extern vec *get_deferred_access_checks (void); +extern void reopen_deferring_access_checks (vec *); extern void pop_to_parent_deferring_access_checks (void); extern bool perform_access_checks (vec *, tsubst_flags_t); diff -Naur gcc-4.8.1.orig/gcc/cp/cvt.c gcc-4.8.1/gcc/cp/cvt.c --- gcc-4.8.1.orig/gcc/cp/cvt.c 2013-02-20 03:02:35.000000000 -0600 +++ gcc-4.8.1/gcc/cp/cvt.c 2013-08-20 07:59:37.559809000 -0500 @@ -620,6 +620,9 @@ if (TREE_TYPE (expr) == type) return expr; + + if (TREE_CODE (expr) == SIZEOF_EXPR) + expr = maybe_constant_value (expr); result = cp_convert (type, expr, complain); @@ -1580,17 +1583,6 @@ if (DECL_NONCONVERTING_P (cand)) continue; - if (TREE_CODE (cand) == TEMPLATE_DECL) - { - if (complain) - { - error ("ambiguous default type conversion from %qT", - basetype); - error (" candidate conversions include %qD", cand); - } - return error_mark_node; - } - candidate = non_reference (TREE_TYPE (TREE_TYPE (cand))); switch (TREE_CODE (candidate)) @@ -1624,11 +1616,23 @@ break; default: + /* A wildcard could be instantiated to match any desired + type, but we can't deduce the template argument. */ + if (WILDCARD_TYPE_P (candidate)) + win = true; break; } if (win) { + if (TREE_CODE (cand) == TEMPLATE_DECL) + { + if (complain) + error ("default type conversion can't deduce template" + " argument for %qD", cand); + return error_mark_node; + } + if (winner) { if (complain) diff -Naur gcc-4.8.1.orig/gcc/cp/decl.c gcc-4.8.1/gcc/cp/decl.c --- gcc-4.8.1.orig/gcc/cp/decl.c 2013-05-16 10:09:07.000000000 -0500 +++ gcc-4.8.1/gcc/cp/decl.c 2013-07-25 10:07:27.406614000 -0500 @@ -10878,7 +10878,7 @@ DECL, if there is no DECL available. */ tree -check_default_argument (tree decl, tree arg) +check_default_argument (tree decl, tree arg, tsubst_flags_t complain) { tree var; tree decl_type; @@ -10910,13 +10910,14 @@ A default argument expression is implicitly converted to the parameter type. */ ++cp_unevaluated_operand; - perform_implicit_conversion_flags (decl_type, arg, tf_warning_or_error, + perform_implicit_conversion_flags (decl_type, arg, complain, LOOKUP_IMPLICIT); --cp_unevaluated_operand; if (warn_zero_as_null_pointer_constant && TYPE_PTR_OR_PTRMEM_P (decl_type) && null_ptr_cst_p (arg) + && (complain & tf_warning) && maybe_warn_zero_as_null_pointer_constant (arg, input_location)) return nullptr_node; @@ -10930,10 +10931,14 @@ var = cp_walk_tree_without_duplicates (&arg, local_variable_p_walkfn, NULL); if (var) { - if (DECL_NAME (var) == this_identifier) - permerror (input_location, "default argument %qE uses %qD", arg, var); - else - error ("default argument %qE uses local variable %qD", arg, var); + if (complain & tf_warning_or_error) + { + if (DECL_NAME (var) == this_identifier) + permerror (input_location, "default argument %qE uses %qD", + arg, var); + else + error ("default argument %qE uses local variable %qD", arg, var); + } return error_mark_node; } @@ -11084,7 +11089,7 @@ if (any_error) init = NULL_TREE; else if (init && !processing_template_decl) - init = check_default_argument (decl, init); + init = check_default_argument (decl, init, tf_warning_or_error); } DECL_CHAIN (decl) = decls; diff -Naur gcc-4.8.1.orig/gcc/cp/init.c gcc-4.8.1/gcc/cp/init.c --- gcc-4.8.1.orig/gcc/cp/init.c 2013-04-25 11:25:04.000000000 -0500 +++ gcc-4.8.1/gcc/cp/init.c 2013-07-13 20:06:02.832708000 -0500 @@ -3524,6 +3524,8 @@ /* Clear out INIT so that we don't get confused below. */ init = NULL_TREE; + /* Any elements without explicit initializers get {}. */ + explicit_value_init_p = true; } else if (from_array) { diff -Naur gcc-4.8.1.orig/gcc/cp/method.c gcc-4.8.1/gcc/cp/method.c --- gcc-4.8.1.orig/gcc/cp/method.c 2013-02-12 14:47:15.000000000 -0600 +++ gcc-4.8.1/gcc/cp/method.c 2013-05-31 08:03:45.258613000 -0500 @@ -1340,7 +1340,8 @@ if (diag && assign_p && move_p && BINFO_VIRTUAL_P (base_binfo) && rval && TREE_CODE (rval) == FUNCTION_DECL - && move_fn_p (rval) && !trivial_fn_p (rval)) + && move_fn_p (rval) && !trivial_fn_p (rval) + && vbase_has_user_provided_move_assign (basetype)) warning (OPT_Wvirtual_move_assign, "defaulted move assignment for %qT calls a non-trivial " "move assignment operator for virtual base %qT", diff -Naur gcc-4.8.1.orig/gcc/cp/name-lookup.c gcc-4.8.1/gcc/cp/name-lookup.c --- gcc-4.8.1.orig/gcc/cp/name-lookup.c 2013-02-27 12:13:24.000000000 -0600 +++ gcc-4.8.1/gcc/cp/name-lookup.c 2013-08-17 20:07:02.824495000 -0500 @@ -3015,8 +3015,10 @@ if (name == error_mark_node) return false; - /* Check for invalid member names. */ - gcc_assert (TYPE_BEING_DEFINED (current_class_type)); + /* Check for invalid member names. But don't worry about a default + argument-scope lambda being pushed after the class is complete. */ + gcc_assert (TYPE_BEING_DEFINED (current_class_type) + || LAMBDA_TYPE_P (TREE_TYPE (decl))); /* Check that we're pushing into the right binding level. */ gcc_assert (current_class_type == class_binding_level->this_entity); diff -Naur gcc-4.8.1.orig/gcc/cp/parser.c gcc-4.8.1/gcc/cp/parser.c --- gcc-4.8.1.orig/gcc/cp/parser.c 2013-05-14 15:37:48.000000000 -0500 +++ gcc-4.8.1/gcc/cp/parser.c 2013-07-25 10:07:27.406614000 -0500 @@ -5438,11 +5438,18 @@ /* Restore the old message. */ parser->type_definition_forbidden_message = saved_message; + bool saved_greater_than_is_operator_p + = parser->greater_than_is_operator_p; + parser->greater_than_is_operator_p = true; + /* And the expression which is being cast. */ cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); expression = cp_parser_expression (parser, /*cast_p=*/true, & idk); cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + parser->greater_than_is_operator_p + = saved_greater_than_is_operator_p; + /* Only type conversions to integral or enumeration types can be used in constant-expressions. */ if (!cast_valid_in_integral_constant_expression_p (type) @@ -9595,10 +9602,7 @@ range_expr = error_mark_node; stmt = begin_range_for_stmt (scope, init); finish_range_for_decl (stmt, range_decl, range_expr); - if (range_expr != error_mark_node - && !type_dependent_expression_p (range_expr) - /* The length of an array might be dependent. */ - && COMPLETE_TYPE_P (complete_type (TREE_TYPE (range_expr))) + if (!type_dependent_expression_p (range_expr) /* do_auto_deduction doesn't mess with template init-lists. */ && !BRACE_ENCLOSED_INITIALIZER_P (range_expr)) do_range_for_auto_deduction (range_decl, range_expr); @@ -16982,6 +16986,11 @@ { cp_ref_qualifier ref_qual = REF_QUAL_NONE; cp_token *token = cp_lexer_peek_token (parser->lexer); + + /* Don't try to parse bitwise '&' as a ref-qualifier (c++/57532). */ + if (cxx_dialect < cxx11 && cp_parser_parsing_tentatively (parser)) + return ref_qual; + switch (token->type) { case CPP_AND: @@ -22557,7 +22566,8 @@ /* In a non-template class, check conversions now. In a template, we'll wait and instantiate these as needed. */ if (TREE_CODE (decl) == PARM_DECL) - parsed_arg = check_default_argument (parmtype, parsed_arg); + parsed_arg = check_default_argument (parmtype, parsed_arg, + tf_warning_or_error); else { int flags = LOOKUP_IMPLICIT; diff -Naur gcc-4.8.1.orig/gcc/cp/pt.c gcc-4.8.1/gcc/cp/pt.c --- gcc-4.8.1.orig/gcc/cp/pt.c 2013-05-24 08:25:44.000000000 -0500 +++ gcc-4.8.1/gcc/cp/pt.c 2013-07-25 10:07:27.406614000 -0500 @@ -138,6 +138,7 @@ tree); static int type_unification_real (tree, tree, tree, const tree *, unsigned int, int, unification_kind_t, int, + vec **, bool); static void note_template_header (int); static tree convert_nontype_argument_function (tree, tree); @@ -183,7 +184,7 @@ tree, tree); static bool template_template_parm_bindings_ok_p (tree, tree); static int template_args_equal (tree, tree); -static void tsubst_default_arguments (tree); +static void tsubst_default_arguments (tree, tsubst_flags_t); static tree for_each_template_parm_r (tree *, int *, void *); static tree copy_default_args_to_explicit_spec_1 (tree, tree); static void copy_default_args_to_explicit_spec (tree); @@ -5612,6 +5613,10 @@ else return NULL_TREE; } + + /* Avoid typedef problems. */ + if (TREE_TYPE (expr) != type) + expr = fold_convert (type, expr); } /* [temp.arg.nontype]/5, bullet 2 @@ -9859,7 +9864,7 @@ FN), which has the indicated TYPE. */ tree -tsubst_default_argument (tree fn, tree type, tree arg) +tsubst_default_argument (tree fn, tree type, tree arg, tsubst_flags_t complain) { tree saved_class_ptr = NULL_TREE; tree saved_class_ref = NULL_TREE; @@ -9899,7 +9904,7 @@ stack. */ ++function_depth; arg = tsubst_expr (arg, DECL_TI_ARGS (fn), - tf_warning_or_error, NULL_TREE, + complain, NULL_TREE, /*integral_constant_expression_p=*/false); --function_depth; pop_deferring_access_checks(); @@ -9911,12 +9916,13 @@ cp_function_chain->x_current_class_ref = saved_class_ref; } - if (errorcount+sorrycount > errs) + if (errorcount+sorrycount > errs + && (complain & tf_warning_or_error)) inform (input_location, " when instantiating default argument for call to %D", fn); /* Make sure the default argument is reasonable. */ - arg = check_default_argument (type, arg); + arg = check_default_argument (type, arg, complain); pop_access_scope (fn); @@ -9926,7 +9932,7 @@ /* Substitute into all the default arguments for FN. */ static void -tsubst_default_arguments (tree fn) +tsubst_default_arguments (tree fn, tsubst_flags_t complain) { tree arg; tree tmpl_args; @@ -9947,7 +9953,8 @@ if (TREE_PURPOSE (arg)) TREE_PURPOSE (arg) = tsubst_default_argument (fn, TREE_VALUE (arg), - TREE_PURPOSE (arg)); + TREE_PURPOSE (arg), + complain); } /* Substitute the ARGS into the T, which is a _DECL. Return the @@ -10298,7 +10305,7 @@ if (!member && !PRIMARY_TEMPLATE_P (gen_tmpl) && !uses_template_parms (argvec)) - tsubst_default_arguments (r); + tsubst_default_arguments (r, complain); } else DECL_TEMPLATE_INFO (r) = NULL_TREE; @@ -12507,6 +12514,9 @@ case TYPE_DECL: return tsubst (t, args, complain, in_decl); + case USING_DECL: + t = DECL_NAME (t); + /* Fall through. */ case IDENTIFIER_NODE: if (IDENTIFIER_TYPENAME_P (t)) { @@ -14974,7 +14984,6 @@ return error_mark_node; tinst = build_tree_list (fn, NULL_TREE); ++deduction_depth; - push_deferring_access_checks (dk_deferred); gcc_assert (TREE_CODE (fn) == TEMPLATE_DECL); @@ -15066,8 +15075,13 @@ } processing_template_decl += incomplete; input_location = DECL_SOURCE_LOCATION (fn); + /* Ignore any access checks; we'll see them again in + instantiate_template and they might have the wrong + access path at this point. */ + push_deferring_access_checks (dk_deferred); fntype = tsubst (TREE_TYPE (fn), explicit_targs, complain | tf_partial, NULL_TREE); + pop_deferring_access_checks (); input_location = loc; processing_template_decl -= incomplete; pop_tinst_level (); @@ -15075,12 +15089,6 @@ if (fntype == error_mark_node) goto fail; - /* Throw away these access checks; we'll see them again in - instantiate_template and they might have the wrong - access path at this point. */ - pop_deferring_access_checks (); - push_deferring_access_checks (dk_deferred); - /* Place the explicitly specified arguments in TARGS. */ for (i = NUM_TMPL_ARGS (explicit_targs); i--;) TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i); @@ -15106,9 +15114,15 @@ callers must be ready to deal with unification failures in any event. */ + /* type_unification_real will pass back any access checks from default + template argument substitution. */ + vec *checks; + checks = NULL; + ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), targs, parms, args, nargs, /*subr=*/0, - strict, flags, explain_p); + strict, flags, &checks, explain_p); + if (!ok) goto fail; @@ -15155,16 +15169,23 @@ excessive_deduction_depth = true; goto fail; } + + /* Also collect access checks from the instantiation. */ + reopen_deferring_access_checks (checks); + decl = instantiate_template (fn, targs, complain); + + checks = get_deferred_access_checks (); + pop_deferring_access_checks (); + pop_tinst_level (); if (decl == error_mark_node) goto fail; - /* Now perform any access checks encountered during deduction, such as - for default template arguments. */ + /* Now perform any access checks encountered during substitution. */ push_access_scope (decl); - ok = perform_deferred_access_checks (complain); + ok = perform_access_checks (checks, complain); pop_access_scope (decl); if (!ok) goto fail; @@ -15193,7 +15214,6 @@ r = decl; fail: - pop_deferring_access_checks (); --deduction_depth; if (excessive_deduction_depth) { @@ -15454,7 +15474,10 @@ If SUBR is 1, we're being called recursively (to unify the arguments of a function or method parameter of a function - template). */ + template). + + CHECKS is a pointer to a vector of access checks encountered while + substituting default template arguments. */ static int type_unification_real (tree tparms, @@ -15465,6 +15488,7 @@ int subr, unification_kind_t strict, int flags, + vec **checks, bool explain_p) { tree parm, arg; @@ -15604,6 +15628,7 @@ { tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i)); tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i)); + reopen_deferring_access_checks (*checks); location_t save_loc = input_location; if (DECL_P (parm)) input_location = DECL_SOURCE_LOCATION (parm); @@ -15611,6 +15636,8 @@ arg = convert_template_argument (parm, arg, targs, complain, i, NULL_TREE); input_location = save_loc; + *checks = get_deferred_access_checks (); + pop_deferring_access_checks (); if (arg == error_mark_node) return 1; else @@ -17078,7 +17105,7 @@ return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm), args, nargs, 1, DEDUCE_EXACT, - LOOKUP_NORMAL, explain_p); + LOOKUP_NORMAL, NULL, explain_p); } case OFFSET_TYPE: @@ -19888,6 +19915,29 @@ && VAR_HAD_UNKNOWN_BOUND (expression)) return true; + /* An array of unknown bound depending on a variadic parameter, eg: + + template + void foo (Args... args) + { + int arr[] = { args... }; + } + + template + void bar () + { + int arr[] = { vals... }; + } + + If the array has no length and has an initializer, it must be that + we couldn't determine its length in cp_complete_array_type because + it is dependent. */ + if (TREE_CODE (expression) == VAR_DECL + && TREE_CODE (TREE_TYPE (expression)) == ARRAY_TYPE + && !TYPE_DOMAIN (TREE_TYPE (expression)) + && DECL_INITIAL (expression)) + return true; + if (TREE_TYPE (expression) == unknown_type_node) { if (TREE_CODE (expression) == ADDR_EXPR) @@ -20626,7 +20676,7 @@ = build_tree_list (NULL_TREE, TYPE_NAME (auto_node)); val = type_unification_real (tparms, targs, parms, args, 1, 0, DEDUCE_CALL, LOOKUP_NORMAL, - /*explain_p=*/false); + NULL, /*explain_p=*/false); if (val > 0) { if (processing_template_decl) diff -Naur gcc-4.8.1.orig/gcc/cp/semantics.c gcc-4.8.1/gcc/cp/semantics.c --- gcc-4.8.1.orig/gcc/cp/semantics.c 2013-05-14 07:51:17.000000000 -0500 +++ gcc-4.8.1/gcc/cp/semantics.c 2013-07-30 11:58:28.826601000 -0500 @@ -155,6 +155,17 @@ } } +/* Save the current deferred access states and start deferred access + checking, continuing the set of deferred checks in CHECKS. */ + +void +reopen_deferring_access_checks (vec * checks) +{ + push_deferring_access_checks (dk_deferred); + if (!deferred_access_no_check) + deferred_access_stack->last().deferred_access_checks = checks; +} + /* Resume deferring access checks again after we stopped doing this previously. */ @@ -5945,7 +5956,7 @@ || TREE_CODE (t) == MODIFY_EXPR) { member = TREE_OPERAND (t, 0); - init = unshare_expr (TREE_OPERAND (t, 1)); + init = break_out_target_exprs (TREE_OPERAND (t, 1)); } else if (TREE_CODE (t) == CALL_EXPR) { @@ -5953,7 +5964,7 @@ /* We don't use build_cplus_new here because it complains about abstract bases. Leaving the call unwrapped means that it has the wrong type, but cxx_eval_constant_expression doesn't care. */ - init = unshare_expr (t); + init = break_out_target_exprs (t); } else if (TREE_CODE (t) == DECL_EXPR) /* Declaring a temporary, don't add it to the CONSTRUCTOR. */ @@ -6190,7 +6201,7 @@ } case RETURN_EXPR: - return unshare_expr (TREE_OPERAND (body, 0)); + return break_out_target_exprs (TREE_OPERAND (body, 0)); case DECL_EXPR: if (TREE_CODE (DECL_EXPR_DECL (body)) == USING_DECL) @@ -7635,11 +7646,6 @@ { tree sub = op0; STRIP_NOPS (sub); - if (TREE_CODE (sub) == POINTER_PLUS_EXPR) - { - sub = TREE_OPERAND (sub, 0); - STRIP_NOPS (sub); - } if (TREE_CODE (sub) == ADDR_EXPR) { /* We couldn't fold to a constant value. Make sure it's not @@ -7990,6 +7996,7 @@ case UNGT_EXPR: case UNGE_EXPR: case UNEQ_EXPR: + case LTGT_EXPR: case RANGE_EXPR: case COMPLEX_EXPR: r = cxx_eval_binary_expression (call, t, allow_non_constant, addr, @@ -8846,6 +8853,12 @@ } return false; + case OMP_ATOMIC: + case OMP_ATOMIC_READ: + case OMP_ATOMIC_CAPTURE_OLD: + case OMP_ATOMIC_CAPTURE_NEW: + return false; + default: if (objc_is_property_ref (t)) return false; @@ -9065,7 +9078,8 @@ { tree type; if (type_dependent_expression_p (expr) - && !(TREE_TYPE (expr) && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)) + && !(TREE_TYPE (expr) && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE + && !type_uses_auto (TREE_TYPE (expr)))) { type = cxx_make_type (DECLTYPE_TYPE); DECLTYPE_TYPE_EXPR (type) = expr; diff -Naur gcc-4.8.1.orig/gcc/cp/tree.c gcc-4.8.1/gcc/cp/tree.c --- gcc-4.8.1.orig/gcc/cp/tree.c 2013-05-24 08:25:51.000000000 -0500 +++ gcc-4.8.1/gcc/cp/tree.c 2013-08-06 20:18:57.648578000 -0500 @@ -1220,6 +1220,8 @@ result = build_method_type_directly (class_type, type, TREE_CHAIN (arg_types)); + result + = build_ref_qualified_type (result, type_memfn_rqual (t)); } else { diff -Naur gcc-4.8.1.orig/gcc/cp/typeck2.c gcc-4.8.1/gcc/cp/typeck2.c --- gcc-4.8.1.orig/gcc/cp/typeck2.c 2013-04-11 11:05:02.000000000 -0500 +++ gcc-4.8.1/gcc/cp/typeck2.c 2013-07-30 08:30:12.307006000 -0500 @@ -262,7 +262,7 @@ so that we can check again once it is completed. This makes sense only for objects for which we have a declaration or at least a name. */ - if (!COMPLETE_TYPE_P (type)) + if (!COMPLETE_TYPE_P (type) && (complain & tf_error)) { void **slot; struct pending_abstract_type *pat; diff -Naur gcc-4.8.1.orig/gcc/cp/typeck.c gcc-4.8.1/gcc/cp/typeck.c --- gcc-4.8.1.orig/gcc/cp/typeck.c 2013-05-13 14:34:15.000000000 -0500 +++ gcc-4.8.1/gcc/cp/typeck.c 2013-07-09 12:52:34.273079000 -0500 @@ -8307,7 +8307,8 @@ && TREE_CODE (retval) == VAR_DECL && DECL_CONTEXT (retval) == current_function_decl && ! TREE_STATIC (retval) - && ! DECL_ANON_UNION_VAR_P (retval) + /* And not a lambda or anonymous union proxy. */ + && !DECL_HAS_VALUE_EXPR_P (retval) && (DECL_ALIGN (retval) >= DECL_ALIGN (result)) /* The cv-unqualified type of the returned value must be the same as the cv-unqualified return type of the @@ -8352,7 +8353,8 @@ Note that these conditions are similar to, but not as strict as, the conditions for the named return value optimization. */ if ((cxx_dialect != cxx98) - && (TREE_CODE (retval) == VAR_DECL + && ((TREE_CODE (retval) == VAR_DECL + && !DECL_HAS_VALUE_EXPR_P (retval)) || TREE_CODE (retval) == PARM_DECL) && DECL_CONTEXT (retval) == current_function_decl && !TREE_STATIC (retval) diff -Naur gcc-4.8.1.orig/gcc/DATESTAMP gcc-4.8.1/gcc/DATESTAMP --- gcc-4.8.1.orig/gcc/DATESTAMP 2013-05-30 19:16:35.000000000 -0500 +++ gcc-4.8.1/gcc/DATESTAMP 2013-08-27 19:16:35.499545000 -0500 @@ -1 +1 @@ -20130531 +20130828 diff -Naur gcc-4.8.1.orig/gcc/doc/avr-mmcu.texi gcc-4.8.1/gcc/doc/avr-mmcu.texi --- gcc-4.8.1.orig/gcc/doc/avr-mmcu.texi 2013-02-28 03:03:09.000000000 -0600 +++ gcc-4.8.1/gcc/doc/avr-mmcu.texi 2013-07-10 07:36:36.732157000 -0500 @@ -38,7 +38,7 @@ @item avr5 ``Enhanced'' devices with 16@tie{}KiB up to 64@tie{}KiB of program memory. -@*@var{mcu}@tie{}= @code{ata5790}, @code{ata5790n}, @code{ata5795}, @code{atmega16}, @code{atmega16a}, @code{atmega16hva}, @code{atmega16hva}, @code{atmega16hva2}, @code{atmega16hva2}, @code{atmega16hvb}, @code{atmega16hvb}, @code{atmega16hvbrevb}, @code{atmega16m1}, @code{atmega16m1}, @code{atmega16u4}, @code{atmega16u4}, @code{atmega161}, @code{atmega162}, @code{atmega163}, @code{atmega164a}, @code{atmega164p}, @code{atmega164pa}, @code{atmega165}, @code{atmega165a}, @code{atmega165p}, @code{atmega165pa}, @code{atmega168}, @code{atmega168a}, @code{atmega168p}, @code{atmega168pa}, @code{atmega169}, @code{atmega169a}, @code{atmega169p}, @code{atmega169pa}, @code{atmega26hvg}, @code{atmega32}, @code{atmega32a}, @code{atmega32a}, @code{atmega32c1}, @code{atmega32c1}, @code{atmega32hvb}, @code{atmega32hvb}, @code{atmega32hvbrevb}, @code{atmega32m1}, @code{atmega32m1}, @code{atmega32u4}, @code{atmega32u4}, @code{atmega32u6}, @code{atmega32u6}, @code{atmega323}, @code{atmega324a}, @code{atmega324p}, @code{atmega324pa}, @code{atmega325}, @code{atmega325a}, @code{atmega325p}, @code{atmega3250}, @code{atmega3250a}, @code{atmega3250p}, @code{atmega3250pa}, @code{atmega328}, @code{atmega328p}, @code{atmega329}, @code{atmega329a}, @code{atmega329p}, @code{atmega329pa}, @code{atmega3290}, @code{atmega3290a}, @code{atmega3290p}, @code{atmega3290pa}, @code{atmega406}, @code{atmega48hvf}, @code{atmega64}, @code{atmega64a}, @code{atmega64c1}, @code{atmega64c1}, @code{atmega64hve}, @code{atmega64m1}, @code{atmega64m1}, @code{atmega64rfa2}, @code{atmega64rfr2}, @code{atmega640}, @code{atmega644}, @code{atmega644a}, @code{atmega644p}, @code{atmega644pa}, @code{atmega645}, @code{atmega645a}, @code{atmega645p}, @code{atmega6450}, @code{atmega6450a}, @code{atmega6450p}, @code{atmega649}, @code{atmega649a}, @code{atmega649p}, @code{atmega6490}, @code{atmega6490a}, @code{atmega6490p}, @code{at90can32}, @code{at90can64}, @code{at90pwm161}, @code{at90pwm216}, @code{at90pwm316}, @code{at90scr100}, @code{at90usb646}, @code{at90usb647}, @code{at94k}, @code{m3000}. +@*@var{mcu}@tie{}= @code{ata5790}, @code{ata5790n}, @code{ata5795}, @code{atmega16}, @code{atmega16a}, @code{atmega16hva}, @code{atmega16hva2}, @code{atmega16hvb}, @code{atmega16hvbrevb}, @code{atmega16m1}, @code{atmega16u4}, @code{atmega161}, @code{atmega162}, @code{atmega163}, @code{atmega164a}, @code{atmega164p}, @code{atmega164pa}, @code{atmega165}, @code{atmega165a}, @code{atmega165p}, @code{atmega165pa}, @code{atmega168}, @code{atmega168a}, @code{atmega168p}, @code{atmega168pa}, @code{atmega169}, @code{atmega169a}, @code{atmega169p}, @code{atmega169pa}, @code{atmega26hvg}, @code{atmega32}, @code{atmega32a}, @code{atmega32c1}, @code{atmega32hvb}, @code{atmega32hvbrevb}, @code{atmega32m1}, @code{atmega32u4}, @code{atmega32u6}, @code{atmega323}, @code{atmega324a}, @code{atmega324p}, @code{atmega324pa}, @code{atmega325}, @code{atmega325a}, @code{atmega325p}, @code{atmega3250}, @code{atmega3250a}, @code{atmega3250p}, @code{atmega3250pa}, @code{atmega328}, @code{atmega328p}, @code{atmega329}, @code{atmega329a}, @code{atmega329p}, @code{atmega329pa}, @code{atmega3290}, @code{atmega3290a}, @code{atmega3290p}, @code{atmega3290pa}, @code{atmega406}, @code{atmega48hvf}, @code{atmega64}, @code{atmega64a}, @code{atmega64c1}, @code{atmega64hve}, @code{atmega64m1}, @code{atmega64rfa2}, @code{atmega64rfr2}, @code{atmega640}, @code{atmega644}, @code{atmega644a}, @code{atmega644p}, @code{atmega644pa}, @code{atmega645}, @code{atmega645a}, @code{atmega645p}, @code{atmega6450}, @code{atmega6450a}, @code{atmega6450p}, @code{atmega649}, @code{atmega649a}, @code{atmega649p}, @code{atmega6490}, @code{atmega6490a}, @code{atmega6490p}, @code{at90can32}, @code{at90can64}, @code{at90pwm161}, @code{at90pwm216}, @code{at90pwm316}, @code{at90scr100}, @code{at90usb646}, @code{at90usb647}, @code{at94k}, @code{m3000}. @item avr51 ``Enhanced'' devices with 128@tie{}KiB of program memory. diff -Naur gcc-4.8.1.orig/gcc/doc/cpp.texi gcc-4.8.1/gcc/doc/cpp.texi --- gcc-4.8.1.orig/gcc/doc/cpp.texi 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/doc/cpp.texi 2013-06-19 04:03:22.324781000 -0500 @@ -1926,11 +1926,9 @@ This macro is defined when the C++ compiler is in use. You can use @code{__cplusplus} to test whether a header is compiled by a C compiler or a C++ compiler. This macro is similar to @code{__STDC_VERSION__}, in -that it expands to a version number. A fully conforming implementation -of the 1998 C++ standard will define this macro to @code{199711L}. The -GNU C++ compiler is not yet fully conforming, so it uses @code{1} -instead. It is hoped to complete the implementation of standard C++ -in the near future. +that it expands to a version number. Depending on the language standard +selected, the value of the macro is @code{199711L}, as mandated by the +1998 C++ standard, or @code{201103L}, per the 2011 C++ standard. @item __OBJC__ This macro is defined, with value 1, when the Objective-C compiler is in diff -Naur gcc-4.8.1.orig/gcc/doc/extend.texi gcc-4.8.1/gcc/doc/extend.texi --- gcc-4.8.1.orig/gcc/doc/extend.texi 2013-03-28 09:07:55.000000000 -0500 +++ gcc-4.8.1/gcc/doc/extend.texi 2013-08-02 10:41:10.548493000 -0500 @@ -8786,6 +8786,7 @@ * PowerPC Built-in Functions:: * PowerPC AltiVec/VSX Built-in Functions:: * RX Built-in Functions:: +* S/390 System z Built-in Functions:: * SH Built-in Functions:: * SPARC VIS Built-in Functions:: * SPU Built-in Functions:: @@ -14026,6 +14027,120 @@ Generates the @code{wait} machine instruction. @end deftypefn +@node S/390 System z Built-in Functions +@subsection S/390 System z Built-in Functions +@deftypefn {Built-in Function} int __builtin_tbegin (void*) +Generates the @code{tbegin} machine instruction starting a +non-constraint hardware transaction. If the parameter is non-NULL the +memory area is used to store the transaction diagnostic buffer and +will be passed as first operand to @code{tbegin}. This buffer can be +defined using the @code{struct __htm_tdb} C struct defined in +@code{htmintrin.h} and must reside on a double-word boundary. The +second tbegin operand is set to @code{0xff0c}. This enables +save/restore of all GPRs and disables aborts for FPR and AR +manipulations inside the transaction body. The condition code set by +the tbegin instruction is returned as integer value. The tbegin +instruction by definition overwrites the content of all FPRs. The +compiler will generate code which saves and restores the FPRs. For +soft-float code it is recommended to used the @code{*_nofloat} +variant. In order to prevent a TDB from being written it is required +to pass an constant zero value as parameter. Passing the zero value +through a variable is not sufficient. Although modifications of +access registers inside the transaction will not trigger an +transaction abort it is not supported to actually modify them. Access +registers do not get saved when entering a transaction. They will have +undefined state when reaching the abort code. +@end deftypefn + +Macros for the possible return codes of tbegin are defined in the +@code{htmintrin.h} header file: + +@table @code +@item _HTM_TBEGIN_STARTED +@code{tbegin} has been executed as part of normal processing. The +transaction body is supposed to be executed. +@item _HTM_TBEGIN_INDETERMINATE +The transaction was aborted due to an indeterminate condition which +might be persistent. +@item _HTM_TBEGIN_TRANSIENT +The transaction aborted due to a transient failure. The transaction +should be re-executed in that case. +@item _HTM_TBEGIN_PERSISTENT +The transaction aborted due to a persistent failure. Re-execution +under same circumstances will not be productive. +@end table + +@defmac _HTM_FIRST_USER_ABORT_CODE +The @code{_HTM_FIRST_USER_ABORT_CODE} defined in @code{htmintrin.h} +specifies the first abort code which can be used for +@code{__builtin_tabort}. Values below this threshold are reserved for +machine use. +@end defmac + +@deftp {Data type} {struct __htm_tdb} +The @code{struct __htm_tdb} defined in @code{htmintrin.h} describes +the structure of the transaction diagnostic block as specified in the +Principles of Operation manual chapter 5-91. +@end deftp + +@deftypefn {Built-in Function} int __builtin_tbegin_nofloat (void*) +Same as @code{__builtin_tbegin} but without FPR saves and restores. +Using this variant in code making use of FPRs will leave the FPRs in +undefined state when entering the transaction abort handler code. +@end deftypefn + +@deftypefn {Built-in Function} int __builtin_tbegin_retry (void*, int) +In addition to @code{__builtin_tbegin} a loop for transient failures +is generated. If tbegin returns a condition code of 2 the transaction +will be retried as often as specified in the second argument. The +perform processor assist instruction is used to tell the CPU about the +number of fails so far. +@end deftypefn + +@deftypefn {Built-in Function} int __builtin_tbegin_retry_nofloat (void*, int) +Same as @code{__builtin_tbegin_retry} but without FPR saves and +restores. Using this variant in code making use of FPRs will leave +the FPRs in undefined state when entering the transaction abort +handler code. +@end deftypefn + +@deftypefn {Built-in Function} void __builtin_tbeginc (void) +Generates the @code{tbeginc} machine instruction starting a constraint +hardware transaction. The second operand is set to @code{0xff08}. +@end deftypefn + +@deftypefn {Built-in Function} int __builtin_tend (void) +Generates the @code{tend} machine instruction finishing a transaction +and making the changes visible to other threads. The condition code +generated by tend is returned as integer value. +@end deftypefn + +@deftypefn {Built-in Function} void __builtin_tabort (int) +Generates the @code{tabort} machine instruction with the specified +abort code. Abort codes from 0 through 255 are reserved and will +result in an error message. +@end deftypefn + +@deftypefn {Built-in Function} void __builtin_tx_assist (int) +Generates the @code{ppa rX,rY,1} machine instruction. Where the +integer parameter is loaded into rX and a value of zero is loaded into +rY. The integer parameter specifies the number of times the +transaction repeatedly aborted. +@end deftypefn + +@deftypefn {Built-in Function} int __builtin_tx_nesting_depth (void) +Generates the @code{etnd} machine instruction. The current nesting +depth is returned as integer value. For a nesting depth of 0 the code +is not executed as part of an transaction. +@end deftypefn + +@deftypefn {Built-in Function} void __builtin_non_tx_store (unsigned long long *, unsigned long long) + +Generates the @code{ntstg} machine instruction. The second argument +is written to the first arguments location. The store operation will +not be rolled-back in case of an transaction abort. +@end deftypefn + @node SH Built-in Functions @subsection SH Built-in Functions The following built-in functions are supported on the SH1, SH2, SH3 and SH4 diff -Naur gcc-4.8.1.orig/gcc/doc/invoke.texi gcc-4.8.1/gcc/doc/invoke.texi --- gcc-4.8.1.orig/gcc/doc/invoke.texi 2013-03-29 08:41:29.000000000 -0500 +++ gcc-4.8.1/gcc/doc/invoke.texi 2013-06-19 14:55:50.111258000 -0500 @@ -13726,8 +13726,13 @@ SSE4.1, SSE4.2, AVX, AES, PCLMUL, FSGSBASE, RDRND and F16C instruction set support. +@item core-avx2 +Intel Core CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, +SSE4.1, SSE4.2, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2 +and F16C instruction set support. + @item atom -Intel Atom CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3 and SSSE3 +Intel Atom CPU with 64-bit extensions, MOVBE, MMX, SSE, SSE2, SSE3 and SSSE3 instruction set support. @item k6 diff -Naur gcc-4.8.1.orig/gcc/file-find.c gcc-4.8.1/gcc/file-find.c --- gcc-4.8.1.orig/gcc/file-find.c 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/file-find.c 2013-06-19 15:59:25.231992000 -0500 @@ -31,7 +31,7 @@ } char * -find_a_file (struct path_prefix *pprefix, const char *name) +find_a_file (struct path_prefix *pprefix, const char *name, int mode) { char *temp; struct prefix_list *pl; @@ -50,7 +50,7 @@ if (IS_ABSOLUTE_PATH (name)) { - if (access (name, X_OK) == 0) + if (access (name, mode) == 0) { strcpy (temp, name); @@ -66,7 +66,7 @@ strcpy (temp, name); strcat (temp, HOST_EXECUTABLE_SUFFIX); - if (access (temp, X_OK) == 0) + if (access (temp, mode) == 0) return temp; #endif @@ -83,7 +83,7 @@ if (stat (temp, &st) >= 0 && ! S_ISDIR (st.st_mode) - && access (temp, X_OK) == 0) + && access (temp, mode) == 0) return temp; #ifdef HOST_EXECUTABLE_SUFFIX @@ -93,7 +93,7 @@ if (stat (temp, &st) >= 0 && ! S_ISDIR (st.st_mode) - && access (temp, X_OK) == 0) + && access (temp, mode) == 0) return temp; #endif } diff -Naur gcc-4.8.1.orig/gcc/file-find.h gcc-4.8.1/gcc/file-find.h --- gcc-4.8.1.orig/gcc/file-find.h 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/file-find.h 2013-06-19 15:59:25.231992000 -0500 @@ -38,7 +38,7 @@ }; extern void find_file_set_debug (bool); -extern char *find_a_file (struct path_prefix *, const char *); +extern char *find_a_file (struct path_prefix *, const char *, int); extern void add_prefix (struct path_prefix *, const char *); extern void prefix_from_env (const char *, struct path_prefix *); extern void prefix_from_string (const char *, struct path_prefix *); diff -Naur gcc-4.8.1.orig/gcc/fortran/interface.c gcc-4.8.1/gcc/fortran/interface.c --- gcc-4.8.1.orig/gcc/fortran/interface.c 2013-04-26 14:20:55.000000000 -0500 +++ gcc-4.8.1/gcc/fortran/interface.c 2013-05-31 13:10:03.669091000 -0500 @@ -1024,7 +1024,8 @@ bool type_must_agree, char *errmsg, int err_len) { /* Check type and rank. */ - if (type_must_agree && !compare_type_rank (s2, s1)) + if (type_must_agree && + (!compare_type_rank (s1, s2) || !compare_type_rank (s2, s1))) { snprintf (errmsg, err_len, "Type/rank mismatch in argument '%s'", s1->name); diff -Naur gcc-4.8.1.orig/gcc/fortran/match.c gcc-4.8.1/gcc/fortran/match.c --- gcc-4.8.1.orig/gcc/fortran/match.c 2013-04-18 13:20:22.000000000 -0500 +++ gcc-4.8.1/gcc/fortran/match.c 2013-08-24 04:12:21.843607000 -0500 @@ -5142,7 +5142,6 @@ { gfc_ref *ref; gfc_symbol *assoc_sym; - int i; assoc_sym = associate->symtree->n.sym; @@ -5153,9 +5152,8 @@ while (ref && ref->next) ref = ref->next; - if (selector->ts.type == BT_CLASS - && CLASS_DATA (selector)->as - && ref && ref->type == REF_ARRAY) + if (selector->ts.type == BT_CLASS && CLASS_DATA (selector)->as + && ref && ref->type == REF_ARRAY) { /* Ensure that the array reference type is set. We cannot use gfc_resolve_expr at this point, so the usable parts of @@ -5163,7 +5161,7 @@ if (ref->u.ar.type == AR_UNKNOWN) { ref->u.ar.type = AR_ELEMENT; - for (i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++) + for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++) if (ref->u.ar.dimen_type[i] == DIMEN_RANGE || ref->u.ar.dimen_type[i] == DIMEN_VECTOR || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN @@ -5182,37 +5180,19 @@ selector->rank = 0; } - if (selector->ts.type != BT_CLASS) + if (selector->rank) { - /* The correct class container has to be available. */ - if (selector->rank) - { - assoc_sym->attr.dimension = 1; - assoc_sym->as = gfc_get_array_spec (); - assoc_sym->as->rank = selector->rank; - assoc_sym->as->type = AS_DEFERRED; - } - else - assoc_sym->as = NULL; - - assoc_sym->ts.type = BT_CLASS; - assoc_sym->ts.u.derived = selector->ts.u.derived; - assoc_sym->attr.pointer = 1; - gfc_build_class_symbol (&assoc_sym->ts, &assoc_sym->attr, - &assoc_sym->as, false); + assoc_sym->attr.dimension = 1; + assoc_sym->as = gfc_get_array_spec (); + assoc_sym->as->rank = selector->rank; + assoc_sym->as->type = AS_DEFERRED; } else + assoc_sym->as = NULL; + + if (selector->ts.type == BT_CLASS) { /* The correct class container has to be available. */ - if (selector->rank) - { - assoc_sym->attr.dimension = 1; - assoc_sym->as = gfc_get_array_spec (); - assoc_sym->as->rank = selector->rank; - assoc_sym->as->type = AS_DEFERRED; - } - else - assoc_sym->as = NULL; assoc_sym->ts.type = BT_CLASS; assoc_sym->ts.u.derived = CLASS_DATA (selector)->ts.u.derived; assoc_sym->attr.pointer = 1; diff -Naur gcc-4.8.1.orig/gcc/fortran/module.c gcc-4.8.1/gcc/fortran/module.c --- gcc-4.8.1.orig/gcc/fortran/module.c 2013-01-29 15:40:51.000000000 -0600 +++ gcc-4.8.1/gcc/fortran/module.c 2013-07-28 09:13:17.566941000 -0500 @@ -4465,7 +4465,7 @@ module_locus locus; symbol_attribute attr; - if (st_sym->name == gfc_current_ns->proc_name->name) + if (gfc_current_ns->proc_name && st_sym->name == gfc_current_ns->proc_name->name) { gfc_error ("'%s' of module '%s', imported at %C, is also the name of the " "current program unit", st_sym->name, module_name); diff -Naur gcc-4.8.1.orig/gcc/fortran/resolve.c gcc-4.8.1/gcc/fortran/resolve.c --- gcc-4.8.1.orig/gcc/fortran/resolve.c 2013-05-07 11:36:48.000000000 -0500 +++ gcc-4.8.1/gcc/fortran/resolve.c 2013-06-11 11:18:13.173979000 -0500 @@ -9746,6 +9746,10 @@ /* Add the attributes and the arrayspec to the temporary. */ tmp->n.sym->attr = gfc_expr_attr (e); + tmp->n.sym->attr.function = 0; + tmp->n.sym->attr.result = 0; + tmp->n.sym->attr.flavor = FL_VARIABLE; + if (as) { tmp->n.sym->as = gfc_copy_array_spec (as); @@ -9759,6 +9763,7 @@ gfc_set_sym_referenced (tmp->n.sym); gfc_add_flavor (&tmp->n.sym->attr, FL_VARIABLE, name, NULL); + gfc_commit_symbol (tmp->n.sym); e = gfc_lval_expr_from_sym (tmp->n.sym); /* Should the lhs be a section, use its array ref for the diff -Naur gcc-4.8.1.orig/gcc/fortran/simplify.c gcc-4.8.1/gcc/fortran/simplify.c --- gcc-4.8.1.orig/gcc/fortran/simplify.c 2013-05-07 11:36:48.000000000 -0500 +++ gcc-4.8.1/gcc/fortran/simplify.c 2013-07-08 14:10:32.194953000 -0500 @@ -332,13 +332,15 @@ } -/* Helper function for gfc_simplify_dot_product() and gfc_simplify_matmul. */ +/* Helper function for gfc_simplify_dot_product() and gfc_simplify_matmul; + if conj_a is true, the matrix_a is complex conjugated. */ static gfc_expr * compute_dot_product (gfc_expr *matrix_a, int stride_a, int offset_a, - gfc_expr *matrix_b, int stride_b, int offset_b) + gfc_expr *matrix_b, int stride_b, int offset_b, + bool conj_a) { - gfc_expr *result, *a, *b; + gfc_expr *result, *a, *b, *c; result = gfc_get_constant_expr (matrix_a->ts.type, matrix_a->ts.kind, &matrix_a->where); @@ -361,9 +363,11 @@ case BT_INTEGER: case BT_REAL: case BT_COMPLEX: - result = gfc_add (result, - gfc_multiply (gfc_copy_expr (a), - gfc_copy_expr (b))); + if (conj_a && a->ts.type == BT_COMPLEX) + c = gfc_simplify_conjg (a); + else + c = gfc_copy_expr (a); + result = gfc_add (result, gfc_multiply (c, gfc_copy_expr (b))); break; default: @@ -1881,7 +1885,7 @@ gcc_assert (vector_b->rank == 1); gcc_assert (gfc_compare_types (&vector_a->ts, &vector_b->ts)); - return compute_dot_product (vector_a, 1, 0, vector_b, 1, 0); + return compute_dot_product (vector_a, 1, 0, vector_b, 1, 0, true); } @@ -3894,7 +3898,7 @@ for (row = 0; row < result_rows; ++row) { gfc_expr *e = compute_dot_product (matrix_a, stride_a, offset_a, - matrix_b, 1, offset_b); + matrix_b, 1, offset_b, false); gfc_constructor_append_expr (&result->value.constructor, e, NULL); diff -Naur gcc-4.8.1.orig/gcc/fortran/trans-array.c gcc-4.8.1/gcc/fortran/trans-array.c --- gcc-4.8.1.orig/gcc/fortran/trans-array.c 2013-02-21 06:26:44.000000000 -0600 +++ gcc-4.8.1/gcc/fortran/trans-array.c 2013-08-24 07:46:17.832897000 -0500 @@ -3674,7 +3674,7 @@ /* Calculate the lower bound of an array section. */ static void -gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim) +gfc_conv_section_startstride (stmtblock_t * block, gfc_ss * ss, int dim) { gfc_expr *stride = NULL; tree desc; @@ -3703,12 +3703,12 @@ /* Calculate the start of the range. For vector subscripts this will be the range of the vector. */ - evaluate_bound (&loop->pre, info->start, ar->start, desc, dim, true); + evaluate_bound (block, info->start, ar->start, desc, dim, true); /* Similarly calculate the end. Although this is not used in the scalarizer, it is needed when checking bounds and where the end is an expression with side-effects. */ - evaluate_bound (&loop->pre, info->end, ar->end, desc, dim, false); + evaluate_bound (block, info->end, ar->end, desc, dim, false); /* Calculate the stride. */ if (stride == NULL) @@ -3717,8 +3717,8 @@ { gfc_init_se (&se, NULL); gfc_conv_expr_type (&se, stride, gfc_array_index_type); - gfc_add_block_to_block (&loop->pre, &se.pre); - info->stride[dim] = gfc_evaluate_now (se.expr, &loop->pre); + gfc_add_block_to_block (block, &se.pre); + info->stride[dim] = gfc_evaluate_now (se.expr, block); } } @@ -3735,6 +3735,8 @@ gfc_ss *ss; tree desc; + gfc_loopinfo * const outer_loop = outermost_loop (loop); + loop->dimen = 0; /* Determine the rank of the loop. */ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain) @@ -3794,10 +3796,11 @@ /* Get the descriptor for the array. If it is a cross loops array, we got the descriptor already in the outermost loop. */ if (ss->parent == NULL) - gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter); + gfc_conv_ss_descriptor (&outer_loop->pre, ss, + !loop->array_parameter); for (n = 0; n < ss->dimen; n++) - gfc_conv_section_startstride (loop, ss, ss->dim[n]); + gfc_conv_section_startstride (&outer_loop->pre, ss, ss->dim[n]); break; case GFC_SS_INTRINSIC: @@ -3833,7 +3836,7 @@ fold_convert (gfc_array_index_type, rank), gfc_index_one_node); - info->end[0] = gfc_evaluate_now (tmp, &loop->pre); + info->end[0] = gfc_evaluate_now (tmp, &outer_loop->pre); info->start[0] = gfc_index_zero_node; info->stride[0] = gfc_index_one_node; continue; @@ -4115,7 +4118,7 @@ } tmp = gfc_finish_block (&block); - gfc_add_expr_to_block (&loop->pre, tmp); + gfc_add_expr_to_block (&outer_loop->pre, tmp); } for (loop = loop->nested; loop; loop = loop->next) @@ -4398,6 +4401,8 @@ mpz_t i; bool nonoptional_arr; + gfc_loopinfo * const outer_loop = outermost_loop (loop); + loopspec = loop->specloop; mpz_init (i); @@ -4583,7 +4588,7 @@ else { /* Set the delta for this section. */ - info->delta[dim] = gfc_evaluate_now (loop->from[n], &loop->pre); + info->delta[dim] = gfc_evaluate_now (loop->from[n], &outer_loop->pre); /* Number of iterations is (end - start + step) / step. with start = 0, this simplifies to last = end / step; @@ -4595,7 +4600,7 @@ gfc_array_index_type, tmp, info->stride[dim]); tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type, tmp, build_int_cst (gfc_array_index_type, -1)); - loop->to[n] = gfc_evaluate_now (tmp, &loop->pre); + loop->to[n] = gfc_evaluate_now (tmp, &outer_loop->pre); /* Make the loop variable start at 0. */ loop->from[n] = gfc_index_zero_node; } @@ -4671,6 +4676,8 @@ tree tmp; int n, dim; + gfc_loopinfo * const outer_loop = outermost_loop (loop); + loopspec = loop->specloop; /* Calculate the translation from loop variables to array indices. */ @@ -4706,7 +4713,7 @@ gfc_array_index_type, info->start[dim], tmp); - info->delta[dim] = gfc_evaluate_now (tmp, &loop->pre); + info->delta[dim] = gfc_evaluate_now (tmp, &outer_loop->pre); } } } @@ -6690,10 +6697,10 @@ gcc_assert (ar->dimen_type[n + ndim] == DIMEN_THIS_IMAGE); /* Make sure the call to gfc_conv_section_startstride won't - generate unnecessary code to calculate stride. */ + generate unnecessary code to calculate stride. */ gcc_assert (ar->stride[n + ndim] == NULL); - gfc_conv_section_startstride (&loop, ss, n + ndim); + gfc_conv_section_startstride (&loop.pre, ss, n + ndim); loop.from[n + loop.dimen] = info->start[n + ndim]; loop.to[n + loop.dimen] = info->end[n + ndim]; } diff -Naur gcc-4.8.1.orig/gcc/fortran/trans-intrinsic.c gcc-4.8.1/gcc/fortran/trans-intrinsic.c --- gcc-4.8.1.orig/gcc/fortran/trans-intrinsic.c 2013-03-15 05:09:39.000000000 -0500 +++ gcc-4.8.1/gcc/fortran/trans-intrinsic.c 2013-08-11 06:31:41.480740000 -0500 @@ -5653,8 +5653,7 @@ if (expr->ts.type == BT_CHARACTER) { - tree direct; - tree indirect; + tree direct, indirect, free; ptr = convert (gfc_get_pchar_type (expr->ts.kind), source); tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), @@ -5687,6 +5686,13 @@ tmp = build3_v (COND_EXPR, tmp, direct, indirect); gfc_add_expr_to_block (&se->pre, tmp); + /* Free the temporary string, if necessary. */ + free = gfc_call_free (tmpdecl); + tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, + dest_word_len, source_bytes); + tmp = build3_v (COND_EXPR, tmp, free, build_empty_stmt (input_location)); + gfc_add_expr_to_block (&se->post, tmp); + se->expr = tmpdecl; se->string_length = fold_convert (gfc_charlen_type_node, dest_word_len); } diff -Naur gcc-4.8.1.orig/gcc/gcc-ar.c gcc-4.8.1/gcc/gcc-ar.c --- gcc-4.8.1.orig/gcc/gcc-ar.c 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/gcc-ar.c 2013-06-19 15:59:25.231992000 -0500 @@ -136,7 +136,7 @@ setup_prefixes (av[0]); /* Find the GCC LTO plugin */ - plugin = find_a_file (&target_path, LTOPLUGINSONAME); + plugin = find_a_file (&target_path, LTOPLUGINSONAME, R_OK); if (!plugin) { fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME); @@ -144,24 +144,20 @@ } /* Find the wrapped binutils program. */ - exe_name = find_a_file (&target_path, PERSONALITY); + exe_name = find_a_file (&target_path, PERSONALITY, X_OK); if (!exe_name) { + const char *real_exe_name = PERSONALITY; #ifdef CROSS_DIRECTORY_STRUCTURE - const char *cross_exe_name; - - cross_exe_name = concat (target_machine, "-", PERSONALITY, NULL); - exe_name = find_a_file (&path, cross_exe_name); + real_exe_name = concat (target_machine, "-", PERSONALITY, NULL); +#endif + exe_name = find_a_file (&path, real_exe_name, X_OK); if (!exe_name) { fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0], - cross_exe_name); + real_exe_name); exit (1); } -#else - fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0], PERSONALITY); - exit (1); -#endif } /* Create new command line with plugin */ diff -Naur gcc-4.8.1.orig/gcc/gimple.c gcc-4.8.1/gcc/gimple.c --- gcc-4.8.1.orig/gcc/gimple.c 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/gimple.c 2013-08-16 04:06:41.868666000 -0500 @@ -4045,6 +4045,13 @@ ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); } } + else if (visit_addr + && gimple_code (stmt) == GIMPLE_GOTO) + { + tree op = gimple_goto_dest (stmt); + if (TREE_CODE (op) == ADDR_EXPR) + ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data); + } return ret; } diff -Naur gcc-4.8.1.orig/gcc/gimple-ssa-strength-reduction.c gcc-4.8.1/gcc/gimple-ssa-strength-reduction.c --- gcc-4.8.1.orig/gcc/gimple-ssa-strength-reduction.c 2013-04-15 10:00:06.000000000 -0500 +++ gcc-4.8.1/gcc/gimple-ssa-strength-reduction.c 2013-08-06 10:08:59.668112000 -0500 @@ -1525,11 +1525,23 @@ static void replace_ref (tree *expr, slsr_cand_t c) { - tree add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr), - c->base_expr, c->stride); - tree mem_ref = fold_build2 (MEM_REF, TREE_TYPE (*expr), add_expr, - double_int_to_tree (c->cand_type, c->index)); - + tree add_expr, mem_ref, acc_type = TREE_TYPE (*expr); + unsigned HOST_WIDE_INT misalign; + unsigned align; + + /* Ensure the memory reference carries the minimum alignment + requirement for the data type. See PR58041. */ + get_object_alignment_1 (*expr, &align, &misalign); + if (misalign != 0) + align = (misalign & -misalign); + if (align < TYPE_ALIGN (acc_type)) + acc_type = build_aligned_type (acc_type, align); + + add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr), + c->base_expr, c->stride); + mem_ref = fold_build2 (MEM_REF, acc_type, add_expr, + double_int_to_tree (c->cand_type, c->index)); + /* Gimplify the base addressing expression for the new MEM_REF tree. */ gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt); TREE_OPERAND (mem_ref, 0) diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/backend.h gcc-4.8.1/gcc/go/gofrontend/backend.h --- gcc-4.8.1.orig/gcc/go/gofrontend/backend.h 2012-11-29 12:11:17.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/backend.h 2013-06-18 18:50:42.020320000 -0500 @@ -95,7 +95,10 @@ // Get a function type. The receiver, parameter, and results are // generated from the types in the Function_type. The Function_type - // is provided so that the names are available. + // is provided so that the names are available. This should return + // not the type of a Go function (which is a pointer to a struct) + // but the type of a C function pointer (which will be used as the + // type of the first field of the struct). virtual Btype* function_type(const Btyped_identifier& receiver, const std::vector& parameters, @@ -388,18 +391,22 @@ Bstatement** pstatement) = 0; // Create a named immutable initialized data structure. This is - // used for type descriptors and map descriptors. This returns a - // Bvariable because it corresponds to an initialized const global - // variable in C. + // used for type descriptors, map descriptors, and function + // descriptors. This returns a Bvariable because it corresponds to + // an initialized const variable in C. // // NAME is the name to use for the initialized global variable which // this call will create. // + // IS_HIDDEN will be true if the descriptor should only be visible + // within the current object. + // // IS_COMMON is true if NAME may be defined by several packages, and // the linker should merge all such definitions. If IS_COMMON is // false, NAME should be defined in only one file. In general // IS_COMMON will be true for the type descriptor of an unnamed type - // or a builtin type. + // or a builtin type. IS_HIDDEN and IS_COMMON will never both be + // true. // // TYPE will be a struct type; the type of the returned expression // must be a pointer to this struct type. @@ -409,20 +416,20 @@ // address. After calling this the frontend will call // immutable_struct_set_init. virtual Bvariable* - immutable_struct(const std::string& name, bool is_common, Btype* type, - Location) = 0; + immutable_struct(const std::string& name, bool is_hidden, bool is_common, + Btype* type, Location) = 0; // Set the initial value of a variable created by immutable_struct. - // The NAME, IS_COMMON, TYPE, and location parameters are the same - // ones passed to immutable_struct. INITIALIZER will be a composite - // literal of type TYPE. It will not contain any function calls or - // anything else which can not be put into a read-only data section. - // It may contain the address of variables created by + // The NAME, IS_HIDDEN, IS_COMMON, TYPE, and location parameters are + // the same ones passed to immutable_struct. INITIALIZER will be a + // composite literal of type TYPE. It will not contain any function + // calls or anything else that can not be put into a read-only data + // section. It may contain the address of variables created by // immutable_struct. virtual void immutable_struct_set_init(Bvariable*, const std::string& name, - bool is_common, Btype* type, Location, - Bexpression* initializer) = 0; + bool is_hidden, bool is_common, Btype* type, + Location, Bexpression* initializer) = 0; // Create a reference to a named immutable initialized data // structure defined in some other package. This will be a diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/expressions.cc gcc-4.8.1/gcc/go/gofrontend/expressions.cc --- gcc-4.8.1.orig/gcc/go/gofrontend/expressions.cc 2012-12-21 09:59:27.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/expressions.cc 2013-06-26 17:42:47.881515000 -0500 @@ -1090,6 +1090,15 @@ return this->statement_->type(); } +// Determine the type of the expression. + +void +Set_and_use_temporary_expression::do_determine_type( + const Type_context* context) +{ + this->expr_->determine_type(context); +} + // Take the address. void @@ -1255,17 +1264,16 @@ go_unreachable(); } -// Get the tree for a function expression without evaluating the -// closure. +// Get the tree for the code of a function expression. tree -Func_expression::get_tree_without_closure(Gogo* gogo) +Func_expression::get_code_pointer(Gogo* gogo, Named_object* no, Location loc) { Function_type* fntype; - if (this->function_->is_function()) - fntype = this->function_->func_value()->type(); - else if (this->function_->is_function_declaration()) - fntype = this->function_->func_declaration_value()->type(); + if (no->is_function()) + fntype = no->func_value()->type(); + else if (no->is_function_declaration()) + fntype = no->func_declaration_value()->type(); else go_unreachable(); @@ -1273,14 +1281,12 @@ // can't take their address. if (fntype->is_builtin()) { - error_at(this->location(), + error_at(loc, "invalid use of special builtin function %qs; must be called", - this->function_->name().c_str()); + no->message_name().c_str()); return error_mark_node; } - Named_object* no = this->function_; - tree id = no->get_id(gogo); if (id == error_mark_node) return error_mark_node; @@ -1296,46 +1302,55 @@ if (fndecl == error_mark_node) return error_mark_node; - return build_fold_addr_expr_loc(this->location().gcc_location(), fndecl); + return build_fold_addr_expr_loc(loc.gcc_location(), fndecl); } // Get the tree for a function expression. This is used when we take -// the address of a function rather than simply calling it. If the -// function has a closure, we must use a trampoline. +// the address of a function rather than simply calling it. A func +// value is represented as a pointer to a block of memory. The first +// word of that memory is a pointer to the function code. The +// remaining parts of that memory are the addresses of variables that +// the function closes over. tree Func_expression::do_get_tree(Translate_context* context) { - Gogo* gogo = context->gogo(); - - tree fnaddr = this->get_tree_without_closure(gogo); - if (fnaddr == error_mark_node) - return error_mark_node; - - go_assert(TREE_CODE(fnaddr) == ADDR_EXPR - && TREE_CODE(TREE_OPERAND(fnaddr, 0)) == FUNCTION_DECL); - TREE_ADDRESSABLE(TREE_OPERAND(fnaddr, 0)) = 1; - - // If there is no closure, that is all have to do. + // If there is no closure, just use the function descriptor. if (this->closure_ == NULL) - return fnaddr; - - go_assert(this->function_->func_value()->enclosing() != NULL); + { + Gogo* gogo = context->gogo(); + Named_object* no = this->function_; + Expression* descriptor; + if (no->is_function()) + descriptor = no->func_value()->descriptor(gogo, no); + else if (no->is_function_declaration()) + { + if (no->func_declaration_value()->type()->is_builtin()) + { + error_at(this->location(), + ("invalid use of special builtin function %qs; " + "must be called"), + no->message_name().c_str()); + return error_mark_node; + } + descriptor = no->func_declaration_value()->descriptor(gogo, no); + } + else + go_unreachable(); - // Get the value of the closure. This will be a pointer to space - // allocated on the heap. - tree closure_tree = this->closure_->get_tree(context); - if (closure_tree == error_mark_node) - return error_mark_node; - go_assert(POINTER_TYPE_P(TREE_TYPE(closure_tree))); + tree dtree = descriptor->get_tree(context); + if (dtree == error_mark_node) + return error_mark_node; + return build_fold_addr_expr_loc(this->location().gcc_location(), dtree); + } - // Now we need to build some code on the heap. This code will load - // the static chain pointer with the closure and then jump to the - // body of the function. The normal gcc approach is to build the - // code on the stack. Unfortunately we can not do that, as Go - // permits us to return the function pointer. + go_assert(this->function_->func_value()->enclosing() != NULL); - return gogo->make_trampoline(fnaddr, closure_tree, this->location()); + // If there is a closure, then the closure is itself the function + // expression. It is a pointer to a struct whose first field points + // to the function code and whose remaining fields are the addresses + // of the closed-over variables. + return this->closure_->get_tree(context); } // Ast dump for function. @@ -1361,6 +1376,197 @@ return new Func_expression(function, closure, location); } +// Class Func_descriptor_expression. + +// Constructor. + +Func_descriptor_expression::Func_descriptor_expression(Named_object* fn) + : Expression(EXPRESSION_FUNC_DESCRIPTOR, fn->location()), + fn_(fn), dfn_(NULL), dvar_(NULL) +{ + go_assert(!fn->is_function() || !fn->func_value()->needs_closure()); +} + +// Traversal. + +int +Func_descriptor_expression::do_traverse(Traverse*) +{ + return TRAVERSE_CONTINUE; +} + +// All function descriptors have the same type. + +Type* Func_descriptor_expression::descriptor_type; + +void +Func_descriptor_expression::make_func_descriptor_type() +{ + if (Func_descriptor_expression::descriptor_type != NULL) + return; + Type* uintptr_type = Type::lookup_integer_type("uintptr"); + Type* struct_type = Type::make_builtin_struct_type(1, "code", uintptr_type); + Func_descriptor_expression::descriptor_type = + Type::make_builtin_named_type("functionDescriptor", struct_type); +} + +Type* +Func_descriptor_expression::do_type() +{ + Func_descriptor_expression::make_func_descriptor_type(); + return Func_descriptor_expression::descriptor_type; +} + +// Copy a Func_descriptor_expression; + +Expression* +Func_descriptor_expression::do_copy() +{ + Func_descriptor_expression* fde = + Expression::make_func_descriptor(this->fn_); + if (this->dfn_ != NULL) + fde->set_descriptor_wrapper(this->dfn_); + return fde; +} + +// The tree for a function descriptor. + +tree +Func_descriptor_expression::do_get_tree(Translate_context* context) +{ + if (this->dvar_ != NULL) + return var_to_tree(this->dvar_); + + Gogo* gogo = context->gogo(); + Named_object* no = this->fn_; + Location loc = no->location(); + + std::string var_name; + if (no->package() == NULL) + var_name = gogo->pkgpath_symbol(); + else + var_name = no->package()->pkgpath_symbol(); + var_name.push_back('.'); + var_name.append(Gogo::unpack_hidden_name(no->name())); + var_name.append("$descriptor"); + + Btype* btype = this->type()->get_backend(gogo); + + Bvariable* bvar; + if (no->package() != NULL + || Linemap::is_predeclared_location(no->location())) + { + bvar = context->backend()->immutable_struct_reference(var_name, btype, + loc); + go_assert(this->dfn_ == NULL); + } + else + { + Location bloc = Linemap::predeclared_location(); + bool is_hidden = ((no->is_function() + && no->func_value()->enclosing() != NULL) + || Gogo::is_thunk(no)); + bvar = context->backend()->immutable_struct(var_name, is_hidden, false, + btype, bloc); + Expression_list* vals = new Expression_list(); + go_assert(this->dfn_ != NULL); + vals->push_back(Expression::make_func_code_reference(this->dfn_, bloc)); + Expression* init = + Expression::make_struct_composite_literal(this->type(), vals, bloc); + Translate_context bcontext(gogo, NULL, NULL, NULL); + bcontext.set_is_const(); + Bexpression* binit = tree_to_expr(init->get_tree(&bcontext)); + context->backend()->immutable_struct_set_init(bvar, var_name, is_hidden, + false, btype, bloc, binit); + } + + this->dvar_ = bvar; + return var_to_tree(bvar); +} + +// Print a function descriptor expression. + +void +Func_descriptor_expression::do_dump_expression(Ast_dump_context* context) const +{ + context->ostream() << "[descriptor " << this->fn_->name() << "]"; +} + +// Make a function descriptor expression. + +Func_descriptor_expression* +Expression::make_func_descriptor(Named_object* fn) +{ + return new Func_descriptor_expression(fn); +} + +// Make the function descriptor type, so that it can be converted. + +void +Expression::make_func_descriptor_type() +{ + Func_descriptor_expression::make_func_descriptor_type(); +} + +// A reference to just the code of a function. + +class Func_code_reference_expression : public Expression +{ + public: + Func_code_reference_expression(Named_object* function, Location location) + : Expression(EXPRESSION_FUNC_CODE_REFERENCE, location), + function_(function) + { } + + protected: + int + do_traverse(Traverse*) + { return TRAVERSE_CONTINUE; } + + Type* + do_type() + { return Type::make_pointer_type(Type::make_void_type()); } + + void + do_determine_type(const Type_context*) + { } + + Expression* + do_copy() + { + return Expression::make_func_code_reference(this->function_, + this->location()); + } + + tree + do_get_tree(Translate_context*); + + void + do_dump_expression(Ast_dump_context* context) const + { context->ostream() << "[raw " << this->function_->name() << "]" ; } + + private: + // The function. + Named_object* function_; +}; + +// Get the tree for a reference to function code. + +tree +Func_code_reference_expression::do_get_tree(Translate_context* context) +{ + return Func_expression::get_code_pointer(context->gogo(), this->function_, + this->location()); +} + +// Make a reference to the code of a function. + +Expression* +Expression::make_func_code_reference(Named_object* function, Location location) +{ + return new Func_code_reference_expression(function, location); +} + // Class Unknown_expression. // Return the name of an unknown expression. @@ -5462,6 +5668,7 @@ if (tleft->is_abstract() && subcontext.type != NULL && !subcontext.may_be_abstract + && subcontext.type->interface_type() == NULL && subcontext.type->integer_type() == NULL) this->report_error(("invalid context-determined non-integer type " "for left operand of shift")); @@ -5641,6 +5848,20 @@ this->set_is_error(); return; } + if (this->op_ == OPERATOR_DIV || this->op_ == OPERATOR_MOD) + { + // Division by a zero integer constant is an error. + Numeric_constant rconst; + unsigned long rval; + if (left_type->integer_type() != NULL + && this->right_->numeric_constant_value(&rconst) + && rconst.to_unsigned_long(&rval) == Numeric_constant::NC_UL_VALID + && rval == 0) + { + this->report_error(_("integer division by zero")); + return; + } + } } else { @@ -6429,20 +6650,49 @@ return Expression::traverse(&this->expr_, traverse); } +// Lower the expression. If this is a method value rather than being +// called, and the method is accessed via a pointer, we may need to +// add nil checks. Introduce a temporary variable so that those nil +// checks do not cause multiple evaluation. + +Expression* +Bound_method_expression::do_lower(Gogo*, Named_object*, + Statement_inserter* inserter, int) +{ + // For simplicity we use a temporary for every call to an embedded + // method, even though some of them might be pure value methods and + // not require a temporary. + if (this->expr_->var_expression() == NULL + && this->expr_->temporary_reference_expression() == NULL + && this->expr_->set_and_use_temporary_expression() == NULL + && (this->method_->field_indexes() != NULL + || (this->method_->is_value_method() + && this->expr_->type()->points_to() != NULL))) + { + Temporary_statement* temp = + Statement::make_temporary(this->expr_->type(), NULL, this->location()); + inserter->insert(temp); + this->expr_ = Expression::make_set_and_use_temporary(temp, this->expr_, + this->location()); + } + return this; +} + // Return the type of a bound method expression. The type of this -// object is really the type of the method with no receiver. We -// should be able to get away with just returning the type of the -// method. +// object is simply the type of the method with no receiver. Type* Bound_method_expression::do_type() { - if (this->method_->is_function()) - return this->method_->func_value()->type(); - else if (this->method_->is_function_declaration()) - return this->method_->func_declaration_value()->type(); + Named_object* fn = this->method_->named_object(); + Function_type* fntype; + if (fn->is_function()) + fntype = fn->func_value()->type(); + else if (fn->is_function_declaration()) + fntype = fn->func_declaration_value()->type(); else return Type::make_error_type(); + return fntype->copy_without_receiver(); } // Determine the types of a method expression. @@ -6450,7 +6700,14 @@ void Bound_method_expression::do_determine_type(const Type_context*) { - Function_type* fntype = this->type()->function_type(); + Named_object* fn = this->method_->named_object(); + Function_type* fntype; + if (fn->is_function()) + fntype = fn->func_value()->type(); + else if (fn->is_function_declaration()) + fntype = fn->func_declaration_value()->type(); + else + fntype = NULL; if (fntype == NULL || !fntype->is_method()) this->expr_->determine_type_no_context(); else @@ -6465,31 +6722,278 @@ void Bound_method_expression::do_check_types(Gogo*) { - if (!this->method_->is_function() - && !this->method_->is_function_declaration()) - this->report_error(_("object is not a method")); + Named_object* fn = this->method_->named_object(); + if (!fn->is_function() && !fn->is_function_declaration()) + { + this->report_error(_("object is not a method")); + return; + } + + Function_type* fntype; + if (fn->is_function()) + fntype = fn->func_value()->type(); + else if (fn->is_function_declaration()) + fntype = fn->func_declaration_value()->type(); else + go_unreachable(); + Type* rtype = fntype->receiver()->type()->deref(); + Type* etype = (this->expr_type_ != NULL + ? this->expr_type_ + : this->expr_->type()); + etype = etype->deref(); + if (!Type::are_identical(rtype, etype, true, NULL)) + this->report_error(_("method type does not match object type")); +} + +// If a bound method expression is not simply called, then it is +// represented as a closure. The closure will hold a single variable, +// the receiver to pass to the method. The function will be a simple +// thunk that pulls that value from the closure and calls the method +// with the remaining arguments. +// +// Because method values are not common, we don't build all thunks for +// every methods, but instead only build them as we need them. In +// particular, we even build them on demand for methods defined in +// other packages. + +Bound_method_expression::Method_value_thunks + Bound_method_expression::method_value_thunks; + +// Find or create the thunk for METHOD. + +Named_object* +Bound_method_expression::create_thunk(Gogo* gogo, const Method* method, + Named_object* fn) +{ + std::pair val(fn, NULL); + std::pair ins = + Bound_method_expression::method_value_thunks.insert(val); + if (!ins.second) { - Type* rtype = this->type()->function_type()->receiver()->type()->deref(); - Type* etype = (this->expr_type_ != NULL - ? this->expr_type_ - : this->expr_->type()); - etype = etype->deref(); - if (!Type::are_identical(rtype, etype, true, NULL)) - this->report_error(_("method type does not match object type")); + // We have seen this method before. + go_assert(ins.first->second != NULL); + return ins.first->second; } + + Location loc = fn->location(); + + Function_type* orig_fntype; + if (fn->is_function()) + orig_fntype = fn->func_value()->type(); + else if (fn->is_function_declaration()) + orig_fntype = fn->func_declaration_value()->type(); + else + orig_fntype = NULL; + + if (orig_fntype == NULL || !orig_fntype->is_method()) + { + ins.first->second = Named_object::make_erroneous_name(Gogo::thunk_name()); + return ins.first->second; + } + + Struct_field_list* sfl = new Struct_field_list(); + // The type here is wrong--it should be new_fntype. But we don't + // have new_fntype yet, and it doesn't really matter. + Type* vt = Type::make_pointer_type(Type::make_void_type()); + sfl->push_back(Struct_field(Typed_identifier("fn.0", vt, loc))); + sfl->push_back(Struct_field(Typed_identifier("val.1", + orig_fntype->receiver()->type(), + loc))); + Type* closure_type = Type::make_struct_type(sfl, loc); + closure_type = Type::make_pointer_type(closure_type); + + Function_type* new_fntype = orig_fntype->copy_with_closure(closure_type); + + Named_object* new_no = gogo->start_function(Gogo::thunk_name(), new_fntype, + false, loc); + + gogo->start_block(loc); + + Named_object* cp = gogo->lookup("closure.0", NULL); + go_assert(cp != NULL + && cp->is_variable() + && cp->var_value()->is_parameter()); + + // Field 0 of the closure is the function code pointer, field 1 is + // the value on which to invoke the method. + Expression* arg = Expression::make_var_reference(cp, loc); + arg = Expression::make_unary(OPERATOR_MULT, arg, loc); + arg = Expression::make_field_reference(arg, 1, loc); + + Expression* bme = Expression::make_bound_method(arg, method, fn, loc); + + const Typed_identifier_list* orig_params = orig_fntype->parameters(); + Expression_list* args; + if (orig_params == NULL || orig_params->empty()) + args = NULL; + else + { + const Typed_identifier_list* new_params = new_fntype->parameters(); + args = new Expression_list(); + for (Typed_identifier_list::const_iterator p = new_params->begin(); + p + 1 != new_params->end(); + ++p) + { + Named_object* p_no = gogo->lookup(p->name(), NULL); + go_assert(p_no != NULL + && p_no->is_variable() + && p_no->var_value()->is_parameter()); + args->push_back(Expression::make_var_reference(p_no, loc)); + } + } + + Call_expression* call = Expression::make_call(bme, args, + orig_fntype->is_varargs(), + loc); + call->set_varargs_are_lowered(); + + Statement* s = Statement::make_return_from_call(call, loc); + gogo->add_statement(s); + Block* b = gogo->finish_block(loc); + gogo->add_block(b, loc); + gogo->lower_block(new_no, b); + gogo->finish_function(loc); + + ins.first->second = new_no; + return new_no; +} + +// Return an expression to check *REF for nil while dereferencing +// according to FIELD_INDEXES. Update *REF to build up the field +// reference. This is a static function so that we don't have to +// worry about declaring Field_indexes in expressions.h. + +static Expression* +bme_check_nil(const Method::Field_indexes* field_indexes, Location loc, + Expression** ref) +{ + if (field_indexes == NULL) + return Expression::make_boolean(false, loc); + Expression* cond = bme_check_nil(field_indexes->next, loc, ref); + Struct_type* stype = (*ref)->type()->deref()->struct_type(); + go_assert(stype != NULL + && field_indexes->field_index < stype->field_count()); + if ((*ref)->type()->struct_type() == NULL) + { + go_assert((*ref)->type()->points_to() != NULL); + Expression* n = Expression::make_binary(OPERATOR_EQEQ, *ref, + Expression::make_nil(loc), + loc); + cond = Expression::make_binary(OPERATOR_OROR, cond, n, loc); + *ref = Expression::make_unary(OPERATOR_MULT, *ref, loc); + go_assert((*ref)->type()->struct_type() == stype); + } + *ref = Expression::make_field_reference(*ref, field_indexes->field_index, + loc); + return cond; } -// Get the tree for a method expression. There is no standard tree -// representation for this. The only places it may currently be used -// are in a Call_expression or a Go_statement, which will take it -// apart directly. So this has nothing to do at present. +// Get the tree for a method value. tree -Bound_method_expression::do_get_tree(Translate_context*) +Bound_method_expression::do_get_tree(Translate_context* context) { - error_at(this->location(), "reference to method other than calling it"); - return error_mark_node; + Named_object* thunk = Bound_method_expression::create_thunk(context->gogo(), + this->method_, + this->function_); + if (thunk->is_erroneous()) + { + go_assert(saw_errors()); + return error_mark_node; + } + + // FIXME: We should lower this earlier, but we can't lower it in the + // lowering pass because at that point we don't know whether we need + // to create the thunk or not. If the expression is called, we + // don't need the thunk. + + Location loc = this->location(); + + // If the method expects a value, and we have a pointer, we need to + // dereference the pointer. + + Named_object* fn = this->method_->named_object(); + Function_type* fntype; + if (fn->is_function()) + fntype = fn->func_value()->type(); + else if (fn->is_function_declaration()) + fntype = fn->func_declaration_value()->type(); + else + go_unreachable(); + + Expression* val = this->expr_; + if (fntype->receiver()->type()->points_to() == NULL + && val->type()->points_to() != NULL) + val = Expression::make_unary(OPERATOR_MULT, val, loc); + + // Note that we are ignoring this->expr_type_ here. The thunk will + // expect a closure whose second field has type this->expr_type_ (if + // that is not NULL). We are going to pass it a closure whose + // second field has type this->expr_->type(). Since + // this->expr_type_ is only not-NULL for pointer types, we can get + // away with this. + + Struct_field_list* fields = new Struct_field_list(); + fields->push_back(Struct_field(Typed_identifier("fn.0", + thunk->func_value()->type(), + loc))); + fields->push_back(Struct_field(Typed_identifier("val.1", val->type(), loc))); + Struct_type* st = Type::make_struct_type(fields, loc); + + Expression_list* vals = new Expression_list(); + vals->push_back(Expression::make_func_code_reference(thunk, loc)); + vals->push_back(val); + + Expression* ret = Expression::make_struct_composite_literal(st, vals, loc); + ret = Expression::make_heap_composite(ret, loc); + + tree ret_tree = ret->get_tree(context); + + Expression* nil_check = NULL; + + // See whether the expression or any embedded pointers are nil. + + Expression* expr = this->expr_; + if (this->method_->field_indexes() != NULL) + { + // Note that we are evaluating this->expr_ twice, but that is OK + // because in the lowering pass we forced it into a temporary + // variable. + Expression* ref = expr; + nil_check = bme_check_nil(this->method_->field_indexes(), loc, &ref); + expr = ref; + } + + if (this->method_->is_value_method() && expr->type()->points_to() != NULL) + { + Expression* n = Expression::make_binary(OPERATOR_EQEQ, expr, + Expression::make_nil(loc), + loc); + if (nil_check == NULL) + nil_check = n; + else + nil_check = Expression::make_binary(OPERATOR_OROR, nil_check, n, loc); + } + + if (nil_check != NULL) + { + tree nil_check_tree = nil_check->get_tree(context); + tree crash = + context->gogo()->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, loc); + if (ret_tree == error_mark_node + || nil_check_tree == error_mark_node + || crash == error_mark_node) + return error_mark_node; + + ret_tree = fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR, + TREE_TYPE(ret_tree), + build3_loc(loc.gcc_location(), COND_EXPR, + void_type_node, nil_check_tree, + crash, NULL_TREE), + ret_tree); + } + + return ret_tree; } // Dump ast representation of a bound method expression. @@ -6508,16 +7012,16 @@ ast_dump_context->ostream() << ")"; } - ast_dump_context->ostream() << "." << this->method_->name(); + ast_dump_context->ostream() << "." << this->function_->name(); } // Make a method expression. Bound_method_expression* -Expression::make_bound_method(Expression* expr, Named_object* method, - Location location) +Expression::make_bound_method(Expression* expr, const Method* method, + Named_object* function, Location location) { - return new Bound_method_expression(expr, method, location); + return new Bound_method_expression(expr, method, function, location); } // Class Builtin_call_expression. This is used for a call to a @@ -6722,6 +7226,26 @@ return Expression::make_error(loc); } + if (this->code_ == BUILTIN_OFFSETOF) + { + Expression* arg = this->one_arg(); + Field_reference_expression* farg = arg->field_reference_expression(); + while (farg != NULL) + { + if (!farg->implicit()) + break; + // When the selector refers to an embedded field, + // it must not be reached through pointer indirections. + if (farg->expr()->deref() != farg->expr()) + { + this->report_error(_("argument of Offsetof implies indirection of an embedded field")); + return this; + } + // Go up until we reach the original base. + farg = farg->expr()->field_reference_expression(); + } + } + if (this->is_constant()) { Numeric_constant nc; @@ -6874,6 +7398,8 @@ Type* uintptr_type = Type::lookup_integer_type("uintptr"); int uintptr_bits = uintptr_type->integer_type()->bits(); + Type_context int_context(Type::lookup_integer_type("int"), false); + ++parg; Expression* len_arg; if (parg == args->end()) @@ -6892,6 +7418,7 @@ else { len_arg = *parg; + len_arg->determine_type(&int_context); if (!this->check_int_value(len_arg, true)) return Expression::make_error(this->location()); if (len_arg->type()->integer_type() != NULL @@ -6904,6 +7431,7 @@ if (is_slice && parg != args->end()) { cap_arg = *parg; + cap_arg->determine_type(&int_context); if (!this->check_int_value(cap_arg, false)) return Expression::make_error(this->location()); @@ -7279,19 +7807,31 @@ Field_reference_expression* farg = arg->field_reference_expression(); if (farg == NULL) return false; - Expression* struct_expr = farg->expr(); - Type* st = struct_expr->type(); - if (st->struct_type() == NULL) - return false; - if (st->named_type() != NULL) - st->named_type()->convert(this->gogo_); - unsigned int offset; - if (!st->struct_type()->backend_field_offset(this->gogo_, - farg->field_index(), - &offset)) - return false; + unsigned int total_offset = 0; + while (true) + { + Expression* struct_expr = farg->expr(); + Type* st = struct_expr->type(); + if (st->struct_type() == NULL) + return false; + if (st->named_type() != NULL) + st->named_type()->convert(this->gogo_); + unsigned int offset; + if (!st->struct_type()->backend_field_offset(this->gogo_, + farg->field_index(), + &offset)) + return false; + total_offset += offset; + if (farg->implicit() && struct_expr->field_reference_expression() != NULL) + { + // Go up until we reach the original base. + farg = struct_expr->field_reference_expression(); + continue; + } + break; + } nc->set_unsigned_long(Type::lookup_integer_type("uintptr"), - static_cast(offset)); + static_cast(total_offset)); return true; } else if (this->code_ == BUILTIN_REAL || this->code_ == BUILTIN_IMAG) @@ -7509,6 +8049,8 @@ case BUILTIN_REAL: case BUILTIN_IMAG: arg_type = Builtin_call_expression::complex_type(context->type); + if (arg_type == NULL) + arg_type = Type::lookup_complex_type("complex128"); is_print = false; break; @@ -7517,6 +8059,8 @@ // For the complex function the type of one operand can // determine the type of the other, as in a binary expression. arg_type = Builtin_call_expression::real_imag_type(context->type); + if (arg_type == NULL) + arg_type = Type::lookup_float_type("float64"); if (args != NULL && args->size() == 2) { Type* t1 = args->front()->type(); @@ -8509,6 +9053,74 @@ // Class Call_expression. +// A Go function can be viewed in a couple of different ways. The +// code of a Go function becomes a backend function with parameters +// whose types are simply the backend representation of the Go types. +// If there are multiple results, they are returned as a backend +// struct. + +// However, when Go code refers to a function other than simply +// calling it, the backend type of that function is actually a struct. +// The first field of the struct points to the Go function code +// (sometimes a wrapper as described below). The remaining fields +// hold addresses of closed-over variables. This struct is called a +// closure. + +// There are a few cases to consider. + +// A direct function call of a known function in package scope. In +// this case there are no closed-over variables, and we know the name +// of the function code. We can simply produce a backend call to the +// function directly, and not worry about the closure. + +// A direct function call of a known function literal. In this case +// we know the function code and we know the closure. We generate the +// function code such that it expects an additional final argument of +// the closure type. We pass the closure as the last argument, after +// the other arguments. + +// An indirect function call. In this case we have a closure. We +// load the pointer to the function code from the first field of the +// closure. We pass the address of the closure as the last argument. + +// A call to a method of an interface. Type methods are always at +// package scope, so we call the function directly, and don't worry +// about the closure. + +// This means that for a function at package scope we have two cases. +// One is the direct call, which has no closure. The other is the +// indirect call, which does have a closure. We can't simply ignore +// the closure, even though it is the last argument, because that will +// fail on targets where the function pops its arguments. So when +// generating a closure for a package-scope function we set the +// function code pointer in the closure to point to a wrapper +// function. This wrapper function accepts a final argument that +// points to the closure, ignores it, and calls the real function as a +// direct function call. This wrapper will normally be efficient, and +// can often simply be a tail call to the real function. + +// We don't use GCC's static chain pointer because 1) we don't need +// it; 2) GCC only permits using a static chain to call a known +// function, so we can't use it for an indirect call anyhow. Since we +// can't use it for an indirect call, we may as well not worry about +// using it for a direct call either. + +// We pass the closure last rather than first because it means that +// the function wrapper we put into a closure for a package-scope +// function can normally just be a tail call to the real function. + +// For method expressions we generate a wrapper that loads the +// receiver from the closure and then calls the method. This +// unfortunately forces reshuffling the arguments, since there is a +// new first argument, but we can't avoid reshuffling either for +// method expressions or for indirect calls of package-scope +// functions, and since the latter are more common we reshuffle for +// method expressions. + +// Note that the Go code retains the Go types. The extra final +// argument only appears when we convert to the backend +// representation. + // Traversal. int @@ -8624,7 +9236,7 @@ Bound_method_expression* bme = this->fn_->bound_method_expression(); if (bme != NULL) { - Named_object* method = bme->method(); + Named_object* methodfn = bme->function(); Expression* first_arg = bme->first_argument(); // We always pass a pointer when calling a method. @@ -8665,7 +9277,7 @@ // old arguments, because we may be traversing them up in some // caller. FIXME. this->args_ = new_args; - this->fn_ = Expression::make_func_reference(method, NULL, + this->fn_ = Expression::make_func_reference(methodfn, NULL, bme->location()); } @@ -9117,11 +9729,21 @@ const bool has_closure = func != NULL && func->closure() != NULL; const bool is_interface_method = interface_method != NULL; + int closure_arg; + if (has_closure) + closure_arg = 1; + else if (func != NULL) + closure_arg = 0; + else if (is_interface_method) + closure_arg = 0; + else + closure_arg = 1; + int nargs; tree* args; if (this->args_ == NULL || this->args_->empty()) { - nargs = is_interface_method ? 1 : 0; + nargs = (is_interface_method ? 1 : 0) + closure_arg; args = nargs == 0 ? NULL : new tree[nargs]; } else if (fntype->parameters() == NULL || fntype->parameters()->empty()) @@ -9130,7 +9752,7 @@ go_assert(!is_interface_method && fntype->is_method() && this->args_->size() == 1); - nargs = 1; + nargs = 1 + closure_arg; args = new tree[nargs]; args[0] = this->args_->front()->get_tree(context); } @@ -9141,6 +9763,7 @@ nargs = this->args_->size(); int i = is_interface_method ? 1 : 0; nargs += i; + nargs += closure_arg; args = new tree[nargs]; Typed_identifier_list::const_iterator pp = params->begin(); @@ -9161,36 +9784,71 @@ arg_val, location); if (args[i] == error_mark_node) - { - delete[] args; - return error_mark_node; - } + return error_mark_node; } go_assert(pp == params->end()); - go_assert(i == nargs); + go_assert(i + closure_arg == nargs); } - tree rettype = TREE_TYPE(TREE_TYPE(type_to_tree(fntype->get_backend(gogo)))); + tree fntype_tree = type_to_tree(fntype->get_backend(gogo)); + if (fntype_tree == error_mark_node) + return error_mark_node; + go_assert(POINTER_TYPE_P(fntype_tree)); + if (TREE_TYPE(fntype_tree) == error_mark_node) + return error_mark_node; + go_assert(TREE_CODE(TREE_TYPE(fntype_tree)) == RECORD_TYPE); + tree fnfield_type = TREE_TYPE(TYPE_FIELDS(TREE_TYPE(fntype_tree))); + if (fnfield_type == error_mark_node) + return error_mark_node; + go_assert(FUNCTION_POINTER_TYPE_P(fnfield_type)); + tree rettype = TREE_TYPE(TREE_TYPE(fnfield_type)); if (rettype == error_mark_node) - { - delete[] args; - return error_mark_node; - } + return error_mark_node; tree fn; - if (has_closure) - fn = func->get_tree_without_closure(gogo); + if (func != NULL) + { + Named_object* no = func->named_object(); + go_assert(!no->is_function() + || !no->func_value()->is_descriptor_wrapper()); + fn = Func_expression::get_code_pointer(gogo, no, location); + if (has_closure) + { + go_assert(closure_arg == 1 && nargs > 0); + args[nargs - 1] = func->closure()->get_tree(context); + } + } else if (!is_interface_method) - fn = this->fn_->get_tree(context); - else - fn = this->interface_method_function(context, interface_method, &args[0]); - - if (fn == error_mark_node || TREE_TYPE(fn) == error_mark_node) { - delete[] args; - return error_mark_node; + tree closure_tree = this->fn_->get_tree(context); + if (closure_tree == error_mark_node) + return error_mark_node; + tree fnc = fold_convert_loc(location.gcc_location(), fntype_tree, + closure_tree); + go_assert(POINTER_TYPE_P(TREE_TYPE(fnc)) + && (TREE_CODE(TREE_TYPE(TREE_TYPE(fnc))) + == RECORD_TYPE)); + tree field = TYPE_FIELDS(TREE_TYPE(TREE_TYPE(fnc))); + fn = fold_build3_loc(location.gcc_location(), COMPONENT_REF, + TREE_TYPE(field), + build_fold_indirect_ref_loc(location.gcc_location(), + fnc), + field, NULL_TREE); + go_assert(closure_arg == 1 && nargs > 0); + args[nargs - 1] = closure_tree; + } + else + { + fn = this->interface_method_function(context, interface_method, + &args[0]); + if (fn == error_mark_node) + return error_mark_node; + go_assert(closure_arg == 0); } + if (fn == error_mark_node || TREE_TYPE(fn) == error_mark_node) + return error_mark_node; + tree fndecl = fn; if (TREE_CODE(fndecl) == ADDR_EXPR) fndecl = TREE_OPERAND(fndecl, 0); @@ -9198,12 +9856,7 @@ // Add a type cast in case the type of the function is a recursive // type which refers to itself. if (!DECL_P(fndecl) || !DECL_IS_BUILTIN(fndecl)) - { - tree fnt = type_to_tree(fntype->get_backend(gogo)); - if (fnt == error_mark_node) - return error_mark_node; - fn = fold_convert_loc(location.gcc_location(), fnt, fn); - } + fn = fold_convert_loc(location.gcc_location(), fnfield_type, fn); // This is to support builtin math functions when using 80387 math. tree excess_type = NULL_TREE; @@ -9247,13 +9900,6 @@ SET_EXPR_LOCATION(ret, location.gcc_location()); - if (has_closure) - { - tree closure_tree = func->closure()->get_tree(context); - if (closure_tree != error_mark_node) - CALL_EXPR_STATIC_CHAIN(ret) = closure_tree; - } - // If this is a recursive function type which returns itself, as in // type F func() F // we have used ptr_type_node for the return type. Add a cast here @@ -9274,24 +9920,6 @@ if (this->results_ != NULL) ret = this->set_results(context, ret); - // We can't unwind the stack past a call to nil, so we need to - // insert an explicit check so that the panic can be recovered. - if (func == NULL) - { - tree compare = fold_build2_loc(location.gcc_location(), EQ_EXPR, - boolean_type_node, fn, - fold_convert_loc(location.gcc_location(), - TREE_TYPE(fn), - null_pointer_node)); - tree crash = build3_loc(location.gcc_location(), COND_EXPR, - void_type_node, compare, - gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, - location), - NULL_TREE); - ret = fold_build2_loc(location.gcc_location(), COMPOUND_EXPR, - TREE_TYPE(ret), crash, ret); - } - this->tree_ = ret; return ret; @@ -9774,13 +10402,20 @@ void Array_index_expression::do_check_types(Gogo*) { - if (this->start_->type()->integer_type() == NULL) + Numeric_constant nc; + unsigned long v; + if (this->start_->type()->integer_type() == NULL + && !this->start_->type()->is_error() + && (!this->start_->numeric_constant_value(&nc) + || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT)) this->report_error(_("index must be integer")); if (this->end_ != NULL && this->end_->type()->integer_type() == NULL && !this->end_->type()->is_error() && !this->end_->is_nil_expression() - && !this->end_->is_error_expression()) + && !this->end_->is_error_expression() + && (!this->end_->numeric_constant_value(&nc) + || nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_NOTINT)) this->report_error(_("slice end must be integer")); Array_type* array_type = this->array_->type()->array_type(); @@ -10845,6 +11480,28 @@ return Expression::traverse(&this->expr_, traverse); } +// Lower the expression. If this expression is not called, we need to +// evaluate the expression twice when converting to the backend +// interface. So introduce a temporary variable if necessary. + +Expression* +Interface_field_reference_expression::do_lower(Gogo*, Named_object*, + Statement_inserter* inserter, + int) +{ + if (this->expr_->var_expression() == NULL + && this->expr_->temporary_reference_expression() == NULL + && this->expr_->set_and_use_temporary_expression() == NULL) + { + Temporary_statement* temp = + Statement::make_temporary(this->expr_->type(), NULL, this->location()); + inserter->insert(temp); + this->expr_ = Expression::make_set_and_use_temporary(temp, this->expr_, + this->location()); + } + return this; +} + // Return the type of an interface field reference. Type* @@ -10905,18 +11562,188 @@ } } -// Get a tree for a reference to a field in an interface. There is no -// standard tree type representation for this: it's a function -// attached to its first argument, like a Bound_method_expression. -// The only places it may currently be used are in a Call_expression -// or a Go_statement, which will take it apart directly. So this has -// nothing to do at present. +// If an interface field reference is not simply called, then it is +// represented as a closure. The closure will hold a single variable, +// the value of the interface on which the method should be called. +// The function will be a simple thunk that pulls the value from the +// closure and calls the method with the remaining arguments. + +// Because method values are not common, we don't build all thunks for +// all possible interface methods, but instead only build them as we +// need them. In particular, we even build them on demand for +// interface methods defined in other packages. + +Interface_field_reference_expression::Interface_method_thunks + Interface_field_reference_expression::interface_method_thunks; + +// Find or create the thunk to call method NAME on TYPE. + +Named_object* +Interface_field_reference_expression::create_thunk(Gogo* gogo, + Interface_type* type, + const std::string& name) +{ + std::pair val(type, NULL); + std::pair ins = + Interface_field_reference_expression::interface_method_thunks.insert(val); + if (ins.second) + { + // This is the first time we have seen this interface. + ins.first->second = new Method_thunks(); + } + + for (Method_thunks::const_iterator p = ins.first->second->begin(); + p != ins.first->second->end(); + p++) + if (p->first == name) + return p->second; + + Location loc = type->location(); + + const Typed_identifier* method_id = type->find_method(name); + if (method_id == NULL) + return Named_object::make_erroneous_name(Gogo::thunk_name()); + + Function_type* orig_fntype = method_id->type()->function_type(); + if (orig_fntype == NULL) + return Named_object::make_erroneous_name(Gogo::thunk_name()); + + Struct_field_list* sfl = new Struct_field_list(); + // The type here is wrong--it should be new_fntype. But we don't + // have new_fntype yet, and it doesn't really matter. + Type* vt = Type::make_pointer_type(Type::make_void_type()); + sfl->push_back(Struct_field(Typed_identifier("fn.0", vt, loc))); + sfl->push_back(Struct_field(Typed_identifier("val.1", type, loc))); + Type* closure_type = Type::make_struct_type(sfl, loc); + closure_type = Type::make_pointer_type(closure_type); + + Function_type* new_fntype = orig_fntype->copy_with_closure(closure_type); + + Named_object* new_no = gogo->start_function(Gogo::thunk_name(), new_fntype, + false, loc); + + gogo->start_block(loc); + + Named_object* cp = gogo->lookup("closure.0", NULL); + go_assert(cp != NULL + && cp->is_variable() + && cp->var_value()->is_parameter()); + + // Field 0 of the closure is the function code pointer, field 1 is + // the value on which to invoke the method. + Expression* arg = Expression::make_var_reference(cp, loc); + arg = Expression::make_unary(OPERATOR_MULT, arg, loc); + arg = Expression::make_field_reference(arg, 1, loc); + + Expression *ifre = Expression::make_interface_field_reference(arg, name, + loc); + + const Typed_identifier_list* orig_params = orig_fntype->parameters(); + Expression_list* args; + if (orig_params == NULL || orig_params->empty()) + args = NULL; + else + { + const Typed_identifier_list* new_params = new_fntype->parameters(); + args = new Expression_list(); + for (Typed_identifier_list::const_iterator p = new_params->begin(); + p + 1 != new_params->end(); + ++p) + { + Named_object* p_no = gogo->lookup(p->name(), NULL); + go_assert(p_no != NULL + && p_no->is_variable() + && p_no->var_value()->is_parameter()); + args->push_back(Expression::make_var_reference(p_no, loc)); + } + } + + Call_expression* call = Expression::make_call(ifre, args, + orig_fntype->is_varargs(), + loc); + call->set_varargs_are_lowered(); + + Statement* s = Statement::make_return_from_call(call, loc); + gogo->add_statement(s); + Block* b = gogo->finish_block(loc); + gogo->add_block(b, loc); + gogo->lower_block(new_no, b); + gogo->finish_function(loc); + + ins.first->second->push_back(std::make_pair(name, new_no)); + return new_no; +} + +// Get a tree for a method value. tree -Interface_field_reference_expression::do_get_tree(Translate_context*) +Interface_field_reference_expression::do_get_tree(Translate_context* context) { - error_at(this->location(), "reference to method other than calling it"); - return error_mark_node; + Interface_type* type = this->expr_->type()->interface_type(); + if (type == NULL) + { + go_assert(saw_errors()); + return error_mark_node; + } + + Named_object* thunk = + Interface_field_reference_expression::create_thunk(context->gogo(), + type, this->name_); + if (thunk->is_erroneous()) + { + go_assert(saw_errors()); + return error_mark_node; + } + + // FIXME: We should lower this earlier, but we can't it lower it in + // the lowering pass because at that point we don't know whether we + // need to create the thunk or not. If the expression is called, we + // don't need the thunk. + + Location loc = this->location(); + + Struct_field_list* fields = new Struct_field_list(); + fields->push_back(Struct_field(Typed_identifier("fn.0", + thunk->func_value()->type(), + loc))); + fields->push_back(Struct_field(Typed_identifier("val.1", + this->expr_->type(), + loc))); + Struct_type* st = Type::make_struct_type(fields, loc); + + Expression_list* vals = new Expression_list(); + vals->push_back(Expression::make_func_code_reference(thunk, loc)); + vals->push_back(this->expr_); + + Expression* expr = Expression::make_struct_composite_literal(st, vals, loc); + expr = Expression::make_heap_composite(expr, loc); + + tree closure_tree = expr->get_tree(context); + + // Note that we are evaluating this->expr_ twice, but that is OK + // because in the lowering pass we forced it into a temporary + // variable. + tree expr_tree = this->expr_->get_tree(context); + tree nil_check_tree = Expression::comparison_tree(context, + Type::lookup_bool_type(), + OPERATOR_EQEQ, + this->expr_->type(), + expr_tree, + Type::make_nil_type(), + null_pointer_node, + loc); + tree crash = context->gogo()->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, + loc); + if (closure_tree == error_mark_node + || nil_check_tree == error_mark_node + || crash == error_mark_node) + return error_mark_node; + return fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR, + TREE_TYPE(closure_tree), + build3_loc(loc.gcc_location(), COND_EXPR, + void_type_node, nil_check_tree, crash, + NULL_TREE), + closure_tree); } // Dump ast representation for an interface field reference. @@ -11114,8 +11941,10 @@ // as their first argument. If this is for a pointer type, we can // simply reuse the existing function. We use an internal hack to // get the right type. - - if (method != NULL && is_pointer) + // FIXME: This optimization is disabled because it doesn't yet work + // with function descriptors when the method expression is not + // directly called. + if (method != NULL && is_pointer && false) { Named_object* mno = (method->needs_stub_method() ? method->stub_object() @@ -11170,22 +11999,7 @@ method_type->is_varargs(), location); - size_t count = call->result_count(); - Statement* s; - if (count == 0) - s = Statement::make_statement(call, true); - else - { - Expression_list* retvals = new Expression_list(); - if (count <= 1) - retvals->push_back(call); - else - { - for (size_t i = 0; i < count; ++i) - retvals->push_back(Expression::make_call_result(call, i)); - } - s = Statement::make_return_statement(retvals, location); - } + Statement* s = Statement::make_return_from_call(call, location); gogo->add_statement(s); Block* b = gogo->finish_block(location); diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/expressions.h gcc-4.8.1/gcc/go/gofrontend/expressions.h --- gcc-4.8.1.orig/gcc/go/gofrontend/expressions.h 2013-01-28 18:28:09.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/expressions.h 2013-06-24 17:11:25.306173000 -0500 @@ -16,6 +16,7 @@ class Traverse; class Statement_inserter; class Type; +class Method; struct Type_context; class Integer_type; class Float_type; @@ -32,6 +33,7 @@ class Binary_expression; class Call_expression; class Func_expression; +class Func_descriptor_expression; class Unknown_expression; class Index_expression; class Map_index_expression; @@ -67,6 +69,8 @@ EXPRESSION_SET_AND_USE_TEMPORARY, EXPRESSION_SINK, EXPRESSION_FUNC_REFERENCE, + EXPRESSION_FUNC_DESCRIPTOR, + EXPRESSION_FUNC_CODE_REFERENCE, EXPRESSION_UNKNOWN_REFERENCE, EXPRESSION_BOOLEAN, EXPRESSION_STRING, @@ -150,10 +154,24 @@ static Expression* make_sink(Location); - // Make a reference to a function in an expression. + // Make a reference to a function in an expression. This returns a + // pointer to the struct holding the address of the function + // followed by any closed-over variables. static Expression* make_func_reference(Named_object*, Expression* closure, Location); + // Make a function descriptor, an immutable struct with a single + // field that points to the function code. This may only be used + // with functions that do not have closures. FN is the function for + // which we are making the descriptor. + static Func_descriptor_expression* + make_func_descriptor(Named_object* fn); + + // Make a reference to the code of a function. This is used to set + // descriptor and closure fields. + static Expression* + make_func_code_reference(Named_object*, Location); + // Make a reference to an unknown name. In a correct program this // will always be lowered to a real const/var/func reference. static Unknown_expression* @@ -207,9 +225,11 @@ make_call_result(Call_expression*, unsigned int index); // Make an expression which is a method bound to its first - // parameter. + // parameter. METHOD is the method being called, FUNCTION is the + // function to call. static Bound_method_expression* - make_bound_method(Expression* object, Named_object* method, Location); + make_bound_method(Expression* object, const Method* method, + Named_object* function, Location); // Make an index or slice expression. This is a parser expression // which represents LEFT[START:END]. END may be NULL, meaning an @@ -523,6 +543,11 @@ bool is_local_variable() const; + // Make the builtin function descriptor type, so that it can be + // converted. + static void + make_func_descriptor_type(); + // Traverse an expression. static int traverse(Expression**, Traverse*); @@ -1057,8 +1082,7 @@ do_type(); void - do_determine_type(const Type_context*) - { } + do_determine_type(const Type_context*); Expression* do_copy() @@ -1484,7 +1508,7 @@ { } // Return the object associated with the function. - const Named_object* + Named_object* named_object() const { return this->function_; } @@ -1494,9 +1518,9 @@ closure() { return this->closure_; } - // Return a tree for this function without evaluating the closure. - tree - get_tree_without_closure(Gogo*); + // Return a tree for the code for a function. + static tree + get_code_pointer(Gogo*, Named_object* function, Location loc); protected: int @@ -1532,11 +1556,68 @@ // The function itself. Named_object* function_; // A closure. This is normally NULL. For a nested function, it may - // be a heap-allocated struct holding pointers to all the variables - // referenced by this function and defined in enclosing functions. + // be a struct holding pointers to all the variables referenced by + // this function and defined in enclosing functions. Expression* closure_; }; +// A function descriptor. A function descriptor is a struct with a +// single field pointing to the function code. This is used for +// functions without closures. + +class Func_descriptor_expression : public Expression +{ + public: + Func_descriptor_expression(Named_object* fn); + + // Set the descriptor wrapper. + void + set_descriptor_wrapper(Named_object* dfn) + { + go_assert(this->dfn_ == NULL); + this->dfn_ = dfn; + } + + // Make the function descriptor type, so that it can be converted. + static void + make_func_descriptor_type(); + + protected: + int + do_traverse(Traverse*); + + Type* + do_type(); + + void + do_determine_type(const Type_context*) + { } + + Expression* + do_copy(); + + bool + do_is_addressable() const + { return true; } + + tree + do_get_tree(Translate_context*); + + void + do_dump_expression(Ast_dump_context* context) const; + + private: + // The type of all function descriptors. + static Type* descriptor_type; + + // The function for which this is the descriptor. + Named_object* fn_; + // The descriptor function. + Named_object* dfn_; + // The descriptor variable. + Bvariable* dvar_; +}; + // A reference to an unknown name. class Unknown_expression : public Parser_expression @@ -1773,10 +1854,10 @@ class Bound_method_expression : public Expression { public: - Bound_method_expression(Expression* expr, Named_object* method, - Location location) + Bound_method_expression(Expression* expr, const Method *method, + Named_object* function, Location location) : Expression(EXPRESSION_BOUND_METHOD, location), - expr_(expr), expr_type_(NULL), method_(method) + expr_(expr), expr_type_(NULL), method_(method), function_(function) { } // Return the object which is the first argument. @@ -1791,20 +1872,33 @@ first_argument_type() const { return this->expr_type_; } - // Return the method function. - Named_object* - method() + // Return the method. + const Method* + method() const { return this->method_; } + // Return the function to call. + Named_object* + function() const + { return this->function_; } + // Set the implicit type of the expression. void set_first_argument_type(Type* type) { this->expr_type_ = type; } + // Create a thunk to call FUNCTION, for METHOD, when it is used as + // part of a method value. + static Named_object* + create_thunk(Gogo*, const Method* method, Named_object* function); + protected: int do_traverse(Traverse*); + Expression* + do_lower(Gogo*, Named_object*, Statement_inserter*, int); + Type* do_type(); @@ -1818,7 +1912,7 @@ do_copy() { return new Bound_method_expression(this->expr_->copy(), this->method_, - this->location()); + this->function_, this->location()); } tree @@ -1828,6 +1922,11 @@ do_dump_expression(Ast_dump_context*) const; private: + // A mapping from method functions to the thunks we have created for + // them. + typedef Unordered_map(Named_object*, Named_object*) Method_value_thunks; + static Method_value_thunks method_value_thunks; + // The object used to find the method. This is passed to the method // as the first argument. Expression* expr_; @@ -1835,8 +1934,12 @@ // NULL in the normal case, non-NULL when using a method from an // anonymous field which does not require a stub. Type* expr_type_; - // The method itself. - Named_object* method_; + // The method. + const Method* method_; + // The function to call. This is not the same as + // method_->named_object() when the method has a stub. This will be + // the real function rather than the stub. + Named_object* function_; }; // A reference to a field in a struct. @@ -1847,7 +1950,7 @@ Field_reference_expression(Expression* expr, unsigned int field_index, Location location) : Expression(EXPRESSION_FIELD_REFERENCE, location), - expr_(expr), field_index_(field_index), called_fieldtrack_(false) + expr_(expr), field_index_(field_index), implicit_(false), called_fieldtrack_(false) { } // Return the struct expression. @@ -1860,6 +1963,15 @@ field_index() const { return this->field_index_; } + // Return whether this node was implied by an anonymous field. + bool + implicit() const + { return this->implicit_; } + + void + set_implicit(bool implicit) + { this->implicit_ = implicit; } + // Set the struct expression. This is used when parsing. void set_struct_expression(Expression* expr) @@ -1914,6 +2026,9 @@ Expression* expr_; // The zero-based index of the field we are retrieving. unsigned int field_index_; + // Whether this node was emitted implicitly for an embedded field, + // that is, expr_ is not the expr_ of the original user node. + bool implicit_; // Whether we have already emitted a fieldtrack call. bool called_fieldtrack_; }; @@ -1940,6 +2055,11 @@ name() const { return this->name_; } + // Create a thunk to call the method NAME in TYPE when it is used as + // part of a method value. + static Named_object* + create_thunk(Gogo*, Interface_type* type, const std::string& name); + // Return a tree for the pointer to the function to call, given a // tree for the expression. tree @@ -1955,6 +2075,9 @@ int do_traverse(Traverse* traverse); + Expression* + do_lower(Gogo*, Named_object*, Statement_inserter*, int); + Type* do_type(); @@ -1979,6 +2102,13 @@ do_dump_expression(Ast_dump_context*) const; private: + // A mapping from interface types to a list of thunks we have + // created for methods. + typedef std::vector > Method_thunks; + typedef Unordered_map(Interface_type*, Method_thunks*) + Interface_method_thunks; + static Interface_method_thunks interface_method_thunks; + // The expression for the interface object. This should have a type // of interface or pointer to interface. Expression* expr_; diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/go.cc gcc-4.8.1/gcc/go/gofrontend/go.cc --- gcc-4.8.1.orig/gcc/go/gofrontend/go.cc 2012-10-30 19:38:49.000000000 -0500 +++ gcc-4.8.1/gcc/go/gofrontend/go.cc 2013-06-20 19:12:07.782178000 -0500 @@ -44,7 +44,7 @@ GO_EXTERN_C void go_parse_input_files(const char** filenames, unsigned int filename_count, - bool only_check_syntax, bool require_return_statement) + bool only_check_syntax, bool) { go_assert(filename_count > 0); @@ -84,10 +84,16 @@ // Finalize method lists and build stub methods for named types. ::gogo->finalize_methods(); + // Check that functions have a terminating statement. + ::gogo->check_return_statements(); + // Now that we have seen all the names, lower the parse tree into a // form which is easier to use. ::gogo->lower_parse_tree(); + // Create function descriptors as needed. + ::gogo->create_function_descriptors(); + // Write out queued up functions for hash and comparison of types. ::gogo->write_specific_type_functions(); @@ -104,10 +110,6 @@ if (only_check_syntax) return; - // Check that functions have return statements. - if (require_return_statement) - ::gogo->check_return_statements(); - // Export global identifiers as appropriate. ::gogo->do_exports(); diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/gogo.cc gcc-4.8.1/gcc/go/gofrontend/gogo.cc --- gcc-4.8.1.orig/gcc/go/gofrontend/gogo.cc 2013-02-10 00:02:38.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/gogo.cc 2013-08-07 14:00:55.550656000 -0500 @@ -364,7 +364,7 @@ // Declare "main" as a function which takes no parameters and // returns no value. Location uloc = Linemap::unknown_location(); - this->declare_function("main", + this->declare_function(Gogo::pack_hidden_name("main", false), Type::make_function_type (NULL, NULL, NULL, uloc), uloc); } @@ -819,7 +819,8 @@ char buf[30]; snprintf(buf, sizeof buf, ".$sink%d", sink_count); ++sink_count; - ret = Named_object::make_function(buf, NULL, function); + ret = this->package_->bindings()->add_function(buf, NULL, function); + ret->func_value()->set_is_sink(); } else if (!type->is_method()) { @@ -1277,6 +1278,14 @@ n.c_str()); inform(pf->second, "%qs imported here", n.c_str()); } + + // No package scope identifier may be named "init". + if (!p->second->is_function() + && Gogo::unpack_hidden_name(p->second->name()) == "init") + { + error_at(p->second->location(), + "cannot declare init - must be func"); + } } } @@ -1599,8 +1608,9 @@ return TRAVERSE_CONTINUE; } -// Lower function closure types. Record the function while lowering -// it, so that we can pass it down when lowering an expression. +// Lower the body of a function, and set the closure type. Record the +// function while lowering it, so that we can pass it down when +// lowering an expression. int Lower_parse_tree::function(Named_object* no) @@ -1732,6 +1742,146 @@ lower.constant(no, false); } +// Traverse the tree to create function descriptors as needed. + +class Create_function_descriptors : public Traverse +{ + public: + Create_function_descriptors(Gogo* gogo) + : Traverse(traverse_functions | traverse_expressions), + gogo_(gogo) + { } + + int + function(Named_object*); + + int + expression(Expression**); + + private: + Gogo* gogo_; +}; + +// Create a descriptor for every top-level exported function. + +int +Create_function_descriptors::function(Named_object* no) +{ + if (no->is_function() + && no->func_value()->enclosing() == NULL + && !no->func_value()->is_method() + && !no->func_value()->is_descriptor_wrapper() + && !Gogo::is_hidden_name(no->name())) + no->func_value()->descriptor(this->gogo_, no); + + return TRAVERSE_CONTINUE; +} + +// If we see a function referenced in any way other than calling it, +// create a descriptor for it. + +int +Create_function_descriptors::expression(Expression** pexpr) +{ + Expression* expr = *pexpr; + + Func_expression* fe = expr->func_expression(); + if (fe != NULL) + { + // We would not get here for a call to this function, so this is + // a reference to a function other than calling it. We need a + // descriptor. + if (fe->closure() != NULL) + return TRAVERSE_CONTINUE; + Named_object* no = fe->named_object(); + if (no->is_function() && !no->func_value()->is_method()) + no->func_value()->descriptor(this->gogo_, no); + else if (no->is_function_declaration() + && !no->func_declaration_value()->type()->is_method() + && !Linemap::is_predeclared_location(no->location())) + no->func_declaration_value()->descriptor(this->gogo_, no); + return TRAVERSE_CONTINUE; + } + + Bound_method_expression* bme = expr->bound_method_expression(); + if (bme != NULL) + { + // We would not get here for a call to this method, so this is a + // method value. We need to create a thunk. + Bound_method_expression::create_thunk(this->gogo_, bme->method(), + bme->function()); + return TRAVERSE_CONTINUE; + } + + Interface_field_reference_expression* ifre = + expr->interface_field_reference_expression(); + if (ifre != NULL) + { + // We would not get here for a call to this interface method, so + // this is a method value. We need to create a thunk. + Interface_type* type = ifre->expr()->type()->interface_type(); + if (type != NULL) + Interface_field_reference_expression::create_thunk(this->gogo_, type, + ifre->name()); + return TRAVERSE_CONTINUE; + } + + Call_expression* ce = expr->call_expression(); + if (ce != NULL) + { + Expression* fn = ce->fn(); + if (fn->func_expression() != NULL + || fn->bound_method_expression() != NULL + || fn->interface_field_reference_expression() != NULL) + { + // Traverse the arguments but not the function. + Expression_list* args = ce->args(); + if (args != NULL) + { + if (args->traverse(this) == TRAVERSE_EXIT) + return TRAVERSE_EXIT; + } + return TRAVERSE_SKIP_COMPONENTS; + } + } + + return TRAVERSE_CONTINUE; +} + +// Create function descriptors as needed. We need a function +// descriptor for all exported functions and for all functions that +// are referenced without being called. + +void +Gogo::create_function_descriptors() +{ + // Create a function descriptor for any exported function that is + // declared in this package. This is so that we have a descriptor + // for functions written in assembly. Gather the descriptors first + // so that we don't add declarations while looping over them. + std::vector fndecls; + Bindings* b = this->package_->bindings(); + for (Bindings::const_declarations_iterator p = b->begin_declarations(); + p != b->end_declarations(); + ++p) + { + Named_object* no = p->second; + if (no->is_function_declaration() + && !no->func_declaration_value()->type()->is_method() + && !Linemap::is_predeclared_location(no->location()) + && !Gogo::is_hidden_name(no->name())) + fndecls.push_back(no); + } + for (std::vector::const_iterator p = fndecls.begin(); + p != fndecls.end(); + ++p) + (*p)->func_declaration_value()->descriptor(this, *p); + fndecls.clear(); + + Create_function_descriptors cfd(this); + this->traverse(&cfd); +} + // Look for interface types to finalize methods of inherited // interfaces. @@ -2643,6 +2793,13 @@ Expression* closure = NULL; if (orig_func->needs_closure()) { + // For the new function we are creating, declare a new parameter + // variable NEW_CLOSURE_NO and set it to be the closure variable + // of the function. This will be set to the closure value + // passed in by the caller. Then pass a reference to this + // variable as the closure value when calling the original + // function. In other words, simply pass the closure value + // through the thunk we are creating. Named_object* orig_closure_no = orig_func->closure_var(); Variable* orig_closure_var = orig_closure_no->var_value(); Variable* new_var = new Variable(orig_closure_var->type(), NULL, false, @@ -2682,22 +2839,7 @@ // Any varargs call has already been lowered. call->set_varargs_are_lowered(); - Statement* s; - if (orig_fntype->results() == NULL || orig_fntype->results()->empty()) - s = Statement::make_statement(call, true); - else - { - Expression_list* vals = new Expression_list(); - size_t rc = orig_fntype->results()->size(); - if (rc == 1) - vals->push_back(call); - else - { - for (size_t i = 0; i < rc; ++i) - vals->push_back(Expression::make_call_result(call, i)); - } - s = Statement::make_return_statement(vals, location); - } + Statement* s = Statement::make_return_from_call(call, location); s->determine_types(); gogo->add_statement(s); @@ -2991,7 +3133,8 @@ return TRAVERSE_CONTINUE; if (func->block()->may_fall_through()) - error_at(func->location(), "control reaches end of non-void function"); + error_at(func->block()->end_location(), + "missing return at end of function"); return TRAVERSE_CONTINUE; } @@ -3101,6 +3244,7 @@ Map_type::make_map_descriptor_type(); Channel_type::make_chan_type_descriptor_type(); Interface_type::make_interface_type_descriptor_type(); + Expression::make_func_descriptor_type(); Type::convert_builtin_named_types(this); Runtime::convert_types(this); @@ -3128,10 +3272,10 @@ Location location) : type_(type), enclosing_(enclosing), results_(NULL), closure_var_(NULL), block_(block), location_(location), labels_(), - local_type_count_(0), fndecl_(NULL), defer_stack_(NULL), - results_are_named_(false), nointerface_(false), calls_recover_(false), - is_recover_thunk_(false), has_recover_thunk_(false), - in_unique_section_(false) + local_type_count_(0), descriptor_(NULL), fndecl_(NULL), defer_stack_(NULL), + is_sink_(false), results_are_named_(false), nointerface_(false), + calls_recover_(false), is_recover_thunk_(false), has_recover_thunk_(false), + in_unique_section_(false), is_descriptor_wrapper_(false) { } @@ -3206,6 +3350,7 @@ { if (this->closure_var_ == NULL) { + go_assert(this->descriptor_ == NULL); // We don't know the type of the variable yet. We add fields as // we find them. Location loc = this->type_->location(); @@ -3229,7 +3374,14 @@ return; Named_object* closure = this->closure_var_; Struct_type* st = closure->var_value()->type()->deref()->struct_type(); - unsigned int index = 0; + + // The first field of a closure is always a pointer to the function + // code. + Type* voidptr_type = Type::make_pointer_type(Type::make_void_type()); + st->push_field(Struct_field(Typed_identifier(".$f", voidptr_type, + this->location_))); + + unsigned int index = 1; for (Closure_fields::const_iterator p = this->closure_fields_.begin(); p != this->closure_fields_.end(); ++p, ++index) @@ -3410,6 +3562,102 @@ this->block_->determine_types(); } +// Build a wrapper function for a function descriptor. A function +// descriptor refers to a function that takes a closure as its last +// argument. In this case there will be no closure, but an indirect +// call will pass nil as the last argument. We need to build a +// wrapper function that accepts and discards that last argument, so +// that cases like -mrtd will work correctly. In most cases the +// wrapper function will simply be a jump. + +Named_object* +Function::make_descriptor_wrapper(Gogo* gogo, Named_object* no, + Function_type* orig_fntype) +{ + Location loc = no->location(); + + Type* vt = Type::make_pointer_type(Type::make_void_type()); + Function_type* new_fntype = orig_fntype->copy_with_closure(vt); + + std::string name = no->name() + "$descriptorfn"; + Named_object* dno = gogo->start_function(name, new_fntype, false, loc); + dno->func_value()->is_descriptor_wrapper_ = true; + + // Put the wrapper in a unique section so that it can be discarded + // by the linker if it is not needed. Every top-level function will + // get a wrapper, in case there is a reference other than a call + // from some other package, but most will not need one. + dno->func_value()->set_in_unique_section(); + + gogo->start_block(loc); + + Expression* fn = Expression::make_func_reference(no, NULL, loc); + + // Call the function begin wrapped, passing all of the arguments + // except for the last one (the last argument is the ignored + // closure). + const Typed_identifier_list* orig_params = orig_fntype->parameters(); + Expression_list* args; + if (orig_params == NULL || orig_params->empty()) + args = NULL; + else + { + const Typed_identifier_list* new_params = new_fntype->parameters(); + args = new Expression_list(); + for (Typed_identifier_list::const_iterator p = new_params->begin(); + p + 1 != new_params->end(); + ++p) + { + Named_object* p_no = gogo->lookup(p->name(), NULL); + go_assert(p_no != NULL + && p_no->is_variable() + && p_no->var_value()->is_parameter()); + args->push_back(Expression::make_var_reference(p_no, loc)); + } + } + + Call_expression* call = Expression::make_call(fn, args, + orig_fntype->is_varargs(), + loc); + call->set_varargs_are_lowered(); + + Statement* s = Statement::make_return_from_call(call, loc); + gogo->add_statement(s); + Block* b = gogo->finish_block(loc); + gogo->add_block(b, loc); + gogo->lower_block(dno, b); + gogo->finish_function(loc); + + return dno; +} + +// Return the function descriptor, the value you get when you refer to +// the function in Go code without calling it. + +Expression* +Function::descriptor(Gogo* gogo, Named_object* no) +{ + go_assert(!this->is_method()); + go_assert(this->closure_var_ == NULL); + go_assert(!this->is_descriptor_wrapper_); + if (this->descriptor_ == NULL) + { + // Make and record the descriptor first, so that when we lower + // the descriptor wrapper we don't try to make it again. + Func_descriptor_expression* descriptor = + Expression::make_func_descriptor(no); + this->descriptor_ = descriptor; + if (no->package() == NULL + && !Linemap::is_predeclared_location(no->location())) + { + Named_object* dno = Function::make_descriptor_wrapper(gogo, no, + this->type_); + descriptor->set_descriptor_wrapper(dno); + } + } + return this->descriptor_; +} + // Get a pointer to the variable representing the defer stack for this // function, making it if necessary. The value of the variable is set // by the runtime routines to true if the function is returning, @@ -3940,6 +4188,32 @@ } } +// Class Function_declaration. + +// Return the function descriptor. + +Expression* +Function_declaration::descriptor(Gogo* gogo, Named_object* no) +{ + go_assert(!this->fntype_->is_method()); + if (this->descriptor_ == NULL) + { + // Make and record the descriptor first, so that when we lower + // the descriptor wrapper we don't try to make it again. + Func_descriptor_expression* descriptor = + Expression::make_func_descriptor(no); + this->descriptor_ = descriptor; + if (no->package() == NULL + && !Linemap::is_predeclared_location(no->location())) + { + Named_object* dno = Function::make_descriptor_wrapper(gogo, no, + this->fntype_); + descriptor->set_descriptor_wrapper(dno); + } + } + return this->descriptor_; +} + // Class Variable. Variable::Variable(Type* type, Expression* init, bool is_global, @@ -4755,6 +5029,12 @@ Named_object::set_function_value(Function* function) { go_assert(this->classification_ == NAMED_OBJECT_FUNC_DECLARATION); + if (this->func_declaration_value()->has_descriptor()) + { + Expression* descriptor = + this->func_declaration_value()->descriptor(NULL, NULL); + function->set_descriptor(descriptor); + } this->classification_ = NAMED_OBJECT_FUNC; // FIXME: We should free the old value. this->u_.func_value = function; diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/gogo.h gcc-4.8.1/gcc/go/gofrontend/gogo.h --- gcc-4.8.1.orig/gcc/go/gofrontend/gogo.h 2012-12-21 16:23:23.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/gogo.h 2013-06-24 18:13:14.268180000 -0500 @@ -476,6 +476,10 @@ void lower_constant(Named_object*); + // Create all necessary function descriptors. + void + create_function_descriptors(); + // Finalize the method lists and build stub methods for named types. void finalize_methods(); @@ -614,10 +618,6 @@ receive_from_channel(tree type_tree, tree type_descriptor_tree, tree channel, Location); - // Make a trampoline which calls FNADDR passing CLOSURE. - tree - make_trampoline(tree fnaddr, tree closure, Location); - private: // During parsing, we keep a stack of functions. Each function on // the stack is one that we are currently parsing. For each @@ -669,10 +669,6 @@ tree ptr_go_string_constant_tree(const std::string&); - // Return the type of a trampoline. - static tree - trampoline_type_tree(); - // Type used to map import names to packages. typedef std::map Imports; @@ -915,6 +911,14 @@ result_variables() { return this->results_; } + bool + is_sink() const + { return this->is_sink_; } + + void + set_is_sink() + { this->is_sink_ = true; } + // Whether the result variables have names. bool results_are_named() const @@ -1046,6 +1050,12 @@ set_in_unique_section() { this->in_unique_section_ = true; } + // Whether this function was created as a descriptor wrapper for + // another function. + bool + is_descriptor_wrapper() const + { return this->is_descriptor_wrapper_; } + // Swap with another function. Used only for the thunk which calls // recover. void @@ -1059,6 +1069,26 @@ void determine_types(); + // Return an expression for the function descriptor, given the named + // object for this function. This may only be called for functions + // without a closure. This will be an immutable struct with one + // field that points to the function's code. + Expression* + descriptor(Gogo*, Named_object*); + + // Set the descriptor for this function. This is used when a + // function declaration is followed by a function definition. + void + set_descriptor(Expression* descriptor) + { + go_assert(this->descriptor_ == NULL); + this->descriptor_ = descriptor; + } + + // Build a descriptor wrapper function. + static Named_object* + make_descriptor_wrapper(Gogo*, Named_object*, Function_type*); + // Return the function's decl given an identifier. tree get_or_make_decl(Gogo*, Named_object*, tree id); @@ -1137,25 +1167,32 @@ Labels labels_; // The number of local types defined in this function. unsigned int local_type_count_; + // The function descriptor, if any. + Expression* descriptor_; // The function decl. tree fndecl_; // The defer stack variable. A pointer to this variable is used to // distinguish the defer stack for one function from another. This // is NULL unless we actually need a defer stack. Temporary_statement* defer_stack_; + // True if this function is sink-named. No code is generated. + bool is_sink_ : 1; // True if the result variables are named. - bool results_are_named_; + bool results_are_named_ : 1; // True if this method should not be included in the type descriptor. - bool nointerface_; + bool nointerface_ : 1; // True if this function calls the predeclared recover function. - bool calls_recover_; + bool calls_recover_ : 1; // True if this a thunk built for a function which calls recover. - bool is_recover_thunk_; + bool is_recover_thunk_ : 1; // True if this function already has a recover thunk. - bool has_recover_thunk_; + bool has_recover_thunk_ : 1; // True if this function should be put in a unique section. This is // turned on for field tracking. bool in_unique_section_ : 1; + // True if this is a function wrapper created to put in a function + // descriptor. + bool is_descriptor_wrapper_ : 1; }; // A snapshot of the current binding state. @@ -1198,7 +1235,8 @@ { public: Function_declaration(Function_type* fntype, Location location) - : fntype_(fntype), location_(location), asm_name_(), fndecl_(NULL) + : fntype_(fntype), location_(location), asm_name_(), descriptor_(NULL), + fndecl_(NULL) { } Function_type* @@ -1218,10 +1256,27 @@ set_asm_name(const std::string& asm_name) { this->asm_name_ = asm_name; } + // Return an expression for the function descriptor, given the named + // object for this function. This may only be called for functions + // without a closure. This will be an immutable struct with one + // field that points to the function's code. + Expression* + descriptor(Gogo*, Named_object*); + + // Return true if we have created a descriptor for this declaration. + bool + has_descriptor() const + { return this->descriptor_ != NULL; } + // Return a decl for the function given an identifier. tree get_or_make_decl(Gogo*, Named_object*, tree id); + // If there is a descriptor, build it into the backend + // representation. + void + build_backend_descriptor(Gogo*); + // Export a function declaration. void export_func(Export* exp, const std::string& name) const @@ -1235,6 +1290,8 @@ // The assembler name: this is the name to use in references to the // function. This is normally empty. std::string asm_name_; + // The function descriptor, if any. + Expression* descriptor_; // The function decl if needed. tree fndecl_; }; @@ -1630,7 +1687,7 @@ Named_constant(Type* type, Expression* expr, int iota_value, Location location) : type_(type), expr_(expr), iota_value_(iota_value), location_(location), - lowering_(false) + lowering_(false), is_sink_(false) { } Type* @@ -1664,6 +1721,14 @@ clear_lowering() { this->lowering_ = false; } + bool + is_sink() const + { return this->is_sink_; } + + void + set_is_sink() + { this->is_sink_ = true; } + // Traverse the expression. int traverse_expression(Traverse*); @@ -1699,6 +1764,8 @@ Location location_; // Whether we are currently lowering this constant. bool lowering_; + // Whether this constant is blank named and needs only type checking. + bool is_sink_; }; // A type declaration. diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/gogo-tree.cc gcc-4.8.1/gcc/go/gofrontend/gogo-tree.cc --- gcc-4.8.1.orig/gcc/go/gofrontend/gogo-tree.cc 2013-01-28 18:28:09.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/gogo-tree.cc 2013-06-24 18:13:14.268180000 -0500 @@ -755,6 +755,18 @@ this->build_interface_method_tables(); Bindings* bindings = this->current_bindings(); + + for (Bindings::const_declarations_iterator p = bindings->begin_declarations(); + p != bindings->end_declarations(); + ++p) + { + // If any function declarations needed a descriptor, make sure + // we build it. + Named_object* no = p->second; + if (no->is_function_declaration()) + no->func_declaration_value()->build_backend_descriptor(this); + } + size_t count_definitions = bindings->size_definitions(); size_t count = count_definitions; @@ -782,6 +794,8 @@ { Named_object* no = *p; + go_assert(i < count); + go_assert(!no->is_type_declaration() && !no->is_function_declaration()); // There is nothing to do for a package. if (no->is_package()) @@ -800,6 +814,15 @@ continue; } + // Skip blank named functions and constants. + if ((no->is_function() && no->func_value()->is_sink()) + || (no->is_const() && no->const_value()->is_sink())) + { + --i; + --count; + continue; + } + // There is nothing useful we can output for constants which // have ideal or non-integral type. if (no->is_const()) @@ -1255,14 +1278,47 @@ if (this->fndecl_ == NULL_TREE) { tree functype = type_to_tree(this->type_->get_backend(gogo)); + + if (functype != error_mark_node) + { + // The type of a function comes back as a pointer to a + // struct whose first field is the function, but we want the + // real function type for a function declaration. + go_assert(POINTER_TYPE_P(functype) + && TREE_CODE(TREE_TYPE(functype)) == RECORD_TYPE); + functype = TREE_TYPE(TYPE_FIELDS(TREE_TYPE(functype))); + go_assert(FUNCTION_POINTER_TYPE_P(functype)); + functype = TREE_TYPE(functype); + + // In the struct, the function type always has a trailing + // closure argument. For the function body, we only use + // that trailing arg if this is a function literal or if it + // is a wrapper created to store in a descriptor. Remove it + // in that case. + if (this->enclosing_ == NULL && !this->is_descriptor_wrapper_) + { + tree old_params = TYPE_ARG_TYPES(functype); + go_assert(old_params != NULL_TREE + && old_params != void_list_node); + tree new_params = NULL_TREE; + tree *pp = &new_params; + while (TREE_CHAIN (old_params) != void_list_node) + { + tree p = TREE_VALUE(old_params); + go_assert(TYPE_P(p)); + *pp = tree_cons(NULL_TREE, p, NULL_TREE); + pp = &TREE_CHAIN(*pp); + old_params = TREE_CHAIN (old_params); + } + *pp = void_list_node; + functype = build_function_type(TREE_TYPE(functype), new_params); + } + } + if (functype == error_mark_node) this->fndecl_ = error_mark_node; else { - // The type of a function comes back as a pointer, but we - // want the real function type for a function declaration. - go_assert(POINTER_TYPE_P(functype)); - functype = TREE_TYPE(functype); tree decl = build_decl(this->location().gcc_location(), FUNCTION_DECL, id, functype); @@ -1308,9 +1364,6 @@ DECL_CONTEXT(resdecl) = decl; DECL_RESULT(decl) = resdecl; - if (this->enclosing_ != NULL) - DECL_STATIC_CHAIN(decl) = 1; - // If a function calls the predeclared recover function, we // can't inline it, because recover behaves differently in a // function passed directly to defer. If this is a recover @@ -1333,29 +1386,6 @@ resolve_unique_section (decl, 0, 1); go_preserve_from_gc(decl); - - if (this->closure_var_ != NULL) - { - push_struct_function(decl); - - Bvariable* bvar = this->closure_var_->get_backend_variable(gogo, - no); - tree closure_decl = var_to_tree(bvar); - if (closure_decl == error_mark_node) - this->fndecl_ = error_mark_node; - else - { - DECL_ARTIFICIAL(closure_decl) = 1; - DECL_IGNORED_P(closure_decl) = 1; - TREE_USED(closure_decl) = 1; - DECL_ARG_TYPE(closure_decl) = TREE_TYPE(closure_decl); - TREE_READONLY(closure_decl) = 1; - - DECL_STRUCT_FUNCTION(decl)->static_chain_decl = closure_decl; - } - - pop_cfun(); - } } } return this->fndecl_; @@ -1382,15 +1412,44 @@ } tree functype = type_to_tree(this->fntype_->get_backend(gogo)); + + if (functype != error_mark_node) + { + // The type of a function comes back as a pointer to a + // struct whose first field is the function, but we want the + // real function type for a function declaration. + go_assert(POINTER_TYPE_P(functype) + && TREE_CODE(TREE_TYPE(functype)) == RECORD_TYPE); + functype = TREE_TYPE(TYPE_FIELDS(TREE_TYPE(functype))); + go_assert(FUNCTION_POINTER_TYPE_P(functype)); + functype = TREE_TYPE(functype); + + // In the struct, the function type always has a trailing + // closure argument. Here we are referring to the function + // code directly, and we know it is not a function literal, + // and we know it is not a wrapper created to store in a + // descriptor. Remove that trailing argument. + tree old_params = TYPE_ARG_TYPES(functype); + go_assert(old_params != NULL_TREE && old_params != void_list_node); + tree new_params = NULL_TREE; + tree *pp = &new_params; + while (TREE_CHAIN (old_params) != void_list_node) + { + tree p = TREE_VALUE(old_params); + go_assert(TYPE_P(p)); + *pp = tree_cons(NULL_TREE, p, NULL_TREE); + pp = &TREE_CHAIN(*pp); + old_params = TREE_CHAIN (old_params); + } + *pp = void_list_node; + functype = build_function_type(TREE_TYPE(functype), new_params); + } + tree decl; if (functype == error_mark_node) decl = error_mark_node; else { - // The type of a function comes back as a pointer, but we - // want the real function type for a function declaration. - go_assert(POINTER_TYPE_P(functype)); - functype = TREE_TYPE(functype); decl = build_decl(this->location().gcc_location(), FUNCTION_DECL, id, functype); TREE_PUBLIC(decl) = 1; @@ -1599,6 +1658,32 @@ } } } + + // The closure variable is passed last, if this is a function + // literal or a descriptor wrapper. + if (this->closure_var_ != NULL) + { + Bvariable* bvar = + this->closure_var_->get_backend_variable(gogo, named_function); + tree var_decl = var_to_tree(bvar); + if (var_decl != error_mark_node) + { + go_assert(TREE_CODE(var_decl) == PARM_DECL); + *pp = var_decl; + pp = &DECL_CHAIN(*pp); + } + } + else if (this->enclosing_ != NULL || this->is_descriptor_wrapper_) + { + tree parm_decl = build_decl(this->location_.gcc_location(), PARM_DECL, + get_identifier("$closure"), + const_ptr_type_node); + DECL_CONTEXT(parm_decl) = current_function_decl; + DECL_ARG_TYPE(parm_decl) = const_ptr_type_node; + *pp = parm_decl; + pp = &DECL_CHAIN(*pp); + } + *pp = NULL_TREE; DECL_ARGUMENTS(fndecl) = params; @@ -1681,6 +1766,13 @@ DECL_SAVED_TREE(fndecl) = code; } + + // If we created a descriptor for the function, make sure we emit it. + if (this->descriptor_ != NULL) + { + Translate_context context(gogo, NULL, NULL, NULL); + this->descriptor_->get_tree(&context); + } } // Build the wrappers around function code needed if the function has @@ -1844,6 +1936,20 @@ } } +// Build the descriptor for a function declaration. This won't +// necessarily happen if the package has just a declaration for the +// function and no other reference to it, but we may still need the +// descriptor for references from other packages. +void +Function_declaration::build_backend_descriptor(Gogo* gogo) +{ + if (this->descriptor_ != NULL) + { + Translate_context context(gogo, NULL, NULL, NULL); + this->descriptor_->get_tree(&context); + } +} + // Return the integer type to use for a size. GO_EXTERN_C @@ -2437,70 +2543,3 @@ build2(COMPOUND_EXPR, type_tree, call, tmp)); } } - -// Return the type of a function trampoline. This is like -// get_trampoline_type in tree-nested.c. - -tree -Gogo::trampoline_type_tree() -{ - static tree type_tree; - if (type_tree == NULL_TREE) - { - unsigned int size; - unsigned int align; - go_trampoline_info(&size, &align); - tree t = build_index_type(build_int_cst(integer_type_node, size - 1)); - t = build_array_type(char_type_node, t); - - type_tree = Gogo::builtin_struct(NULL, "__go_trampoline", NULL_TREE, 1, - "__data", t); - t = TYPE_FIELDS(type_tree); - DECL_ALIGN(t) = align; - DECL_USER_ALIGN(t) = 1; - - go_preserve_from_gc(type_tree); - } - return type_tree; -} - -// Make a trampoline which calls FNADDR passing CLOSURE. - -tree -Gogo::make_trampoline(tree fnaddr, tree closure, Location location) -{ - tree trampoline_type = Gogo::trampoline_type_tree(); - tree trampoline_size = TYPE_SIZE_UNIT(trampoline_type); - - closure = save_expr(closure); - - // We allocate the trampoline using a special function which will - // mark it as executable. - static tree trampoline_fndecl; - tree x = Gogo::call_builtin(&trampoline_fndecl, - location, - "__go_allocate_trampoline", - 2, - ptr_type_node, - size_type_node, - trampoline_size, - ptr_type_node, - fold_convert_loc(location.gcc_location(), - ptr_type_node, closure)); - if (x == error_mark_node) - return error_mark_node; - - x = save_expr(x); - - // Initialize the trampoline. - tree calldecl = builtin_decl_implicit(BUILT_IN_INIT_HEAP_TRAMPOLINE); - tree ini = build_call_expr(calldecl, 3, x, fnaddr, closure); - - // On some targets the trampoline address needs to be adjusted. For - // example, when compiling in Thumb mode on the ARM, the address - // needs to have the low bit set. - x = build_call_expr(builtin_decl_explicit(BUILT_IN_ADJUST_TRAMPOLINE), 1, x); - x = fold_convert(TREE_TYPE(fnaddr), x); - - return build2(COMPOUND_EXPR, TREE_TYPE(x), ini, x); -} diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/parse.cc gcc-4.8.1/gcc/go/gofrontend/parse.cc --- gcc-4.8.1.orig/gcc/go/gofrontend/parse.cc 2012-12-13 16:20:23.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/parse.cc 2013-08-17 13:04:58.702541000 -0500 @@ -1457,6 +1457,16 @@ if (!Gogo::is_sink_name(pi->name())) this->gogo_->add_constant(*pi, *pe, this->iota_value()); + else + { + static int count; + char buf[30]; + snprintf(buf, sizeof buf, ".$sinkconst%d", count); + ++count; + Typed_identifier ti(std::string(buf), type, pi->location()); + Named_object* no = this->gogo_->add_constant(ti, *pe, this->iota_value()); + no->const_value()->set_is_sink(); + } } if (pe != expr_list->end()) error_at(this->location(), "too many initializers"); @@ -2627,7 +2637,11 @@ Named_object* this_function = this->gogo_->current_function(); Named_object* closure = this_function->func_value()->closure_var(); - Enclosing_var ev(var, in_function, this->enclosing_vars_.size()); + // The last argument to the Enclosing_var constructor is the index + // of this variable in the closure. We add 1 to the current number + // of enclosed variables, because the first field in the closure + // points to the function code. + Enclosing_var ev(var, in_function, this->enclosing_vars_.size() + 1); std::pair ins = this->enclosing_vars_.insert(ev); if (ins.second) @@ -2882,8 +2896,9 @@ // Create a closure for the nested function FUNCTION. This is based // on ENCLOSING_VARS, which is a list of all variables defined in // enclosing functions and referenced from FUNCTION. A closure is the -// address of a struct which contains the addresses of all the -// referenced variables. This returns NULL if no closure is required. +// address of a struct which point to the real function code and +// contains the addresses of all the referenced variables. This +// returns NULL if no closure is required. Expression* Parse::create_closure(Named_object* function, Enclosing_vars* enclosing_vars, @@ -2899,16 +2914,25 @@ for (Enclosing_vars::const_iterator p = enclosing_vars->begin(); p != enclosing_vars->end(); ++p) - ev[p->index()] = *p; + { + // Subtract 1 because index 0 is the function code. + ev[p->index() - 1] = *p; + } // Build an initializer for a composite literal of the closure's // type. Named_object* enclosing_function = this->gogo_->current_function(); Expression_list* initializer = new Expression_list; + + initializer->push_back(Expression::make_func_code_reference(function, + location)); + for (size_t i = 0; i < enclosing_var_count; ++i) { - go_assert(ev[i].index() == i); + // Add 1 to i because the first field in the closure is a + // pointer to the function code. + go_assert(ev[i].index() == i + 1); Named_object* var = ev[i].var(); Expression* ref; if (ev[i].in_function() == enclosing_function) @@ -3016,7 +3040,7 @@ && t->array_type()->length()->is_nil_expression()) { error_at(ret->location(), - "invalid use of %<...%> in type conversion"); + "use of %<[...]%> outside of array literal"); ret = Expression::make_error(loc); } else @@ -4499,9 +4523,12 @@ bool is_fallthrough = false; if (this->peek_token()->is_keyword(KEYWORD_FALLTHROUGH)) { + Location fallthrough_loc = this->location(); is_fallthrough = true; if (this->advance_token()->is_op(OPERATOR_SEMICOLON)) this->advance_token(); + if (this->peek_token()->is_op(OPERATOR_RCURLY)) + error_at(fallthrough_loc, _("cannot fallthrough final case in switch")); } if (is_default) @@ -5239,7 +5266,8 @@ no->var_value()->set_type_from_range_value(); if (is_new) any_new = true; - p_range_clause->value = Expression::make_var_reference(no, location); + if (!Gogo::is_sink_name(pti->name())) + p_range_clause->value = Expression::make_var_reference(no, location); } if (!any_new) diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/runtime.def gcc-4.8.1/gcc/go/gofrontend/runtime.def --- gcc-4.8.1.orig/gcc/go/gofrontend/runtime.def 2012-11-29 12:11:17.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/runtime.def 2013-06-18 18:50:42.020320000 -0500 @@ -224,11 +224,6 @@ DEF_GO_RUNTIME(NEW_NOPOINTERS, "__go_new_nopointers", P1(UINTPTR), R1(POINTER)) -// Allocate a trampoline for a function literal. -DEF_GO_RUNTIME(ALLOCATE_GO_TRAMPOLINE, "__go_allocate_trampoline", - P2(UINTPTR, POINTER), R1(POINTER)) - - // Start a new goroutine. DEF_GO_RUNTIME(GO, "__go_go", P2(FUNC_PTR, POINTER), R0()) diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/statements.cc gcc-4.8.1/gcc/go/gofrontend/statements.cc --- gcc-4.8.1.orig/gcc/go/gofrontend/statements.cc 2012-12-21 09:59:27.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/statements.cc 2013-08-07 14:00:55.550656000 -0500 @@ -569,7 +569,10 @@ Assignment_statement::do_determine_types() { this->lhs_->determine_type_no_context(); - Type_context context(this->lhs_->type(), false); + Type* rhs_context_type = this->lhs_->type(); + if (rhs_context_type->is_sink_type()) + rhs_context_type = NULL; + Type_context context(rhs_context_type, false); this->rhs_->determine_type(&context); } @@ -1707,8 +1710,8 @@ this->expr_->discarding_value(); } -// An expression statement may fall through unless it is a call to a -// function which does not return. +// An expression statement is only a terminating statement if it is +// a call to panic. bool Expression_statement::do_may_fall_through() const @@ -1717,22 +1720,28 @@ if (call != NULL) { const Expression* fn = call->fn(); - const Func_expression* fe = fn->func_expression(); - if (fe != NULL) + // panic is still an unknown named object. + const Unknown_expression* ue = fn->unknown_expression(); + if (ue != NULL) { - const Named_object* no = fe->named_object(); + Named_object* no = ue->named_object(); - Function_type* fntype; - if (no->is_function()) - fntype = no->func_value()->type(); - else if (no->is_function_declaration()) - fntype = no->func_declaration_value()->type(); - else - fntype = NULL; - - // The builtin function panic does not return. - if (fntype != NULL && fntype->is_builtin() && no->name() == "panic") - return false; + if (no->is_unknown()) + no = no->unknown_value()->real_named_object(); + if (no != NULL) + { + Function_type* fntype; + if (no->is_function()) + fntype = no->func_value()->type(); + else if (no->is_function_declaration()) + fntype = no->func_declaration_value()->type(); + else + fntype = NULL; + + // The builtin function panic does not return. + if (fntype != NULL && fntype->is_builtin() && no->name() == "panic") + return false; + } } } return true; @@ -1953,10 +1962,15 @@ && results->begin()->type()->points_to() == NULL))) return false; - // If this calls something which is not a simple function, then we + // If this calls something that is not a simple function, then we // need a thunk. Expression* fn = this->call_->call_expression()->fn(); - if (fn->interface_field_reference_expression() != NULL) + if (fn->func_expression() == NULL) + return false; + + // If the function uses a closure, then we need a thunk. FIXME: We + // could accept a zero argument function with a closure. + if (fn->func_expression()->closure() != NULL) return false; return true; @@ -2496,7 +2510,11 @@ Call_expression* ce = this->call_->call_expression(); - *pfn = ce->fn(); + Expression* fn = ce->fn(); + Func_expression* fe = fn->func_expression(); + go_assert(fe != NULL); + *pfn = Expression::make_func_code_reference(fe->named_object(), + fe->location()); const Expression_list* args = ce->args(); if (args == NULL || args->empty()) @@ -2800,6 +2818,28 @@ return new Return_statement(vals, location); } +// Make a statement that returns the result of a call expression. + +Statement* +Statement::make_return_from_call(Call_expression* call, Location location) +{ + size_t rc = call->result_count(); + if (rc == 0) + return Statement::make_statement(call, true); + else + { + Expression_list* vals = new Expression_list(); + if (rc == 1) + vals->push_back(call); + else + { + for (size_t i = 0; i < rc; ++i) + vals->push_back(Expression::make_call_result(call, i)); + } + return Statement::make_return_statement(vals, location); + } +} + // A break or continue statement. class Bc_statement : public Statement @@ -3700,9 +3740,6 @@ void do_check_types(Gogo*); - bool - do_may_fall_through() const; - Bstatement* do_get_backend(Translate_context*); @@ -3746,22 +3783,6 @@ this->set_is_error(); } -// Return whether this switch may fall through. - -bool -Constant_switch_statement::do_may_fall_through() const -{ - if (this->clauses_ == NULL) - return true; - - // If we have a break label, then some case needed it. That implies - // that the switch statement as a whole can fall through. - if (this->break_label_ != NULL) - return true; - - return this->clauses_->may_fall_through(); -} - // Convert to GENERIC. Bstatement* @@ -3911,6 +3932,22 @@ ast_dump_context->ostream() << std::endl; } +// Return whether this switch may fall through. + +bool +Switch_statement::do_may_fall_through() const +{ + if (this->clauses_ == NULL) + return true; + + // If we have a break label, then some case needed it. That implies + // that the switch statement as a whole can fall through. + if (this->break_label_ != NULL) + return true; + + return this->clauses_->may_fall_through(); +} + // Make a switch statement. Switch_statement* @@ -4050,6 +4087,27 @@ } } +// Return true if this type clause may fall through to the statements +// following the switch. + +bool +Type_case_clauses::Type_case_clause::may_fall_through() const +{ + if (this->is_fallthrough_) + { + // This case means that we automatically fall through to the + // next case (it's used for T1 in case T1, T2:). It does not + // mean that we fall through to the end of the type switch as a + // whole. There is sure to be a next case and that next case + // will determine whether we fall through to the statements + // after the type switch. + return false; + } + if (this->statements_ == NULL) + return true; + return this->statements_->may_fall_through(); +} + // Dump the AST representation for a type case clause void @@ -4148,6 +4206,25 @@ NULL); } +// Return true if these clauses may fall through to the statements +// following the switch statement. + +bool +Type_case_clauses::may_fall_through() const +{ + bool found_default = false; + for (Type_clauses::const_iterator p = this->clauses_.begin(); + p != this->clauses_.end(); + ++p) + { + if (p->may_fall_through()) + return true; + if (p->is_default()) + found_default = true; + } + return !found_default; +} + // Dump the AST representation for case clauses (from a switch statement) void @@ -4237,6 +4314,22 @@ return Statement::make_block_statement(b, loc); } +// Return whether this switch may fall through. + +bool +Type_switch_statement::do_may_fall_through() const +{ + if (this->clauses_ == NULL) + return true; + + // If we have a break label, then some case needed it. That implies + // that the switch statement as a whole can fall through. + if (this->break_label_ != NULL) + return true; + + return this->clauses_->may_fall_through(); +} + // Return the break label for this type switch statement, creating it // if necessary. @@ -4954,6 +5047,19 @@ return Statement::make_block_statement(b, loc); } +// Whether the select statement itself may fall through to the following +// statement. + +bool +Select_statement::do_may_fall_through() const +{ + // A select statement is terminating if no break statement + // refers to it and all of its clauses are terminating. + if (this->break_label_ != NULL) + return true; + return this->clauses_->may_fall_through(); +} + // Return the backend representation for a select statement. Bstatement* @@ -5114,6 +5220,20 @@ this->continue_label_ = continue_label; } +// Whether the overall statement may fall through. + +bool +For_statement::do_may_fall_through() const +{ + // A for loop is terminating if it has no condition and + // no break statement. + if(this->cond_ != NULL) + return true; + if(this->break_label_ != NULL) + return true; + return false; +} + // Dump the AST representation for a for statement. void diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/statements.h gcc-4.8.1/gcc/go/gofrontend/statements.h --- gcc-4.8.1.orig/gcc/go/gofrontend/statements.h 2013-01-28 18:28:09.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/statements.h 2013-06-24 17:11:25.306173000 -0500 @@ -207,6 +207,13 @@ static Return_statement* make_return_statement(Expression_list*, Location); + // Make a statement that returns the result of a call expression. + // If the call does not return any results, this just returns the + // call expression as a statement, assuming that the function will + // end immediately afterward. + static Statement* + make_return_from_call(Call_expression*, Location); + // Make a break statement. static Statement* make_break_statement(Unnamed_label* label, Location); @@ -894,8 +901,7 @@ { this->clauses_->check_types(); } bool - do_may_fall_through() const - { return this->clauses_->may_fall_through(); } + do_may_fall_through() const; Bstatement* do_get_backend(Translate_context*); @@ -1086,6 +1092,9 @@ Statement* do_lower(Gogo*, Named_object*, Block*, Statement_inserter*); + bool + do_may_fall_through() const; + Bstatement* do_get_backend(Translate_context*) { go_unreachable(); } @@ -1399,6 +1408,9 @@ void do_dump_statement(Ast_dump_context*) const; + bool + do_may_fall_through() const; + private: // The value to switch on. This may be NULL. Expression* val_; @@ -1449,6 +1461,11 @@ lower(Type*, Block*, Temporary_statement* descriptor_temp, Unnamed_label* break_label) const; + // Return true if these clauses may fall through to the statements + // following the switch statement. + bool + may_fall_through() const; + // Dump the AST representation to a dump context. void dump_clauses(Ast_dump_context*) const; @@ -1493,6 +1510,12 @@ lower(Type*, Block*, Temporary_statement* descriptor_temp, Unnamed_label* break_label, Unnamed_label** stmts_label) const; + // Return true if this clause may fall through to execute the + // statements following the switch statement. This is not the + // same as whether this clause falls through to the next clause. + bool + may_fall_through() const; + // Dump the AST representation to a dump context. void dump_clause(Ast_dump_context*) const; @@ -1556,6 +1579,9 @@ void do_dump_statement(Ast_dump_context*) const; + bool + do_may_fall_through() const; + private: // The variable holding the value we are switching on. Named_object* var_; diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/types.cc gcc-4.8.1/gcc/go/gofrontend/types.cc --- gcc-4.8.1.orig/gcc/go/gofrontend/types.cc 2013-01-31 18:23:22.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/types.cc 2013-08-23 16:04:55.544713000 -0500 @@ -1298,8 +1298,8 @@ // converting INITIALIZER. this->type_descriptor_var_ = - gogo->backend()->immutable_struct(var_name, is_common, initializer_btype, - loc); + gogo->backend()->immutable_struct(var_name, false, is_common, + initializer_btype, loc); if (phash != NULL) *phash = this->type_descriptor_var_; @@ -1308,7 +1308,7 @@ Bexpression* binitializer = tree_to_expr(initializer->get_tree(&context)); gogo->backend()->immutable_struct_set_init(this->type_descriptor_var_, - var_name, is_common, + var_name, false, is_common, initializer_btype, loc, binitializer); } @@ -1528,26 +1528,6 @@ // The type descriptor type. - Typed_identifier_list* params = new Typed_identifier_list(); - params->push_back(Typed_identifier("key", unsafe_pointer_type, bloc)); - params->push_back(Typed_identifier("key_size", uintptr_type, bloc)); - - Typed_identifier_list* results = new Typed_identifier_list(); - results->push_back(Typed_identifier("", uintptr_type, bloc)); - - Type* hashfn_type = Type::make_function_type(NULL, params, results, bloc); - - params = new Typed_identifier_list(); - params->push_back(Typed_identifier("key1", unsafe_pointer_type, bloc)); - params->push_back(Typed_identifier("key2", unsafe_pointer_type, bloc)); - params->push_back(Typed_identifier("key_size", uintptr_type, bloc)); - - results = new Typed_identifier_list(); - results->push_back(Typed_identifier("", Type::lookup_bool_type(), bloc)); - - Type* equalfn_type = Type::make_function_type(NULL, params, results, - bloc); - Struct_type* type_descriptor_type = Type::make_builtin_struct_type(10, "Kind", uint8_type, @@ -1555,8 +1535,8 @@ "fieldAlign", uint8_type, "size", uintptr_type, "hash", uint32_type, - "hashfn", hashfn_type, - "equalfn", equalfn_type, + "hashfn", uintptr_type, + "equalfn", uintptr_type, "string", pointer_string_type, "", pointer_uncommon_type, "ptrToThis", @@ -1946,8 +1926,8 @@ Named_object* equal_fn; this->type_functions(gogo, name, hash_fntype, equal_fntype, &hash_fn, &equal_fn); - vals->push_back(Expression::make_func_reference(hash_fn, NULL, bloc)); - vals->push_back(Expression::make_func_reference(equal_fn, NULL, bloc)); + vals->push_back(Expression::make_func_code_reference(hash_fn, bloc)); + vals->push_back(Expression::make_func_code_reference(equal_fn, bloc)); ++p; go_assert(p->is_field_name("string")); @@ -2207,7 +2187,7 @@ ++p; go_assert(p->is_field_name("tfn")); - vals->push_back(Expression::make_func_reference(no, NULL, bloc)); + vals->push_back(Expression::make_func_code_reference(no, bloc)); ++p; go_assert(p == fields->end()); @@ -3407,6 +3387,19 @@ Btype* Function_type::do_get_backend(Gogo* gogo) { + // When we do anything with a function value other than call it, it + // is represented as a pointer to a struct whose first field is the + // actual function. So that is what we return as the type of a Go + // function. The function stored in the first field always that + // takes one additional trailing argument: the closure pointer. For + // a top-level function, this additional argument will only be + // passed when invoking the function indirectly, via the struct. + + Location loc = this->location(); + Btype* struct_type = + gogo->backend()->placeholder_struct_type("__go_descriptor", loc); + Btype* ptr_struct_type = gogo->backend()->pointer_type(struct_type); + Backend::Btyped_identifier breceiver; if (this->receiver_ != NULL) { @@ -3422,9 +3415,15 @@ } std::vector bparameters; - if (this->parameters_ != NULL) + size_t last; + if (this->parameters_ == NULL) + { + bparameters.resize(1); + last = 0; + } + else { - bparameters.resize(this->parameters_->size()); + bparameters.resize(this->parameters_->size() + 1); size_t i = 0; for (Typed_identifier_list::const_iterator p = this->parameters_->begin(); p != this->parameters_->end(); @@ -3434,8 +3433,12 @@ bparameters[i].btype = p->type()->get_backend(gogo); bparameters[i].location = p->location(); } - go_assert(i == bparameters.size()); + last = i; } + go_assert(last + 1 == bparameters.size()); + bparameters[last].name = "$closure"; + bparameters[last].btype = ptr_struct_type; + bparameters[last].location = loc; std::vector bresults; if (this->results_ != NULL) @@ -3453,8 +3456,15 @@ go_assert(i == bresults.size()); } - return gogo->backend()->function_type(breceiver, bparameters, bresults, - this->location()); + Btype* fntype = gogo->backend()->function_type(breceiver, bparameters, + bresults, loc); + std::vector fields(1); + fields[0].name = "code"; + fields[0].btype = fntype; + fields[0].location = loc; + if (!gogo->backend()->set_placeholder_struct_type(struct_type, fields)) + return gogo->backend()->error_type(); + return ptr_struct_type; } // The type of a function type descriptor. @@ -3826,6 +3836,49 @@ return ret; } +// Make a copy of a function type ignoring any receiver and adding a +// closure parameter. + +Function_type* +Function_type::copy_with_closure(Type* closure_type) const +{ + Typed_identifier_list* new_params = new Typed_identifier_list(); + const Typed_identifier_list* orig_params = this->parameters_; + if (orig_params != NULL && !orig_params->empty()) + { + static int count; + char buf[50]; + for (Typed_identifier_list::const_iterator p = orig_params->begin(); + p != orig_params->end(); + ++p) + { + snprintf(buf, sizeof buf, "pt.%u", count); + ++count; + new_params->push_back(Typed_identifier(buf, p->type(), + p->location())); + } + } + new_params->push_back(Typed_identifier("closure.0", closure_type, + this->location_)); + + const Typed_identifier_list* orig_results = this->results_; + Typed_identifier_list* new_results; + if (orig_results == NULL || orig_results->empty()) + new_results = NULL; + else + { + new_results = new Typed_identifier_list(); + for (Typed_identifier_list::const_iterator p = orig_results->begin(); + p != orig_results->end(); + ++p) + new_results->push_back(Typed_identifier("", p->type(), + p->location())); + } + + return Type::make_function_type(NULL, new_params, new_results, + this->location()); +} + // Make a function type. Function_type* @@ -4168,6 +4221,22 @@ } } +// Return whether this field is an embedded built-in type. + +bool +Struct_field::is_embedded_builtin(Gogo* gogo) const +{ + const std::string& name(this->field_name()); + // We know that a field is an embedded type if it is anonymous. + // We can decide if it is a built-in type by checking to see if it is + // registered globally under the field's name. + // This allows us to distinguish between embedded built-in types and + // embedded types that are aliases to built-in types. + return (this->is_anonymous() + && !Gogo::is_hidden_name(name) + && gogo->lookup_global(name.c_str()) != NULL); +} + // Class Struct_type. // A hash table used to find identical unnamed structs so that they @@ -4532,6 +4601,7 @@ go_assert(sub != NULL); } sub->set_struct_expression(here); + sub->set_implicit(true); } else if (subdepth > found_depth) delete sub; @@ -4781,11 +4851,16 @@ ++q; go_assert(q->is_field_name("pkgPath")); - if (!Gogo::is_hidden_name(pf->field_name())) - fvals->push_back(Expression::make_nil(bloc)); + bool is_embedded_builtin = pf->is_embedded_builtin(gogo); + if (!Gogo::is_hidden_name(pf->field_name()) && !is_embedded_builtin) + fvals->push_back(Expression::make_nil(bloc)); else { - std::string n = Gogo::hidden_name_pkgpath(pf->field_name()); + std::string n; + if (is_embedded_builtin) + n = gogo->package_name(); + else + n = Gogo::hidden_name_pkgpath(pf->field_name()); Expression* s = Expression::make_string(n, bloc); fvals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc)); } @@ -6227,7 +6302,8 @@ std::string mangled_name = "__go_map_" + this->mangled_name(gogo); Btype* map_descriptor_btype = map_descriptor_type->get_backend(gogo); - Bvariable* bvar = gogo->backend()->immutable_struct(mangled_name, true, + Bvariable* bvar = gogo->backend()->immutable_struct(mangled_name, false, + true, map_descriptor_btype, bloc); @@ -6235,7 +6311,7 @@ context.set_is_const(); Bexpression* binitializer = tree_to_expr(initializer->get_tree(&context)); - gogo->backend()->immutable_struct_set_init(bvar, mangled_name, true, + gogo->backend()->immutable_struct_set_init(bvar, mangled_name, false, true, map_descriptor_btype, bloc, binitializer); @@ -7569,7 +7645,7 @@ // the child class. return this->do_bind_method(expr, location); } - return Expression::make_bound_method(expr, this->stub_, location); + return Expression::make_bound_method(expr, this, this->stub_, location); } // Return the named object associated with a method. This may only be @@ -7612,8 +7688,8 @@ Named_method::do_bind_method(Expression* expr, Location location) const { Named_object* no = this->named_object_; - Bound_method_expression* bme = Expression::make_bound_method(expr, no, - location); + Bound_method_expression* bme = Expression::make_bound_method(expr, this, + no, location); // If this is not a local method, and it does not use a stub, then // the real method expects a different type. We need to cast the // first argument. @@ -8991,28 +9067,16 @@ Call_expression* call = Expression::make_call(func, arguments, is_varargs, location); call->set_hidden_fields_are_ok(); - size_t count = call->result_count(); - if (count == 0) - gogo->add_statement(Statement::make_statement(call, true)); - else - { - Expression_list* retvals = new Expression_list(); - if (count <= 1) - retvals->push_back(call); - else - { - for (size_t i = 0; i < count; ++i) - retvals->push_back(Expression::make_call_result(call, i)); - } - Return_statement* retstat = Statement::make_return_statement(retvals, - location); + Statement* s = Statement::make_return_from_call(call, location); + Return_statement* retstat = s->return_statement(); + if (retstat != NULL) + { // We can return values with hidden fields from a stub. This is // necessary if the method is itself hidden. retstat->set_hidden_fields_are_ok(); - - gogo->add_statement(retstat); } + gogo->add_statement(s); } // Apply FIELD_INDEXES to EXPR. The field indexes have to be applied @@ -9353,13 +9417,18 @@ fnt = pf->type()->deref()->named_type(); go_assert(fnt != NULL); + // Methods with pointer receivers on embedded field are + // inherited by the pointer to struct, and also by the struct + // type if the field itself is a pointer. + bool can_be_pointer = (receiver_can_be_pointer + || pf->type()->points_to() != NULL); int sublevel = level == NULL ? 1 : *level + 1; bool sub_is_method; std::string subambig1; std::string subambig2; bool subfound = Type::find_field_or_method(fnt, name, - receiver_can_be_pointer, + can_be_pointer, seen, &sublevel, &sub_is_method, diff -Naur gcc-4.8.1.orig/gcc/go/gofrontend/types.h gcc-4.8.1/gcc/go/gofrontend/types.h --- gcc-4.8.1.orig/gcc/go/gofrontend/types.h 2013-01-31 18:23:22.000000000 -0600 +++ gcc-4.8.1/gcc/go/gofrontend/types.h 2013-08-23 16:04:55.544713000 -0500 @@ -523,6 +523,14 @@ static Type* make_forward_declaration(Named_object*); + // Make a builtin struct type from a list of fields. + static Struct_type* + make_builtin_struct_type(int nfields, ...); + + // Make a builtin named type. + static Named_type* + make_builtin_named_type(const char* name, Type* type); + // Traverse a type. static int traverse(Type*, Traverse*); @@ -1035,14 +1043,6 @@ type_descriptor_constructor(Gogo*, int runtime_type_kind, Named_type*, const Methods*, bool only_value_methods); - // Make a builtin struct type from a list of fields. - static Struct_type* - make_builtin_struct_type(int nfields, ...); - - // Make a builtin named type. - static Named_type* - make_builtin_named_type(const char* name, Type* type); - // For the benefit of child class reflection string generation. void append_reflection(const Type* type, Gogo* gogo, std::string* ret) const @@ -1789,6 +1789,12 @@ Function_type* copy_with_receiver(Type*) const; + // Return a copy of this type ignoring any receiver and adding a + // final closure parameter of type CLOSURE_TYPE. This is used when + // creating descriptors. + Function_type* + copy_with_closure(Type* closure_type) const; + static Type* make_function_type_descriptor_type(); @@ -1796,7 +1802,7 @@ int do_traverse(Traverse*); - // A trampoline function has a pointer which matters for GC. + // A function descriptor may be allocated on the heap. bool do_has_pointer() const { return true; } @@ -1920,6 +1926,10 @@ bool is_field_name(const std::string& name) const; + // Return whether this struct field is an embedded built-in type. + bool + is_embedded_builtin(Gogo*) const; + // The field type. Type* type() const diff -Naur gcc-4.8.1.orig/gcc/go/go-gcc.cc gcc-4.8.1/gcc/go/go-gcc.cc --- gcc-4.8.1.orig/gcc/go/go-gcc.cc 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/go/go-gcc.cc 2013-08-06 11:40:25.449651000 -0500 @@ -287,10 +287,10 @@ Location, Bstatement**); Bvariable* - immutable_struct(const std::string&, bool, Btype*, Location); + immutable_struct(const std::string&, bool, bool, Btype*, Location); void - immutable_struct_set_init(Bvariable*, const std::string&, bool, Btype*, + immutable_struct_set_init(Bvariable*, const std::string&, bool, bool, Btype*, Location, Bexpression*); Bvariable* @@ -1242,20 +1242,41 @@ switch (TREE_CODE(type)) { case RECORD_TYPE: - { - if (go_non_zero_struct == NULL_TREE) - { - type = make_node(RECORD_TYPE); - tree field = build_decl(UNKNOWN_LOCATION, FIELD_DECL, - get_identifier("dummy"), - boolean_type_node); - DECL_CONTEXT(field) = type; - TYPE_FIELDS(type) = field; - layout_type(type); - go_non_zero_struct = type; - } - return go_non_zero_struct; - } + if (TYPE_FIELDS(type) != NULL_TREE) + { + tree ns = make_node(RECORD_TYPE); + tree field_trees = NULL_TREE; + tree *pp = &field_trees; + for (tree field = TYPE_FIELDS(type); + field != NULL_TREE; + field = DECL_CHAIN(field)) + { + tree ft = TREE_TYPE(field); + if (field == TYPE_FIELDS(type)) + ft = non_zero_size_type(ft); + tree f = build_decl(DECL_SOURCE_LOCATION(field), FIELD_DECL, + DECL_NAME(field), ft); + DECL_CONTEXT(f) = ns; + *pp = f; + pp = &DECL_CHAIN(f); + } + TYPE_FIELDS(ns) = field_trees; + layout_type(ns); + return ns; + } + + if (go_non_zero_struct == NULL_TREE) + { + type = make_node(RECORD_TYPE); + tree field = build_decl(UNKNOWN_LOCATION, FIELD_DECL, + get_identifier("dummy"), + boolean_type_node); + DECL_CONTEXT(field) = type; + TYPE_FIELDS(type) = field; + layout_type(type); + go_non_zero_struct = type; + } + return go_non_zero_struct; case ARRAY_TYPE: { @@ -1454,8 +1475,8 @@ // Create a named immutable initialized data structure. Bvariable* -Gcc_backend::immutable_struct(const std::string& name, bool, Btype* btype, - Location location) +Gcc_backend::immutable_struct(const std::string& name, bool, bool, + Btype* btype, Location location) { tree type_tree = btype->get_tree(); if (type_tree == error_mark_node) @@ -1482,7 +1503,7 @@ void Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&, - bool is_common, Btype*, + bool is_hidden, bool is_common, Btype*, Location, Bexpression* initializer) { @@ -1495,12 +1516,18 @@ // We can't call make_decl_one_only until we set DECL_INITIAL. if (!is_common) - TREE_PUBLIC(decl) = 1; - else { - make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl)); - resolve_unique_section(decl, 1, 0); + if (!is_hidden) + TREE_PUBLIC(decl) = 1; } + else + make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl)); + + // These variables are often unneeded in the final program, so put + // them in their own section so that linker GC can discard them. + resolve_unique_section(decl, + compute_reloc_for_constant (init_tree), + 1); rest_of_decl_compilation(decl, 1, 0); } diff -Naur gcc-4.8.1.orig/gcc/ipa-cp.c gcc-4.8.1/gcc/ipa-cp.c --- gcc-4.8.1.orig/gcc/ipa-cp.c 2013-05-09 06:56:32.000000000 -0500 +++ gcc-4.8.1/gcc/ipa-cp.c 2013-06-12 08:17:03.426963000 -0500 @@ -1507,7 +1507,8 @@ tree otr_type; tree t; - if (param_index == -1) + if (param_index == -1 + || known_vals.length () <= (unsigned int) param_index) return NULL_TREE; if (!ie->indirect_info->polymorphic) @@ -1528,8 +1529,7 @@ t = NULL; } else - t = (known_vals.length () > (unsigned int) param_index - ? known_vals[param_index] : NULL); + t = known_vals[param_index]; if (t && TREE_CODE (t) == ADDR_EXPR diff -Naur gcc-4.8.1.orig/gcc/ipa-prop.c gcc-4.8.1/gcc/ipa-prop.c --- gcc-4.8.1.orig/gcc/ipa-prop.c 2013-05-23 08:25:23.000000000 -0500 +++ gcc-4.8.1/gcc/ipa-prop.c 2013-06-24 07:57:52.158957000 -0500 @@ -678,13 +678,19 @@ bool modified = false; ao_ref refd; - gcc_checking_assert (gimple_vuse (stmt)); if (parm_ainfo && parm_ainfo->ref_modified) return false; - ao_ref_init (&refd, ref); - walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified, - NULL); + if (optimize) + { + gcc_checking_assert (gimple_vuse (stmt)); + ao_ref_init (&refd, ref); + walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified, + NULL); + } + else + modified = true; + if (parm_ainfo && modified) parm_ainfo->ref_modified = true; return !modified; diff -Naur gcc-4.8.1.orig/gcc/ira.c gcc-4.8.1/gcc/ira.c --- gcc-4.8.1.orig/gcc/ira.c 2013-05-23 05:36:55.000000000 -0500 +++ gcc-4.8.1/gcc/ira.c 2013-06-20 16:15:52.020104000 -0500 @@ -2863,6 +2863,28 @@ } } +/* Check whether the SUBREG is a paradoxical subreg and set the result + in PDX_SUBREGS. */ + +static int +set_paradoxical_subreg (rtx *subreg, void *pdx_subregs) +{ + rtx reg; + + if ((*subreg) == NULL_RTX) + return 1; + if (GET_CODE (*subreg) != SUBREG) + return 0; + reg = SUBREG_REG (*subreg); + if (!REG_P (reg)) + return 0; + + if (paradoxical_subreg_p (*subreg)) + ((bool *)pdx_subregs)[REGNO (reg)] = true; + + return 0; +} + /* In DEBUG_INSN location adjust REGs from CLEARED_REGS bitmap to the equivalent replacement. */ @@ -2901,16 +2923,33 @@ basic_block bb; int loop_depth; bitmap cleared_regs; + bool *pdx_subregs; /* We need to keep track of whether or not we recorded a LABEL_REF so that we know if the jump optimizer needs to be rerun. */ recorded_label_ref = 0; + /* Use pdx_subregs to show whether a reg is used in a paradoxical + subreg. */ + pdx_subregs = XCNEWVEC (bool, max_regno); + reg_equiv = XCNEWVEC (struct equivalence, max_regno); grow_reg_equivs (); init_alias_analysis (); + /* Scan insns and set pdx_subregs[regno] if the reg is used in a + paradoxical subreg. Don't set such reg sequivalent to a mem, + because lra will not substitute such equiv memory in order to + prevent access beyond allocated memory for paradoxical memory subreg. */ + FOR_EACH_BB (bb) + FOR_BB_INSNS (bb, insn) + { + if (! INSN_P (insn)) + continue; + for_each_rtx (&insn, set_paradoxical_subreg, (void *)pdx_subregs); + } + /* Scan the insns and find which registers have equivalences. Do this in a separate scan of the insns because (due to -fcse-follow-jumps) a register can be set below its use. */ @@ -3008,6 +3047,13 @@ continue; } + /* Don't set reg (if pdx_subregs[regno] == true) equivalent to a mem. */ + if (MEM_P (src) && pdx_subregs[regno]) + { + note_stores (set, no_equiv, NULL); + continue; + } + note = find_reg_note (insn, REG_EQUAL, NULL_RTX); /* cse sometimes generates function invariants, but doesn't put a @@ -3166,7 +3212,8 @@ && reg_equiv[regno].init_insns != const0_rtx && ! find_reg_note (XEXP (reg_equiv[regno].init_insns, 0), REG_EQUIV, NULL_RTX) - && ! contains_replace_regs (XEXP (dest, 0))) + && ! contains_replace_regs (XEXP (dest, 0)) + && ! pdx_subregs[regno]) { rtx init_insn = XEXP (reg_equiv[regno].init_insns, 0); if (validate_equiv_mem (init_insn, src, dest) @@ -3357,6 +3404,7 @@ end_alias_analysis (); free (reg_equiv); + free (pdx_subregs); return recorded_label_ref; } diff -Naur gcc-4.8.1.orig/gcc/lra-assigns.c gcc-4.8.1/gcc/lra-assigns.c --- gcc-4.8.1.orig/gcc/lra-assigns.c 2013-02-15 13:17:02.000000000 -0600 +++ gcc-4.8.1/gcc/lra-assigns.c 2013-07-19 15:47:57.560539000 -0500 @@ -116,6 +116,11 @@ /* Map regno to the corresponding regno assignment info. */ static struct regno_assign_info *regno_assign_info; +/* All inherited, subreg or optional pseudos created before last spill + sub-pass. Such pseudos are permitted to get memory instead of hard + regs. */ +static bitmap_head non_reload_pseudos; + /* Process a pseudo copy with execution frequency COPY_FREQ connecting REGNO1 and REGNO2 to form threads. */ static void @@ -194,6 +199,15 @@ if ((diff = (ira_class_hard_regs_num[cl1] - ira_class_hard_regs_num[cl2])) != 0) return diff; + if ((diff + = (ira_reg_class_max_nregs[cl2][lra_reg_info[r2].biggest_mode] + - ira_reg_class_max_nregs[cl1][lra_reg_info[r1].biggest_mode])) != 0 + /* The code below executes rarely as nregs == 1 in most cases. + So we should not worry about using faster data structures to + check reload pseudos. */ + && ! bitmap_bit_p (&non_reload_pseudos, r1) + && ! bitmap_bit_p (&non_reload_pseudos, r2)) + return diff; if ((diff = (regno_assign_info[regno_assign_info[r2].first].freq - regno_assign_info[regno_assign_info[r1].first].freq)) != 0) return diff; @@ -1156,7 +1170,6 @@ rtx insn; basic_block bb; bitmap_head changed_insns, do_not_assign_nonreload_pseudos; - bitmap_head non_reload_pseudos; unsigned int u; bitmap_iterator bi; bool reload_p; @@ -1265,7 +1278,7 @@ } } } - lra_assert (asm_p); + gcc_assert (asm_p); break; } /* This is a very rare event. We can not assign a hard diff -Naur gcc-4.8.1.orig/gcc/lra-constraints.c gcc-4.8.1/gcc/lra-constraints.c --- gcc-4.8.1.orig/gcc/lra-constraints.c 2013-05-02 14:16:29.000000000 -0500 +++ gcc-4.8.1/gcc/lra-constraints.c 2013-08-15 03:03:32.168856000 -0500 @@ -1388,7 +1388,7 @@ for (nalt = 0; nalt < n_alternatives; nalt++) { /* Loop over operands for one constraint alternative. */ -#ifdef HAVE_ATTR_enabled +#if HAVE_ATTR_enabled if (curr_id->alternative_enabled_p != NULL && ! curr_id->alternative_enabled_p[nalt]) continue; @@ -4396,7 +4396,7 @@ bitmap_clear_bit (&live_regs, reg->regno); /* Mark each used value as live. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) - if (reg->type == OP_IN + if (reg->type != OP_OUT && bitmap_bit_p (&check_only_regs, reg->regno)) bitmap_set_bit (&live_regs, reg->regno); /* It is quite important to remove dead move insns because it diff -Naur gcc-4.8.1.orig/gcc/Makefile.in gcc-4.8.1/gcc/Makefile.in --- gcc-4.8.1.orig/gcc/Makefile.in 2013-05-21 11:00:49.000000000 -0500 +++ gcc-4.8.1/gcc/Makefile.in 2013-07-08 04:14:34.834106000 -0500 @@ -2505,7 +2505,7 @@ $(TM_H) coretypes.h $(TREE_PASS_H) $(FLAGS_H) \ tree-iterator.h $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_INLINE_H) \ $(VEC_H) langhooks.h alloc-pool.h pointer-set.h $(CFGLOOP_H) \ - $(TARGET_H) $(GIMPLE_PRETTY_PRINT_H) $(DIAGNOSTIC_CORE_H) + $(TARGET_H) $(GIMPLE_PRETTY_PRINT_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(GGC_H) \ $(DIAGNOSTIC_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TM_H) \ diff -Naur gcc-4.8.1.orig/gcc/omp-low.c gcc-4.8.1/gcc/omp-low.c --- gcc-4.8.1.orig/gcc/omp-low.c 2013-05-16 05:45:55.000000000 -0500 +++ gcc-4.8.1/gcc/omp-low.c 2013-08-28 05:10:43.062839000 -0500 @@ -836,6 +836,7 @@ DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var); DECL_IGNORED_P (copy) = DECL_IGNORED_P (var); DECL_CONTEXT (copy) = DECL_CONTEXT (var); + TREE_NO_WARNING (copy) = TREE_NO_WARNING (var); TREE_USED (copy) = 1; DECL_SEEN_IN_BIND_EXPR_P (copy) = 1; diff -Naur gcc-4.8.1.orig/gcc/passes.c gcc-4.8.1/gcc/passes.c --- gcc-4.8.1.orig/gcc/passes.c 2013-02-20 09:19:13.000000000 -0600 +++ gcc-4.8.1/gcc/passes.c 2013-08-28 03:29:48.447578000 -0500 @@ -1531,15 +1531,15 @@ /* Perform simple scalar cleanup which is constant/copy propagation. */ NEXT_PASS (pass_ccp); NEXT_PASS (pass_object_sizes); + /* Fold remaining builtins. */ + NEXT_PASS (pass_fold_builtins); /* Copy propagation also copy-propagates constants, this is necessary - to forward object-size results properly. */ + to forward object-size and builtin folding results properly. */ NEXT_PASS (pass_copy_prop); + NEXT_PASS (pass_dce); NEXT_PASS (pass_asan); NEXT_PASS (pass_tsan); NEXT_PASS (pass_rename_ssa_copies); - NEXT_PASS (pass_dce); - /* Fold remaining builtins. */ - NEXT_PASS (pass_fold_builtins); /* ??? We do want some kind of loop invariant motion, but we possibly need to adjust LIM to be more friendly towards preserving accurate debug information here. */ diff -Naur gcc-4.8.1.orig/gcc/recog.c gcc-4.8.1/gcc/recog.c --- gcc-4.8.1.orig/gcc/recog.c 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/recog.c 2013-08-05 15:24:39.437775000 -0500 @@ -1949,9 +1949,6 @@ (strictp ? strict_memory_address_addr_space_p : memory_address_addr_space_p); unsigned int mode_sz = GET_MODE_SIZE (mode); -#ifdef POINTERS_EXTEND_UNSIGNED - enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); -#endif if (CONSTANT_ADDRESS_P (y)) return 1; @@ -1962,6 +1959,13 @@ if (mode_dependent_address_p (y, as)) return 0; + enum machine_mode address_mode = GET_MODE (y); + if (address_mode == VOIDmode) + address_mode = targetm.addr_space.address_mode (as); +#ifdef POINTERS_EXTEND_UNSIGNED + enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); +#endif + /* ??? How much offset does an offsettable BLKmode reference need? Clearly that depends on the situation in which it's being used. However, the current situation in which we test 0xffffffff is @@ -1977,7 +1981,7 @@ int good; y1 = *y2; - *y2 = plus_constant (GET_MODE (y), *y2, mode_sz - 1); + *y2 = plus_constant (address_mode, *y2, mode_sz - 1); /* Use QImode because an odd displacement may be automatically invalid for any wider mode. But it should be valid for a single byte. */ good = (*addressp) (QImode, y, as); @@ -1998,20 +2002,20 @@ if (GET_CODE (y) == LO_SUM && mode != BLKmode && mode_sz <= GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT) - z = gen_rtx_LO_SUM (GET_MODE (y), XEXP (y, 0), - plus_constant (GET_MODE (y), XEXP (y, 1), + z = gen_rtx_LO_SUM (address_mode, XEXP (y, 0), + plus_constant (address_mode, XEXP (y, 1), mode_sz - 1)); #ifdef POINTERS_EXTEND_UNSIGNED /* Likewise for a ZERO_EXTEND from pointer_mode. */ else if (POINTERS_EXTEND_UNSIGNED > 0 && GET_CODE (y) == ZERO_EXTEND && GET_MODE (XEXP (y, 0)) == pointer_mode) - z = gen_rtx_ZERO_EXTEND (GET_MODE (y), + z = gen_rtx_ZERO_EXTEND (address_mode, plus_constant (pointer_mode, XEXP (y, 0), mode_sz - 1)); #endif else - z = plus_constant (GET_MODE (y), y, mode_sz - 1); + z = plus_constant (address_mode, y, mode_sz - 1); /* Use QImode because an odd displacement may be automatically invalid for any wider mode. But it should be valid for a single byte. */ @@ -3116,32 +3120,53 @@ regno = raw_regno; #endif - /* Don't allocate fixed registers. */ - if (fixed_regs[regno]) - continue; - /* Don't allocate global registers. */ - if (global_regs[regno]) - continue; - /* Make sure the register is of the right class. */ - if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno)) - continue; - /* And can support the mode we need. */ + /* Can it support the mode we need? */ if (! HARD_REGNO_MODE_OK (regno, mode)) continue; - /* And that we don't create an extra save/restore. */ - if (! call_used_regs[regno] && ! df_regs_ever_live_p (regno)) - continue; - if (! targetm.hard_regno_scratch_ok (regno)) - continue; - - /* And we don't clobber traceback for noreturn functions. */ - if ((regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM) - && (! reload_completed || frame_pointer_needed)) - continue; success = 1; - for (j = hard_regno_nregs[regno][mode] - 1; j >= 0; j--) + for (j = 0; success && j < hard_regno_nregs[regno][mode]; j++) { + /* Don't allocate fixed registers. */ + if (fixed_regs[regno + j]) + { + success = 0; + break; + } + /* Don't allocate global registers. */ + if (global_regs[regno + j]) + { + success = 0; + break; + } + /* Make sure the register is of the right class. */ + if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j)) + { + success = 0; + break; + } + /* And that we don't create an extra save/restore. */ + if (! call_used_regs[regno + j] && ! df_regs_ever_live_p (regno + j)) + { + success = 0; + break; + } + + if (! targetm.hard_regno_scratch_ok (regno + j)) + { + success = 0; + break; + } + + /* And we don't clobber traceback for noreturn functions. */ + if ((regno + j == FRAME_POINTER_REGNUM + || regno + j == HARD_FRAME_POINTER_REGNUM) + && (! reload_completed || frame_pointer_needed)) + { + success = 0; + break; + } + if (TEST_HARD_REG_BIT (*reg_set, regno + j) || TEST_HARD_REG_BIT (live, regno + j)) { @@ -3149,6 +3174,7 @@ break; } } + if (success) { add_to_hard_reg_set (reg_set, mode, regno); diff -Naur gcc-4.8.1.orig/gcc/simplify-rtx.c gcc-4.8.1/gcc/simplify-rtx.c --- gcc-4.8.1.orig/gcc/simplify-rtx.c 2013-03-05 00:04:14.000000000 -0600 +++ gcc-4.8.1/gcc/simplify-rtx.c 2013-07-08 03:15:01.706973000 -0500 @@ -2784,6 +2784,7 @@ HOST_WIDE_INT mask = INTVAL (trueop1) << count; if (mask >> count == INTVAL (trueop1) + && trunc_int_for_mode (mask, mode) == mask && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0) return simplify_gen_binary (ASHIFTRT, mode, plus_constant (mode, XEXP (op0, 0), diff -Naur gcc-4.8.1.orig/gcc/testsuite/c-c++-common/gomp/pr58257.c gcc-4.8.1/gcc/testsuite/c-c++-common/gomp/pr58257.c --- gcc-4.8.1.orig/gcc/testsuite/c-c++-common/gomp/pr58257.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/c-c++-common/gomp/pr58257.c 2013-08-28 05:10:43.062839000 -0500 @@ -0,0 +1,15 @@ +/* PR middle-end/58257 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fopenmp -Wall" } */ + +int +foo (int n) +{ + int a[10][10]; + int x, y; +#pragma omp parallel for collapse(2) /* { dg-bogus "may be used uninitialized in this function" } */ + for (x = 0; x < n; x++) /* { dg-bogus "may be used uninitialized in this function" } */ + for (y = 0; y < n; y++) + a[x][y] = x + y * y; + return a[0][0]; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.c-torture/compile/pr58164.c gcc-4.8.1/gcc/testsuite/gcc.c-torture/compile/pr58164.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.c-torture/compile/pr58164.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.c-torture/compile/pr58164.c 2013-08-16 04:06:41.868666000 -0500 @@ -0,0 +1,8 @@ +/* PR tree-optimization/58164 */ + +int +foo (void) +{ + int x = 0; + goto *&x; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.c-torture/execute/nest-align-1.x gcc-4.8.1/gcc/testsuite/gcc.c-torture/execute/nest-align-1.x --- gcc-4.8.1.orig/gcc/testsuite/gcc.c-torture/execute/nest-align-1.x 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.c-torture/execute/nest-align-1.x 2013-07-10 16:06:27.116312000 -0500 @@ -0,0 +1,5 @@ +# Force bigger stack alignment for PowerPC EABI targets. +if { [istarget "powerpc-*-eabi*"] } { + set additional_flags "-mno-eabi" +} +return 0 diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.c-torture/execute/pr57568.c gcc-4.8.1/gcc/testsuite/gcc.c-torture/execute/pr57568.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.c-torture/execute/pr57568.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.c-torture/execute/pr57568.c 2013-06-09 13:33:32.138968000 -0500 @@ -0,0 +1,12 @@ +/* PR target/57568 */ + +extern void abort (void); +int a[6][9] = { }, b = 1, *c = &a[3][5]; + +int +main () +{ + if (b && (*c = *c + *c)) + abort (); + return 0; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.c-torture/execute/pr57829.c gcc-4.8.1/gcc/testsuite/gcc.c-torture/execute/pr57829.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.c-torture/execute/pr57829.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.c-torture/execute/pr57829.c 2013-07-08 03:15:01.706973000 -0500 @@ -0,0 +1,31 @@ +/* PR rtl-optimization/57829 */ + +__attribute__((noinline, noclone)) +int +f1 (int k) +{ + return 2 | ((k - 1) >> ((int) sizeof (int) * __CHAR_BIT__ - 1)); +} + +__attribute__((noinline, noclone)) +long int +f2 (long int k) +{ + return 2L | ((k - 1L) >> ((int) sizeof (long int) * __CHAR_BIT__ - 1)); +} + +__attribute__((noinline, noclone)) +int +f3 (int k) +{ + k &= 63; + return 4 | ((k + 2) >> 5); +} + +int +main () +{ + if (f1 (1) != 2 || f2 (1L) != 2L || f3 (63) != 6 || f3 (1) != 4) + __builtin_abort (); + return 0; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.c-torture/execute/pr58209.c gcc-4.8.1/gcc/testsuite/gcc.c-torture/execute/pr58209.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.c-torture/execute/pr58209.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.c-torture/execute/pr58209.c 2013-08-23 02:35:01.611004000 -0500 @@ -0,0 +1,32 @@ +/* PR tree-optimization/58209 */ + +extern void abort (void); +typedef __INTPTR_TYPE__ T; +T buf[1024]; + +T * +foo (T n) +{ + if (n == 0) + return (T *) buf; + T s = (T) foo (n - 1); + return (T *) (s + sizeof (T)); +} + +T * +bar (T n) +{ + if (n == 0) + return buf; + return foo (n - 1) + 1; +} + +int +main () +{ + int i; + for (i = 0; i < 27; i++) + if (foo (i) != buf + i || bar (i) != buf + i) + abort (); + return 0; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.dg/asan/pr56417.c gcc-4.8.1/gcc/testsuite/gcc.dg/asan/pr56417.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.dg/asan/pr56417.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.dg/asan/pr56417.c 2013-08-13 12:02:13.543712000 -0500 @@ -0,0 +1,9 @@ +/* PR sanitizer/56417 */ +/* { dg-do compile } */ +/* { dg-options "-w" } */ + +int +foo (void) +{ + return __builtin_strlen (&foo); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.dg/ipa/pr57358.c gcc-4.8.1/gcc/testsuite/gcc.dg/ipa/pr57358.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.dg/ipa/pr57358.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.dg/ipa/pr57358.c 2013-06-24 07:57:52.158957000 -0500 @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct t { void (*func)(void*); }; +void test_func(struct t* a) __attribute__((optimize("O0"))); +void test_func(struct t* a) +{ + a->func(0); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.dg/pr56977.c gcc-4.8.1/gcc/testsuite/gcc.dg/pr56977.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.dg/pr56977.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.dg/pr56977.c 2013-08-28 03:29:48.447578000 -0500 @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-Og" } */ + +__attribute__((__error__("error"))) void error (); + +void f (int i) { + if (__builtin_constant_p (i)) { + error (); + } +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.dg/pr57518.c gcc-4.8.1/gcc/testsuite/gcc.dg/pr57518.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.dg/pr57518.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.dg/pr57518.c 2013-06-20 16:15:52.020104000 -0500 @@ -0,0 +1,15 @@ +/* PR rtl-optimization/57130 */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-ira" } */ +/* { dg-final { scan-rtl-dump-not "REG_EQUIV.*mem.*\"ip\"" "ira" } } */ + +char ip[10]; +int total; + +void foo() { + int t; + + t = ip[2]; + total = t & 0x3; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.dg/pr57980.c gcc-4.8.1/gcc/testsuite/gcc.dg/pr57980.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.dg/pr57980.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.dg/pr57980.c 2013-08-13 08:34:08.741199000 -0500 @@ -0,0 +1,19 @@ +/* PR tree-optimization/57980 */ +/* { dg-do compile } */ +/* { dg-options "-O -foptimize-sibling-calls -w" } */ + +typedef int V __attribute__ ((vector_size (2 * sizeof (int)))); +extern V f (void); + +V +bar (void) +{ + return -f (); +} + +V +foo (void) +{ + V v = { }; + return v - f (); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.dg/pr58145-1.c gcc-4.8.1/gcc/testsuite/gcc.dg/pr58145-1.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.dg/pr58145-1.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.dg/pr58145-1.c 2013-08-14 15:36:12.151519000 -0500 @@ -0,0 +1,37 @@ +/* PR tree-optimization/58145 */ +/* { dg-do compile { target { int32plus } } } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +struct S { unsigned int data : 32; }; +struct T { unsigned int data; }; +volatile struct S s2; + +void +f1 (int val) +{ + struct S s = { .data = val }; + *(volatile struct S *) 0x880000UL = s; +} + +void +f2 (int val) +{ + struct T t = { .data = val }; + *(volatile struct T *) 0x880000UL = t; +} + +void +f3 (int val) +{ + *(volatile unsigned int *) 0x880000UL = val; +} + +void +f4 (int val) +{ + struct S s = { .data = val }; + s2 = s; +} + +/* { dg-final { scan-tree-dump-times " ={v} " 4 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.dg/pr58145-2.c gcc-4.8.1/gcc/testsuite/gcc.dg/pr58145-2.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.dg/pr58145-2.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.dg/pr58145-2.c 2013-08-14 15:36:12.151519000 -0500 @@ -0,0 +1,51 @@ +/* PR tree-optimization/58145 */ +/* { dg-do compile { target { int32plus } } } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +struct S { unsigned int data : 32; }; +struct T { unsigned int data; }; +volatile struct S s2; + +static inline void +f1 (int val) +{ + struct S s = { .data = val }; + *(volatile struct S *) 0x880000UL = s; +} + +static inline void +f2 (int val) +{ + struct T t = { .data = val }; + *(volatile struct T *) 0x880000UL = t; +} + +static inline void +f3 (int val) +{ + *(volatile unsigned int *) 0x880000UL = val; +} + +static inline void +f4 (int val) +{ + struct S s = { .data = val }; + s2 = s; +} + +void +f5 (void) +{ + int i; + for (i = 0; i < 100; i++) + f1 (0); + for (i = 0; i < 100; i++) + f2 (0); + for (i = 0; i < 100; i++) + f3 (0); + for (i = 0; i < 100; i++) + f4 (0); +} + +/* { dg-final { scan-tree-dump-times " ={v} " 4 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.dg/torture/pr58041.c gcc-4.8.1/gcc/testsuite/gcc.dg/torture/pr58041.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.dg/torture/pr58041.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.dg/torture/pr58041.c 2013-08-06 12:35:11.119492000 -0500 @@ -0,0 +1,33 @@ +/* { dg-do run } */ + +typedef long long V + __attribute__ ((vector_size (2 * sizeof (long long)), may_alias)); + +struct s +{ + char u; + V v[2]; +} __attribute__((packed,aligned(1))); + +__attribute__((noinline, noclone)) +long long foo(struct s *x, int y, V *z) +{ + V a = x->v[y]; + x->v[y] = *z; + return a[1]; +} + +struct s a = {0,{{0,0},{0,0}}}; +int main() +{ + V v1 = {0,1}; + V v2 = {0,2}; + + if (foo(&a,0,&v1) != 0) + __builtin_abort(); + if (foo(&a,0,&v2) != 1) + __builtin_abort(); + if (foo(&a,1,&v1) != 0) + __builtin_abort(); + return 0; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/arm/lp1189445.c gcc-4.8.1/gcc/testsuite/gcc.target/arm/lp1189445.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/arm/lp1189445.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/arm/lp1189445.c 2013-08-09 01:59:01.329587000 -0500 @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_neon } */ +/* { dg-add-options arm_neon } */ +/* { dg-options "-O3" } */ + +int id; +int +test (const long int *data) +{ + int i, retval; + retval = id; + for (i = 0; i < id; i++) + { + retval &= (data[i] <= 0); + } + + return (retval); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/arm/pr58041.c gcc-4.8.1/gcc/testsuite/gcc.target/arm/pr58041.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/arm/pr58041.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/arm/pr58041.c 2013-08-06 10:08:59.668112000 -0500 @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -mno-unaligned-access" } */ +/* { dg-final { scan-assembler "ldrb" } } */ +/* { dg-final { scan-assembler "strb" } } */ + +struct s +{ + char u; + long long v[2]; +} __attribute__((packed,aligned(1))); + +__attribute__((noinline, noclone)) +long long foo(struct s *x, int y, long long z) +{ + long long a = x->v[y]; + x->v[y] = z; + return a; +} + +struct s a = {0,{0,0}}; +int main() +{ + if (foo(&a,0,1) != 0) + __builtin_abort(); + if (foo(&a,0,2) != 1) + __builtin_abort(); + if (foo(&a,1,1) != 0) + __builtin_abort(); + return 0; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/arm/thumb1-Os-mult.c gcc-4.8.1/gcc/testsuite/gcc.target/arm/thumb1-Os-mult.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/arm/thumb1-Os-mult.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/arm/thumb1-Os-mult.c 2013-07-25 00:27:55.786383000 -0500 @@ -0,0 +1,12 @@ +/* { dg-require-effective-target arm_thumb1_ok } */ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +/* { dg-skip-if "" { ! { arm_thumb1 } } } */ + +int +mymul3 (int x) +{ + return x * 0x555; +} + +/* { dg-final { scan-assembler "mul\[\\t \]*r.,\[\\t \]*r." } } */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/avr/torture/builtins-4-roundfx.c gcc-4.8.1/gcc/testsuite/gcc.target/avr/torture/builtins-4-roundfx.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/avr/torture/builtins-4-roundfx.c 2013-02-08 04:13:37.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/avr/torture/builtins-4-roundfx.c 2013-07-19 06:15:26.382992000 -0500 @@ -72,11 +72,11 @@ static void test2hr (void) { - TEST2 (hr, 1, 0x7f, 0x40); - TEST2 (hr, 2, 0x7f, 0b1100000); - TEST2 (hr, 3, 0x7f, 0b1110000); - TEST2 (hr, 4, 0x7f, 0b1111000); - + TEST2 (hr, 1, 0x7f, 0x7f); + TEST2 (hr, 2, 0x70, 0x7f); + TEST2 (hr, 3, 0x78, 0x7f); + TEST2 (hr, 4, 0x7f, 0x7f); + TEST2 (uhr, 1, 0x7f, 0x80); TEST2 (uhr, 2, 0x7f, 0x80); TEST2 (uhr, 3, 0x7f, 0x80); @@ -85,10 +85,13 @@ void test2k (void) { - TEST2 (k, 1, 0x7fffffff, 0x7fff8000 | 0b100000000000000); - TEST2 (k, 2, 0x7fffffff, 0x7fff8000 | 0b110000000000000); - TEST2 (k, 3, 0x7fffffff, 0x7fff8000 | 0b111000000000000); - TEST2 (k, 4, 0x7fffffff, 0x7fff8000 | 0b111100000000000); + TEST2 (k, 1, 0x7fffff00, 0x7fffffff); + TEST2 (k, 2, 0x7ffffff0, 0x7fffffff); + TEST2 (k, 2, 0x7ffff000, 0x7fffffff); + TEST2 (k, 3, 0x7ffff000, 0x7ffff000); + TEST2 (k, 3, 0x7ffff800, 0x7fffffff); + TEST2 (k, 3, 0x7ffff7ff, 0x7ffff000); + TEST2 (k, 4, 0x7ffff7ff, 0x7ffff800); TEST2 (uk, 1, 0x7fffffff, 1ul << 31); TEST2 (uk, 2, 0x7fffffff, 1ul << 31); diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/bmi-1.c gcc-4.8.1/gcc/testsuite/gcc.target/i386/bmi-1.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/bmi-1.c 2010-11-10 16:02:23.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/i386/bmi-1.c 2013-07-19 02:38:07.333150000 -0500 @@ -1,11 +1,11 @@ /* { dg-do compile } */ /* { dg-options "-O2 -mbmi " } */ -/* { dg-final { scan-assembler "andn\[^\\n]*(%|)eax" } } */ -/* { dg-final { scan-assembler "bextr\[^\\n]*(%|)eax" } } */ -/* { dg-final { scan-assembler "blsi\[^\\n]*(%|)eax" } } */ -/* { dg-final { scan-assembler "blsmsk\[^\\n]*(%|)eax" } } */ -/* { dg-final { scan-assembler "blsr\[^\\n]*(%|)eax" } } */ -/* { dg-final { scan-assembler "tzcntl\[^\\n]*(%|)eax" } } */ +/* { dg-final { scan-assembler "andn\[^\\n]*eax" } } */ +/* { dg-final { scan-assembler-times "bextr\[ \\t]+\[^\\n]*eax" 2 } } */ +/* { dg-final { scan-assembler-times "blsi\[^\\n]*eax" 2 } } */ +/* { dg-final { scan-assembler-times "blsmsk\[^\\n]*eax" 2 } } */ +/* { dg-final { scan-assembler-times "blsr\[^\\n]*eax" 2 } } */ +/* { dg-final { scan-assembler-times "tzcntl\[^\\n]*eax" 2 } } */ #include @@ -22,25 +22,57 @@ } unsigned int +func_bextr32_3args (unsigned int X, + unsigned int Y, + unsigned int Z) +{ + return _bextr_u32(X, Y, Z); +} + +unsigned int func_blsi32 (unsigned int X) { return __blsi_u32(X); } unsigned int +func_blsi32_2 (unsigned int X) +{ + return _blsi_u32(X); +} + +unsigned int func_blsmsk32 (unsigned int X) { return __blsmsk_u32(X); } unsigned int +func_blsmsk32_2 (unsigned int X) +{ + return _blsmsk_u32(X); +} + +unsigned int func_blsr32 (unsigned int X) { return __blsr_u32(X); } unsigned int +func_blsr32_2 (unsigned int X) +{ + return _blsr_u32(X); +} + +unsigned int func_tzcnt32 (unsigned int X) { return __tzcnt_u32(X); } + +unsigned int +func_tzcnt32_2 (unsigned int X) +{ + return _tzcnt_u32(X); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/bmi2-bzhi-1.c gcc-4.8.1/gcc/testsuite/gcc.target/i386/bmi2-bzhi-1.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/bmi2-bzhi-1.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/i386/bmi2-bzhi-1.c 2013-06-27 11:45:44.733142000 -0500 @@ -0,0 +1,31 @@ +/* PR target/57623 */ +/* { dg-do assemble { target bmi2 } } */ +/* { dg-options "-O2 -mbmi2" } */ + +#include + +unsigned int +f1 (unsigned int x, unsigned int *y) +{ + return _bzhi_u32 (x, *y); +} + +unsigned int +f2 (unsigned int *x, unsigned int y) +{ + return _bzhi_u32 (*x, y); +} + +#ifdef __x86_64__ +unsigned long long +f3 (unsigned long long x, unsigned long long *y) +{ + return _bzhi_u64 (x, *y); +} + +unsigned long long +f4 (unsigned long long *x, unsigned long long y) +{ + return _bzhi_u64 (*x, y); +} +#endif diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/bmi-2.c gcc-4.8.1/gcc/testsuite/gcc.target/i386/bmi-2.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/bmi-2.c 2011-07-09 14:25:11.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/gcc.target/i386/bmi-2.c 2013-07-19 02:38:07.333150000 -0500 @@ -1,11 +1,11 @@ /* { dg-do compile { target { ! { ia32 } } } } */ /* { dg-options "-O2 -mbmi " } */ -/* { dg-final { scan-assembler "andn\[^\\n]*(%|)rax" } } */ -/* { dg-final { scan-assembler "bextr\[^\\n]*(%|)rax" } } */ -/* { dg-final { scan-assembler "blsi\[^\\n]*(%|)rax" } } */ -/* { dg-final { scan-assembler "blsmsk\[^\\n]*(%|)rax" } } */ -/* { dg-final { scan-assembler "blsr\[^\\n]*(%|)rax" } } */ -/* { dg-final { scan-assembler "tzcntq\[^\\n]*(%|)rax" } } */ +/* { dg-final { scan-assembler "andn\[^\\n]*rax" } } */ +/* { dg-final { scan-assembler-times "bextr\[ \\t]+\[^\\n]*rax" 2 } } */ +/* { dg-final { scan-assembler-times "blsi\[^\\n]*rax" 2 } } */ +/* { dg-final { scan-assembler-times "blsmsk\[^\\n]*rax" 2 } } */ +/* { dg-final { scan-assembler-times "blsr\[^\\n]*rax" 2 } } */ +/* { dg-final { scan-assembler-times "tzcntq\[^\\n]*rax" 2 } } */ #include @@ -22,25 +22,57 @@ } unsigned long long +func_bextr64_3args (unsigned long long X, + unsigned long long Y, + unsigned long long Z) +{ + return _bextr_u64 (X, Y, Z); +} + +unsigned long long func_blsi64 (unsigned long long X) { return __blsi_u64 (X); } unsigned long long +func_blsi64_2 (unsigned long long X) +{ + return _blsi_u64 (X); +} + +unsigned long long func_blsmsk64 (unsigned long long X) { return __blsmsk_u64 (X); } unsigned long long +func_blsmsk64_2 (unsigned long long X) +{ + return _blsmsk_u64 (X); +} + +unsigned long long func_blsr64 (unsigned long long X) { return __blsr_u64 (X); } unsigned long long +func_blsr64_2 (unsigned long long X) +{ + return _blsr_u64 (X); +} + +unsigned long long func_tzcnt64 (unsigned long long X) { return __tzcnt_u64 (X); } + +unsigned long long +func_tzcnt64_2 (unsigned long long X) +{ + return _tzcnt_u64 (X); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/bmi-bextr-3.c gcc-4.8.1/gcc/testsuite/gcc.target/i386/bmi-bextr-3.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/bmi-bextr-3.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/i386/bmi-bextr-3.c 2013-06-27 11:49:38.157989000 -0500 @@ -0,0 +1,31 @@ +/* PR target/57623 */ +/* { dg-do assemble { target bmi } } */ +/* { dg-options "-O2 -mbmi" } */ + +#include + +unsigned int +f1 (unsigned int x, unsigned int *y) +{ + return __bextr_u32 (x, *y); +} + +unsigned int +f2 (unsigned int *x, unsigned int y) +{ + return __bextr_u32 (*x, y); +} + +#ifdef __x86_64__ +unsigned long long +f3 (unsigned long long x, unsigned long long *y) +{ + return __bextr_u64 (x, *y); +} + +unsigned long long +f4 (unsigned long long *x, unsigned long long y) +{ + return __bextr_u64 (*x, y); +} +#endif diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/movabs-1.c gcc-4.8.1/gcc/testsuite/gcc.target/i386/movabs-1.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/movabs-1.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/i386/movabs-1.c 2013-08-13 07:45:06.811510000 -0500 @@ -0,0 +1,10 @@ +/* { dg-do assemble } */ +/* { dg-options "-O2 -masm=intel" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target masm_intel } */ + +void +foo (void) +{ + *(volatile long*)0xFFFF800000000000 = -1; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/pr57459.c gcc-4.8.1/gcc/testsuite/gcc.target/i386/pr57459.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/pr57459.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/i386/pr57459.c 2013-08-13 11:40:33.972568000 -0500 @@ -0,0 +1,60 @@ +/* PR rtl-optimization/57459 */ +/* { dg-do run } */ +/* { dg-options "-fno-inline -O2 -minline-all-stringops -fno-omit-frame-pointer" } */ + +int total1[10], total2[10], total3[10], total4[10], total5[10], a[20]; +int len; + +void stackclean() { + void *ptr = __builtin_alloca(20000); + __builtin_memset(ptr, 0, 20000); +} + +void foo(const char *s) { + int r1 = a[1]; + int r2 = a[2]; + int r3 = a[3]; + int r4 = a[4]; + int r5 = a[5]; + + len = __builtin_strlen(s); + + if (s != 0) + return; + + while (r1) { + total1[r1] = r1; + r1--; + } + + while (r2) { + total2[r2] = r2; + r2--; + } + + while (r3) { + total3[r3] = r3; + r3--; + } + + while (r4) { + total4[r4] = r4; + r4--; + } + + while (r5) { + total5[r5] = r5; + r5--; + } +} + +extern void abort (void); + +int main() { + stackclean(); + foo("abcdefgh"); + if (len != 8) + abort (); + return 0; +} + diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/pr57655.c gcc-4.8.1/gcc/testsuite/gcc.target/i386/pr57655.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/pr57655.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/i386/pr57655.c 2013-06-21 08:30:30.950078000 -0500 @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx -mvzeroupper -mno-fp-ret-in-387" } + +/* { dg-error "x87 register return with x87 disabled" "" { target { ! ia32 } } 8 } */ + +long double +foo (long double x) +{ + return __builtin_ilogbl (x); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/pr57736.c gcc-4.8.1/gcc/testsuite/gcc.target/i386/pr57736.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/pr57736.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/i386/pr57736.c 2013-06-28 15:26:27.574295000 -0500 @@ -0,0 +1,41 @@ +/* PR target/57736 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include + +unsigned long long +f1 (void) +{ + return __rdtsc (); +} + +unsigned long long +f2 (unsigned int *x) +{ + return __rdtscp (x); +} + +unsigned long long +f3 (unsigned int x) +{ + return __rdpmc (x); +} + +void +f4 (void) +{ + __rdtsc (); +} + +void +f5 (unsigned int *x) +{ + __rdtscp (x); +} + +void +f6 (unsigned int x) +{ + __rdpmc (x); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/pr57777.c gcc-4.8.1/gcc/testsuite/gcc.target/i386/pr57777.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/pr57777.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/i386/pr57777.c 2013-07-03 15:24:19.796040000 -0500 @@ -0,0 +1,13 @@ +/* PR target/57777 */ +/* { dg-do assemble { target avx2 } } */ +/* { dg-options "-O3 -mavx2" } */ +/* { dg-additional-options "-fpic" { target fpic } } */ + +void +foo (unsigned long *x, int *y) +{ + static unsigned long b[2] = { 0x0UL, 0x9908b0dfUL }; + int c; + for (c = 0; c < 512; c++) + x[c] = b[x[c] & 1UL]; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/pr58218.c gcc-4.8.1/gcc/testsuite/gcc.target/i386/pr58218.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/i386/pr58218.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/i386/pr58218.c 2013-08-23 05:01:34.440607000 -0500 @@ -0,0 +1,5 @@ +/* PR target/58218 */ +/* { dg-do assemble { target lp64 } } */ +/* { dg-options "-mcmodel=medium" } */ + +struct { float x[16385]; } a = { { 0.f, } }; diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/20020118-1.c gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/20020118-1.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/20020118-1.c 2009-04-28 03:38:37.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/20020118-1.c 2013-07-10 16:06:27.116312000 -0500 @@ -1,6 +1,8 @@ /* { dg-do run { target powerpc*-*-* } }*/ /* VxWorks only guarantees 64 bits of alignment (STACK_BOUNDARY == 64). */ /* { dg-skip-if "" { "powerpc*-*-vxworks*" } { "*" } { "" } } */ +/* Force 128-bit stack alignment for eabi targets. */ +/* { dg-options "-mno-eabi" { target powerpc*-*-eabi* } } */ /* Test local alignment. Test new target macro STARTING_FRAME_PHASE. */ /* Origin: Aldy Hernandez . */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/altivec-consts.c gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/altivec-consts.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/altivec-consts.c 2009-01-13 11:52:32.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/altivec-consts.c 2013-06-23 19:59:24.817984000 -0500 @@ -11,31 +11,24 @@ typedef __attribute__ ((vector_size (16))) unsigned short v8hi; typedef __attribute__ ((vector_size (16))) unsigned int v4si; -char w[16] __attribute__((aligned(16))); - - -/* Emulate the vspltis? instructions on a 16-byte array of chars. */ +typedef __attribute__((aligned(16))) char c16[16]; +typedef __attribute__((aligned(16))) short s8[8]; +typedef __attribute__((aligned(16))) int i4[4]; -void vspltisb (char *v, int val) -{ - int i; - for (i = 0; i < 16; i++) - v[i] = val; -} +#define V16QI(V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16) \ + v16qi v = {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16}; \ + static c16 w = {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16}; \ + check_v16qi (v, w); -void vspltish (char *v, int val) -{ - int i; - for (i = 0; i < 16; i += 2) - v[i] = val >> 7, v[i + 1] = val; -} +#define V8HI(V1,V2,V3,V4,V5,V6,V7,V8) \ + v8hi v = {V1,V2,V3,V4,V5,V6,V7,V8}; \ + static s8 w = {V1,V2,V3,V4,V5,V6,V7,V8}; \ + check_v8hi (v, w); -void vspltisw (char *v, int val) -{ - int i; - for (i = 0; i < 16; i += 4) - v[i] = v[i + 1] = v[i + 2] = val >> 7, v[i + 3] = val; -} +#define V4SI(V1,V2,V3,V4) \ + v4si v = {V1,V2,V3,V4}; \ + static i4 w = {V1,V2,V3,V4}; \ + check_v4si (v, w); /* Use three different check functions for each mode-instruction pair. @@ -48,13 +41,13 @@ abort (); } -void __attribute__ ((noinline)) check_v8hi (v8hi v1, char *v2) +void __attribute__ ((noinline)) check_v8hi (v8hi v1, short *v2) { if (memcmp (&v1, v2, 16)) abort (); } -void __attribute__ ((noinline)) check_v4si (v4si v1, char *v2) +void __attribute__ ((noinline)) check_v4si (v4si v1, int *v2) { if (memcmp (&v1, v2, 16)) abort (); @@ -65,72 +58,52 @@ void v16qi_vspltisb () { - v16qi v = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }; - vspltisb (w, 15); - check_v16qi (v, w); + V16QI (15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15); } void v16qi_vspltisb_neg () { - v16qi v = { -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5 }; - vspltisb (w, -5); - check_v16qi (v, w); + V16QI (-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5); } void v16qi_vspltisb_addself () { - v16qi v = { 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 }; - vspltisb (w, 30); - check_v16qi (v, w); + V16QI (30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30); } void v16qi_vspltisb_neg_addself () { - v16qi v = { -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24 }; - vspltisb (w, -24); - check_v16qi (v, w); + V16QI (-24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24); } void v16qi_vspltish () { - v16qi v = { 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15 }; - vspltish (w, 15); - check_v16qi (v, w); + V16QI (0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15); } void v16qi_vspltish_addself () { - v16qi v = { 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30 }; - vspltish (w, 30); - check_v16qi (v, w); + V16QI (0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30); } void v16qi_vspltish_neg () { - v16qi v = { -1, -5, -1, -5, -1, -5, -1, -5, -1, -5, -1, -5, -1, -5, -1, -5 }; - vspltish (w, -5); - check_v16qi (v, w); + V16QI (-1, -5, -1, -5, -1, -5, -1, -5, -1, -5, -1, -5, -1, -5, -1, -5); } void v16qi_vspltisw () { - v16qi v = { 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15 }; - vspltisw (w, 15); - check_v16qi (v, w); + V16QI (0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15); } void v16qi_vspltisw_addself () { - v16qi v = { 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30 }; - vspltisw (w, 30); - check_v16qi (v, w); + V16QI (0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30); } void v16qi_vspltisw_neg () { - v16qi v = { -1, -1, -1, -5, -1, -1, -1, -5, -1, -1, -1, -5, -1, -1, -1, -5 }; - vspltisw (w, -5); - check_v16qi (v, w); + V16QI (-1, -1, -1, -5, -1, -1, -1, -5, -1, -1, -1, -5, -1, -1, -1, -5); } @@ -138,144 +111,104 @@ void v8hi_vspltisb () { - v8hi v = { 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F }; - vspltisb (w, 15); - check_v8hi (v, w); + V8HI (0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F); } void v8hi_vspltisb_addself () { - v8hi v = { 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E }; - vspltisb (w, 30); - check_v8hi (v, w); + V8HI (0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E); } void v8hi_vspltisb_neg () { - v8hi v = { 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB }; - vspltisb (w, -5); - check_v8hi (v, w); + V8HI (0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB); } void v8hi_vspltish () { - v8hi v = { 15, 15, 15, 15, 15, 15, 15, 15 }; - vspltish (w, 15); - check_v8hi (v, w); + V8HI (15, 15, 15, 15, 15, 15, 15, 15); } void v8hi_vspltish_neg () { - v8hi v = { -5, -5, -5, -5, -5, -5, -5, -5 }; - vspltish (w, -5); - check_v8hi (v, w); + V8HI (-5, -5, -5, -5, -5, -5, -5, -5); } void v8hi_vspltish_addself () { - v8hi v = { 30, 30, 30, 30, 30, 30, 30, 30 }; - vspltish (w, 30); - check_v8hi (v, w); + V8HI (30, 30, 30, 30, 30, 30, 30, 30); } void v8hi_vspltish_neg_addself () { - v8hi v = { -24, -24, -24, -24, -24, -24, -24, -24 }; - vspltish (w, -24); - check_v8hi (v, w); + V8HI (-24, -24, -24, -24, -24, -24, -24, -24); } void v8hi_vspltisw () { - v8hi v = { 0, 15, 0, 15, 0, 15, 0, 15 }; - vspltisw (w, 15); - check_v8hi (v, w); + V8HI (0, 15, 0, 15, 0, 15, 0, 15); } void v8hi_vspltisw_addself () { - v8hi v = { 0, 30, 0, 30, 0, 30, 0, 30 }; - vspltisw (w, 30); - check_v8hi (v, w); + V8HI (0, 30, 0, 30, 0, 30, 0, 30); } void v8hi_vspltisw_neg () { - v8hi v = { -1, -5, -1, -5, -1, -5, -1, -5 }; - vspltisw (w, -5); - check_v8hi (v, w); + V8HI (-1, -5, -1, -5, -1, -5, -1, -5); } /* V4SI tests. */ void v4si_vspltisb () { - v4si v = { 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F }; - vspltisb (w, 15); - check_v4si (v, w); + V4SI (0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F); } void v4si_vspltisb_addself () { - v4si v = { 0x1E1E1E1E, 0x1E1E1E1E, 0x1E1E1E1E, 0x1E1E1E1E }; - vspltisb (w, 30); - check_v4si (v, w); + V4SI (0x1E1E1E1E, 0x1E1E1E1E, 0x1E1E1E1E, 0x1E1E1E1E); } void v4si_vspltisb_neg () { - v4si v = { 0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB }; - vspltisb (w, -5); - check_v4si (v, w); + V4SI (0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB); } void v4si_vspltish () { - v4si v = { 0x000F000F, 0x000F000F, 0x000F000F, 0x000F000F }; - vspltish (w, 15); - check_v4si (v, w); + V4SI (0x000F000F, 0x000F000F, 0x000F000F, 0x000F000F); } void v4si_vspltish_addself () { - v4si v = { 0x001E001E, 0x001E001E, 0x001E001E, 0x001E001E }; - vspltish (w, 30); - check_v4si (v, w); + V4SI (0x001E001E, 0x001E001E, 0x001E001E, 0x001E001E); } void v4si_vspltish_neg () { - v4si v = { 0xFFFBFFFB, 0xFFFBFFFB, 0xFFFBFFFB, 0xFFFBFFFB }; - vspltish (w, -5); - check_v4si (v, w); + V4SI (0xFFFBFFFB, 0xFFFBFFFB, 0xFFFBFFFB, 0xFFFBFFFB); } void v4si_vspltisw () { - v4si v = { 15, 15, 15, 15 }; - vspltisw (w, 15); - check_v4si (v, w); + V4SI (15, 15, 15, 15); } void v4si_vspltisw_neg () { - v4si v = { -5, -5, -5, -5 }; - vspltisw (w, -5); - check_v4si (v, w); + V4SI (-5, -5, -5, -5); } void v4si_vspltisw_addself () { - v4si v = { 30, 30, 30, 30 }; - vspltisw (w, 30); - check_v4si (v, w); + V4SI (30, 30, 30, 30); } void v4si_vspltisw_neg_addself () { - v4si v = { -24, -24, -24, -24 }; - vspltisw (w, -24); - check_v4si (v, w); + V4SI (-24, -24, -24, -24); } @@ -316,3 +249,5 @@ v4si_vspltisw_neg_addself (); return 0; } + +/* { dg-final { scan-assembler-not "lvx" { target { ! powerpc*le-*-* } } } } */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/le-altivec-consts.c gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/le-altivec-consts.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/le-altivec-consts.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/le-altivec-consts.c 2013-06-23 19:59:24.817984000 -0500 @@ -0,0 +1,253 @@ +/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */ +/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ +/* { dg-options "-maltivec -mabi=altivec -O2" } */ + +/* Check that "easy" AltiVec constants are correctly synthesized. */ + +extern void abort (void); + +typedef __attribute__ ((vector_size (16))) unsigned char v16qi; +typedef __attribute__ ((vector_size (16))) unsigned short v8hi; +typedef __attribute__ ((vector_size (16))) unsigned int v4si; + +typedef __attribute__((aligned(16))) char c16[16]; +typedef __attribute__((aligned(16))) short s8[8]; +typedef __attribute__((aligned(16))) int i4[4]; + +#define V16QI(V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16) \ + v16qi v = {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16}; \ + static c16 w = {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16}; \ + check_v16qi (v, w); + +#define V8HI(V1,V2,V3,V4,V5,V6,V7,V8) \ + v8hi v = {V1,V2,V3,V4,V5,V6,V7,V8}; \ + static s8 w = {V1,V2,V3,V4,V5,V6,V7,V8}; \ + check_v8hi (v, w); + +#define V4SI(V1,V2,V3,V4) \ + v4si v = {V1,V2,V3,V4}; \ + static i4 w = {V1,V2,V3,V4}; \ + check_v4si (v, w); + + +/* Use three different check functions for each mode-instruction pair. + The callers have no typecasting and no addressable vectors, to make + the test more robust. */ + +void __attribute__ ((noinline)) check_v16qi (v16qi v1, char *v2) +{ + if (memcmp (&v1, v2, 16)) + abort (); +} + +void __attribute__ ((noinline)) check_v8hi (v8hi v1, short *v2) +{ + if (memcmp (&v1, v2, 16)) + abort (); +} + +void __attribute__ ((noinline)) check_v4si (v4si v1, int *v2) +{ + if (memcmp (&v1, v2, 16)) + abort (); +} + + +/* V16QI tests. */ + +void v16qi_vspltisb () +{ + V16QI (15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15); +} + +void v16qi_vspltisb_neg () +{ + V16QI (-5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5); +} + +void v16qi_vspltisb_addself () +{ + V16QI (30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30); +} + +void v16qi_vspltisb_neg_addself () +{ + V16QI (-24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24); +} + +void v16qi_vspltish () +{ + V16QI (15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0); +} + +void v16qi_vspltish_addself () +{ + V16QI (30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0, 30, 0); +} + +void v16qi_vspltish_neg () +{ + V16QI (-5, -1, -5, -1, -5, -1, -5, -1, -5, -1, -5, -1, -5, -1, -5, -1); +} + +void v16qi_vspltisw () +{ + V16QI (15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0); +} + +void v16qi_vspltisw_addself () +{ + V16QI (30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0); +} + +void v16qi_vspltisw_neg () +{ + V16QI (-5, -1, -1, -1, -5, -1, -1, -1, -5, -1, -1, -1, -5, -1, -1, -1); +} + + +/* V8HI tests. */ + +void v8hi_vspltisb () +{ + V8HI (0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F, 0x0F0F); +} + +void v8hi_vspltisb_addself () +{ + V8HI (0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E, 0x1E1E); +} + +void v8hi_vspltisb_neg () +{ + V8HI (0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB, 0xFBFB); +} + +void v8hi_vspltish () +{ + V8HI (15, 15, 15, 15, 15, 15, 15, 15); +} + +void v8hi_vspltish_neg () +{ + V8HI (-5, -5, -5, -5, -5, -5, -5, -5); +} + +void v8hi_vspltish_addself () +{ + V8HI (30, 30, 30, 30, 30, 30, 30, 30); +} + +void v8hi_vspltish_neg_addself () +{ + V8HI (-24, -24, -24, -24, -24, -24, -24, -24); +} + +void v8hi_vspltisw () +{ + V8HI (15, 0, 15, 0, 15, 0, 15, 0); +} + +void v8hi_vspltisw_addself () +{ + V8HI (30, 0, 30, 0, 30, 0, 30, 0); +} + +void v8hi_vspltisw_neg () +{ + V8HI (-5, -1, -5, -1, -5, -1, -5, -1); +} + +/* V4SI tests. */ + +void v4si_vspltisb () +{ + V4SI (0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F, 0x0F0F0F0F); +} + +void v4si_vspltisb_addself () +{ + V4SI (0x1E1E1E1E, 0x1E1E1E1E, 0x1E1E1E1E, 0x1E1E1E1E); +} + +void v4si_vspltisb_neg () +{ + V4SI (0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB, 0xFBFBFBFB); +} + +void v4si_vspltish () +{ + V4SI (0x000F000F, 0x000F000F, 0x000F000F, 0x000F000F); +} + +void v4si_vspltish_addself () +{ + V4SI (0x001E001E, 0x001E001E, 0x001E001E, 0x001E001E); +} + +void v4si_vspltish_neg () +{ + V4SI (0xFFFBFFFB, 0xFFFBFFFB, 0xFFFBFFFB, 0xFFFBFFFB); +} + +void v4si_vspltisw () +{ + V4SI (15, 15, 15, 15); +} + +void v4si_vspltisw_neg () +{ + V4SI (-5, -5, -5, -5); +} + +void v4si_vspltisw_addself () +{ + V4SI (30, 30, 30, 30); +} + +void v4si_vspltisw_neg_addself () +{ + V4SI (-24, -24, -24, -24); +} + + + +int main () +{ + v16qi_vspltisb (); + v16qi_vspltisb_neg (); + v16qi_vspltisb_addself (); + v16qi_vspltisb_neg_addself (); + v16qi_vspltish (); + v16qi_vspltish_addself (); + v16qi_vspltish_neg (); + v16qi_vspltisw (); + v16qi_vspltisw_addself (); + v16qi_vspltisw_neg (); + + v8hi_vspltisb (); + v8hi_vspltisb_addself (); + v8hi_vspltisb_neg (); + v8hi_vspltish (); + v8hi_vspltish_neg (); + v8hi_vspltish_addself (); + v8hi_vspltish_neg_addself (); + v8hi_vspltisw (); + v8hi_vspltisw_addself (); + v8hi_vspltisw_neg (); + + v4si_vspltisb (); + v4si_vspltisb_addself (); + v4si_vspltisb_neg (); + v4si_vspltish (); + v4si_vspltish_addself (); + v4si_vspltish_neg (); + v4si_vspltisw (); + v4si_vspltisw_neg (); + v4si_vspltisw_addself (); + v4si_vspltisw_neg_addself (); + return 0; +} + +/* { dg-final { scan-assembler-not "lvx" { target { powerpc*le-*-* } } } } */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/ppc-spe64-1.c gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/ppc-spe64-1.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/ppc-spe64-1.c 2009-01-12 21:11:48.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/ppc-spe64-1.c 2013-07-08 14:39:20.298935000 -0500 @@ -4,4 +4,4 @@ /* { dg-options "-m64" } */ /* { dg-error "-m64 not supported in this configuration" "SPE not 64-bit" { target *-*-* } 0 } */ -/* { dg-error "64-bit E500 not supported" "64-bit E500" { target *-*-* } 0 } */ +/* { dg-error "64-bit SPE not supported" "64-bit SPE" { target *-*-* } 0 } */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/pr47197.c gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/pr47197.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/pr47197.c 2012-04-24 10:51:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/pr47197.c 2013-07-08 14:38:40.579938000 -0500 @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target powerpc_altivec_ok } */ /* { dg-options "-maltivec" } */ /* Compile-only test to ensure that expressions can be passed to diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/tfmode_off.c gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/tfmode_off.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/powerpc/tfmode_off.c 2012-11-07 15:03:08.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/powerpc/tfmode_off.c 2013-07-08 15:21:45.963328000 -0500 @@ -1,5 +1,6 @@ /* { dg-do assemble } */ /* { dg-skip-if "" { powerpc-ibm-aix* } { "*" } { "" } } */ +/* { dg-skip-if "no TFmode" { powerpc-*-eabi* } { "*" } { "" } } */ /* { dg-options "-O2 -fno-align-functions -mtraceback=no -save-temps" } */ typedef float TFmode __attribute__ ((mode (TF))); diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/sh/pr56547-1.c gcc-4.8.1/gcc/testsuite/gcc.target/sh/pr56547-1.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/sh/pr56547-1.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/sh/pr56547-1.c 2013-06-09 17:02:28.968408000 -0500 @@ -0,0 +1,19 @@ +/* Verify that the fmac insn is used for the expression 'a * b + a' and + 'a * a + a'. + This assumes that the default compiler setting is -ffp-contract=fast. */ +/* { dg-do compile { target "sh*-*-*" } } */ +/* { dg-options "-O1" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmac" 2 } } */ + +float +test_00 (float a, float b) +{ + return a * b + a; +} + +float +test_01 (float a) +{ + return a * a + a; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/gcc.target/sh/pr56547-2.c gcc-4.8.1/gcc/testsuite/gcc.target/sh/pr56547-2.c --- gcc-4.8.1.orig/gcc/testsuite/gcc.target/sh/pr56547-2.c 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gcc.target/sh/pr56547-2.c 2013-06-09 17:02:28.968408000 -0500 @@ -0,0 +1,18 @@ +/* Verify that the fmac insn is used for the expression 'a * b + a' and + 'a * a + a' when -ffast-math is specified. */ +/* { dg-do compile { target "sh*-*-*" } } */ +/* { dg-options "-O1 -ffast-math" } */ +/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2" "-m3" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ +/* { dg-final { scan-assembler-times "fmac" 2 } } */ + +float +test_00 (float a, float b) +{ + return a * b + a; +} + +float +test_01 (float a) +{ + return a * a + a; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C 2013-07-30 11:58:28.826601000 -0500 @@ -0,0 +1,16 @@ +// PR c++/57901 +// { dg-require-effective-target c++11 } + +struct Z { + Z() = default; + Z(Z const&) = default; + constexpr Z(Z&&) {} /* non-trivial (constexpr) move ctor */ +}; + +template +constexpr int fn0(T v) { return 0; } +template +constexpr int fn (T v) { return fn0(v); } + +constexpr auto t0 = fn0(Z()); // OK! +constexpr auto t = fn (Z()); // error! (GCC 4.8.1) diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/decltype55.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/decltype55.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/decltype55.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/decltype55.C 2013-06-21 03:42:56.865320000 -0500 @@ -0,0 +1,20 @@ +// PR c++/53211 +// { dg-do compile { target c++11 } } + +template + struct is_same { static const bool value = false; }; + +template + struct is_same { static const bool value = true; }; + +template +void func(Args... args) +{ + int arr[] = { args... }; + static_assert (is_same::value, ""); +} + +int main() +{ + func(1, 2, 3, 4); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/defaulted44.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/defaulted44.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/defaulted44.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/defaulted44.C 2013-05-31 08:03:45.258613000 -0500 @@ -0,0 +1,24 @@ +// PR c++/57319 +// { dg-require-effective-target c++11 } + +namespace N1 { + struct A { }; + struct B: virtual A { }; + struct C: virtual B { }; + + struct D: C + { + void operator= (D &); + }; +} + +namespace N2 { + struct A { A& operator=(A&&); }; + struct B: virtual A { }; // { dg-warning "move assignment" } + struct C: virtual B { }; // { dg-warning "move assignment" } + + struct D: C + { + void operator= (D &); + }; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/defaulted45.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/defaulted45.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/defaulted45.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/defaulted45.C 2013-07-13 20:06:02.832708000 -0500 @@ -0,0 +1,20 @@ +// { dg-do run } +// { dg-require-effective-target c++11 } + +struct A +{ + int i; + A() = default; + A(int i): i{i} { } + ~A() {} +}; + +int main(int argc, char **argv) +{ + { int i[4] = { 42, 42, 42, 42 }; } + { + A a[4] = { argc }; + if (a[1].i != 0) + __builtin_abort (); + } +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/initlist71.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/initlist71.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/initlist71.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/initlist71.C 2013-05-31 08:03:23.182211000 -0500 @@ -0,0 +1,9 @@ +// PR c++/56930 +// { dg-require-effective-target c++11 } +// { dg-options -Wconversion } + +int main() +{ + int x = sizeof(int); + int y { sizeof(int) }; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto3.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto3.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto3.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto3.C 2013-07-09 12:52:48.262064000 -0500 @@ -0,0 +1,24 @@ +// PR c++/57526 +// { dg-require-effective-target c++11 } + +template +struct A +{ + void bar( ) { } + + void foo( ) + { + auto* this_ptr = this; + auto lc = [&]( ) + { + this_ptr->bar(); + }; + lc(); + } +}; + +int main() +{ + A a; + a.foo(); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C 2013-08-17 20:07:02.824495000 -0500 @@ -0,0 +1,30 @@ +// PR c++/58083 +// { dg-do compile { target c++11 } } + +namespace details { +struct iterator_concept_checker +{ + typedef char yes_type; + typedef char (&no_type)[2]; + + template + static no_type test(...); + + template + static yes_type test( + int* + , void (*)(T) = [](T it) + { + auto copy = T{it}; // copy constructible + copy = it; // copy assignable + copy.~T(); // destroyable + ++it; // incrementable + } + ); +}; +} + +int main() +{ + details::iterator_concept_checker::test(0); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-return1.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-return1.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-return1.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-return1.C 2013-07-09 12:52:34.273079000 -0500 @@ -0,0 +1,26 @@ +// PR c++/57437 +// { dg-require-effective-target c++11 } + +struct A { + int i; + + A(): i(42) {} + A(const A&) = default; + A(A&& a): i(a.i) { a.i = 0; } +}; + +int main() +{ + A x; + + auto y = [x] () mutable { + x.i++; + return x; + }; + + if (y().i != 43) + __builtin_abort (); + + if (y().i != 44) + __builtin_abort (); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/noexcept21.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/noexcept21.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/noexcept21.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/noexcept21.C 2013-07-05 05:23:08.653887000 -0500 @@ -0,0 +1,87 @@ +// PR c++/57645 +// { dg-do compile { target c++11 } } + +struct Thrower +{ + ~Thrower() noexcept(false) { throw 1; } +}; + +struct ExplicitA +{ + ~ExplicitA() {} + + Thrower t; +}; + +struct ExplicitB +{ + ~ExplicitB(); + + Thrower t; +}; + +ExplicitB::~ExplicitB() {} + +struct ExplicitC +{ + ~ExplicitC() = default; + + Thrower t; +}; + +struct ExplicitD +{ + ~ExplicitD(); + + Thrower t; +}; + +ExplicitD::~ExplicitD() = default; + +struct NoThrower +{ + ~NoThrower() noexcept(true) {} +}; + +struct ExplicitE +{ + ~ExplicitE() {} + + NoThrower t; +}; + +struct ExplicitF +{ + ~ExplicitF(); + + NoThrower t; +}; + +ExplicitF::~ExplicitF() {} + +struct ExplicitG +{ + ~ExplicitG() = default; + + NoThrower t; +}; + +struct ExplicitH +{ + ~ExplicitH(); + + NoThrower t; +}; + +ExplicitH::~ExplicitH() = default; + +#define SA(X) static_assert(X, #X) + +SA( !noexcept(ExplicitA()) ); +SA( !noexcept(ExplicitB()) ); +SA( !noexcept(ExplicitC()) ); +SA( !noexcept(ExplicitD()) ); +SA( noexcept(ExplicitE()) ); +SA( noexcept(ExplicitF()) ); +SA( noexcept(ExplicitG()) ); +SA( noexcept(ExplicitH()) ); diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/pr57981.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/pr57981.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/pr57981.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/pr57981.C 2013-08-20 07:14:43.110616000 -0500 @@ -0,0 +1,17 @@ +// { dg-options "-std=c++11 -Wall -Wextra" } + +template +void f(T t, void* = 0) // { dg-warning "unused parameter" } +{ +} + +template +auto g(T t) -> decltype(f(t)) +{ + f(t); +} + +int main() +{ + g(0); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/ref-qual14.C gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/ref-qual14.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/cpp0x/ref-qual14.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/cpp0x/ref-qual14.C 2013-08-06 20:18:57.648578000 -0500 @@ -0,0 +1,18 @@ +// PR c++/57825 +// { dg-do compile { target c++11 } } + +template +struct target_class +{}; + +template +struct target_class +{}; + +template +struct target_class +{}; + +template +struct target_class +{}; diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/debug/template2.C gcc-4.8.1/gcc/testsuite/g++.dg/debug/template2.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/debug/template2.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/debug/template2.C 2013-07-09 12:52:01.982983000 -0500 @@ -0,0 +1,14 @@ +// PR c++/57545 + +template +struct array { + T data[N]; +}; + +template +struct derived { + typedef long unsigned int size_type; + static const size_type n = 42; + + array a; +}; diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/expr/const1.C gcc-4.8.1/gcc/testsuite/g++.dg/expr/const1.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/expr/const1.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/expr/const1.C 2013-07-09 12:51:47.995955000 -0500 @@ -0,0 +1,9 @@ +// PR c++/57551 + +extern unsigned long ADDR; + +unsigned long f(){ + const unsigned long* const var=&ADDR; + const unsigned long retval=var[1]; + return retval; +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/ext/pr57362.C gcc-4.8.1/gcc/testsuite/g++.dg/ext/pr57362.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/ext/pr57362.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/ext/pr57362.C 2013-07-31 15:11:51.667843000 -0500 @@ -0,0 +1,199 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-require-ifunc "" } */ + +__attribute__((target("default"))) +int foo(void) { return 1; } +__attribute__((target("128bit-long-double"))) +int foo(void) { return 1; } +__attribute__((target("80387"))) +int foo(void) { return 1; } +__attribute__((target("96bit-long-double"))) +int foo(void) { return 1; } +__attribute__((target("long-double-80"))) +int foo(void) { return 1; } +__attribute__((target("long-double-64"))) +int foo(void) { return 1; } +__attribute__((target("accumulate-outgoing-args"))) +int foo(void) { return 1; } +__attribute__((target("align-double"))) +int foo(void) { return 1; } +__attribute__((target("align-stringops"))) +int foo(void) { return 1; } +__attribute__((target("fancy-math-387"))) +int foo(void) { return 1; } +__attribute__((target("force-drap"))) +int foo(void) { return 1; } +__attribute__((target("fp-ret-in-387"))) +int foo(void) { return 1; } +__attribute__((target("hard-float"))) +int foo(void) { return 1; } +__attribute__((target("ieee-fp"))) +int foo(void) { return 1; } +__attribute__((target("inline-all-stringops"))) +int foo(void) { return 1; } +__attribute__((target("inline-stringops-dynamically"))) +int foo(void) { return 1; } +__attribute__((target("intel-syntax"))) +int foo(void) { return 1; } +__attribute__((target("ms-bitfields"))) +int foo(void) { return 1; } +__attribute__((target("no-align-stringops"))) +int foo(void) { return 1; } +__attribute__((target("no-fancy-math-387"))) +int foo(void) { return 1; } +__attribute__((target("no-push-args"))) +int foo(void) { return 1; } +__attribute__((target("no-red-zone"))) +int foo(void) { return 1; } +__attribute__((target("omit-leaf-frame-pointer"))) +int foo(void) { return 1; } +__attribute__((target("pc32"))) +int foo(void) { return 1; } +__attribute__((target("pc64"))) +int foo(void) { return 1; } +__attribute__((target("pc80"))) +int foo(void) { return 1; } +__attribute__((target("push-args"))) +int foo(void) { return 1; } +__attribute__((target("red-zone"))) +int foo(void) { return 1; } +__attribute__((target("rtd"))) +int foo(void) { return 1; } +__attribute__((target("soft-float"))) +int foo(void) { return 1; } +__attribute__((target("sseregparm"))) +int foo(void) { return 1; } +__attribute__((target("stackrealign"))) +int foo(void) { return 1; } +__attribute__((target("stack-arg-probe"))) +int foo(void) { return 1; } +__attribute__((target("tls-direct-seg-refs"))) +int foo(void) { return 1; } +__attribute__((target("vect8-ret-in-mem"))) +int foo(void) { return 1; } +__attribute__((target("recip"))) +int foo(void) { return 1; } +__attribute__((target("cld"))) +int foo(void) { return 1; } +__attribute__((target("vzeroupper"))) +int foo(void) { return 1; } +__attribute__((target("dispatch-scheduler"))) +int foo(void) { return 1; } +__attribute__((target("prefer-avx128"))) +int foo(void) { return 1; } +__attribute__((target("32"))) +int foo(void) { return 1; } +__attribute__((target("64"))) +int foo(void) { return 1; } +__attribute__((target("x32"))) +int foo(void) { return 1; } +__attribute__((target("mmx"))) +int foo(void) { return 1; } +__attribute__((target("3dnow"))) +int foo(void) { return 1; } +__attribute__((target("3dnowa"))) +int foo(void) { return 1; } +__attribute__((target("sse"))) +int foo(void) { return 1; } +__attribute__((target("sse2"))) +int foo(void) { return 1; } +__attribute__((target("sse3"))) +int foo(void) { return 1; } +__attribute__((target("ssse3"))) +int foo(void) { return 1; } +__attribute__((target("sse4.1"))) +int foo(void) { return 1; } +__attribute__((target("sse4.2"))) +int foo(void) { return 1; } +__attribute__((target("sse4"))) +int foo(void) { return 1; } +__attribute__((target("no-sse4"))) +int foo(void) { return 1; } +__attribute__((target("sse5"))) +int foo(void) { return 1; } +__attribute__((target("avx"))) +int foo(void) { return 1; } +__attribute__((target("avx2"))) +int foo(void) { return 1; } +__attribute__((target("fma"))) +int foo(void) { return 1; } +__attribute__((target("sse4a"))) +int foo(void) { return 1; } +__attribute__((target("fma4"))) +int foo(void) { return 1; } +__attribute__((target("xop"))) +int foo(void) { return 1; } +__attribute__((target("lwp"))) +int foo(void) { return 1; } +__attribute__((target("abm"))) +int foo(void) { return 1; } +__attribute__((target("popcnt"))) +int foo(void) { return 1; } +__attribute__((target("bmi"))) +int foo(void) { return 1; } +__attribute__((target("bmi2"))) +int foo(void) { return 1; } +__attribute__((target("lzcnt"))) +int foo(void) { return 1; } +__attribute__((target("hle"))) +int foo(void) { return 1; } +__attribute__((target("rdseed"))) +int foo(void) { return 1; } +__attribute__((target("prfchw"))) +int foo(void) { return 1; } +__attribute__((target("adx"))) +int foo(void) { return 1; } +__attribute__((target("fxsr"))) +int foo(void) { return 1; } +__attribute__((target("xsave"))) +int foo(void) { return 1; } +__attribute__((target("xsaveopt"))) +int foo(void) { return 1; } +__attribute__((target("tbm"))) +int foo(void) { return 1; } +__attribute__((target("cx16"))) +int foo(void) { return 1; } +__attribute__((target("sahf"))) +int foo(void) { return 1; } +__attribute__((target("movbe"))) +int foo(void) { return 1; } +__attribute__((target("crc32"))) +int foo(void) { return 1; } +__attribute__((target("aes"))) +int foo(void) { return 1; } +__attribute__((target("pclmul"))) +int foo(void) { return 1; } +__attribute__((target("sse2avx"))) +int foo(void) { return 1; } +__attribute__((target("fsgsbase"))) +int foo(void) { return 1; } +__attribute__((target("rdrnd"))) +int foo(void) { return 1; } +__attribute__((target("f16c"))) +int foo(void) { return 1; } +__attribute__((target("fentry"))) +int foo(void) { return 1; } +__attribute__((target("8bit-idiv"))) +int foo(void) { return 1; } +__attribute__((target("avx256-split-unaligned-load"))) +int foo(void) { return 1; } +__attribute__((target("avx256-split-unaligned-store"))) +int foo(void) { return 1; } +__attribute__((target("rtm"))) +int foo(void) { return 1; } +//--------------- + +#include + int main (void) + { + int result; + result = foo(); + printf("Result is %d\n", result); + return result; + } + +/* { dg-prune-output "attribute.* is unknown" } */ +/* { dg-prune-output "redefinition of int foo" } */ +/* { dg-prune-output "previous declaration of int foo" } */ +/* { dg-prune-output "int foo.* previously defined here" } */ +/* { dg-prune-output "No dispatcher found for" } */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/opt/pr58006.C gcc-4.8.1/gcc/testsuite/g++.dg/opt/pr58006.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/opt/pr58006.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/opt/pr58006.C 2013-08-18 10:24:12.566692000 -0500 @@ -0,0 +1,22 @@ +// PR tree-optimization/58006 +// { dg-do compile } +// { dg-require-effective-target pthread } +// { dg-options "-Ofast -ftree-parallelize-loops=2" } + +extern "C" float sqrtf (float); + +struct S +{ + float i, j; + float foo () const { return sqrtf (i * i + j * j); } + S () : i (1), j (1) {} +}; + +void +bar (int a, int b) +{ + int i; + float f; + for (i = a; i < b; i++) + f = S ().foo (); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/opt/pr58165.C gcc-4.8.1/gcc/testsuite/g++.dg/opt/pr58165.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/opt/pr58165.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/opt/pr58165.C 2013-08-16 04:04:52.452768000 -0500 @@ -0,0 +1,14 @@ +// PR tree-optimization/58165 +// { dg-do compile } +// { dg-options "-O2" } + +extern "C" float sqrtf (float); + +struct A { A (); ~A (); }; + +void +foo (double d) +{ + A a; + sqrtf (d); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/parse/ref-qual2.C gcc-4.8.1/gcc/testsuite/g++.dg/parse/ref-qual2.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/parse/ref-qual2.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/parse/ref-qual2.C 2013-07-09 12:52:17.034866000 -0500 @@ -0,0 +1,6 @@ +// PR c++/57532 + +int main() +{ + return (int() & int()); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/pr57878.C gcc-4.8.1/gcc/testsuite/g++.dg/pr57878.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/pr57878.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/pr57878.C 2013-08-20 06:56:29.733502000 -0500 @@ -0,0 +1,226 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-m32 -O2 -fno-omit-frame-pointer -fPIC -std=gnu++11" } */ + +typedef int int32; +typedef long long int64; +typedef unsigned int uint32; +typedef unsigned long long uint64; +namespace std { + typedef __SIZE_TYPE__ size_t; + template + struct char_traits; + template + inline _Tp* __addressof(_Tp& __r) noexcept { + return reinterpret_cast<_Tp*> (&const_cast(reinterpret_cast(__r))); + } + template + struct remove_reference { + typedef _Tp type; + }; + template + constexpr _Tp&& forward(typename std::remove_reference<_Tp>::type& __t) noexcept { + return static_cast<_Tp&&>(__t); + } +} +typedef __SIZE_TYPE__ size_t; +extern "C++" { + inline void* operator new(std::size_t, void* __p) noexcept { + return __p; + } +} +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) { + template + class new_allocator { + public: + typedef size_t size_type; + typedef _Tp* pointer; + }; +} +namespace std { + template + using __allocator_base = __gnu_cxx::new_allocator<_Tp>; + template + class allocator + : public __allocator_base<_Tp> { + public: + typedef size_t size_type; + template + struct rebind { + typedef allocator<_Tp1> other; + }; + }; +} +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) { + template + class __sso_string_base; + template, typename _Alloc = std::allocator<_CharT>, template class _Base = __sso_string_base> + class __versa_string; + template + struct __vstring_utility { + typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type; + template + struct _Alloc_hider + : public _Alloc1 { + _Alloc_hider(const _Alloc1& __a, _CharT* __ptr) + : _Alloc1(__a), _M_p(__ptr) { + } + _CharT* _M_p; + }; + }; + template + class __sso_string_base + : protected __vstring_utility<_CharT, _Traits, _Alloc> { + typedef __vstring_utility<_CharT, _Traits, _Alloc> _Util_Base; + typedef typename _Util_Base::_CharT_alloc_type _CharT_alloc_type; + typedef typename _CharT_alloc_type::size_type size_type; + private: + typename _Util_Base::template _Alloc_hider<_CharT_alloc_type> + _M_dataplus; + size_type _M_string_length; + enum { + _S_local_capacity = 15 }; + union { + _CharT _M_local_data[_S_local_capacity + 1]; + }; + template + void _M_construct(_InIterator __beg, _InIterator __end); + public: + size_type _M_max_size() const; + _CharT* _M_data() const { + return _M_dataplus._M_p; + } + size_type _M_length() const { + return _M_string_length; + } + __sso_string_base(const __sso_string_base& __rcs); + const _CharT_alloc_type& _M_get_allocator() const { + } + }; + template + __sso_string_base<_CharT, _Traits, _Alloc>:: __sso_string_base(const __sso_string_base& __rcs) + : _M_dataplus(__rcs._M_get_allocator(), _M_local_data) { + _M_construct(__rcs._M_data(), __rcs._M_data() + __rcs._M_length()); + } + template class _Base> + class __versa_string + : private _Base<_CharT, _Traits, _Alloc> { + }; +} +template, typename _Alloc = std::allocator<_CharT> > +class basic_string + : public __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc> { +}; +typedef basic_string string; +namespace std __attribute__ ((__visibility__ ("default"))) { + template + class __alloctr_rebind_helper { + public: + static const bool __value = true; + }; + template::__value> + struct __alloctr_rebind; + template struct __alloctr_rebind<_Alloc, _Tp, true> + { + typedef typename _Alloc::template rebind<_Tp>::other __type; + }; + template + struct allocator_traits { + private: + template + static typename _Tp::pointer _S_pointer_helper(_Tp*); + typedef decltype(_S_pointer_helper((_Alloc*)0)) __pointer; + public: + typedef __pointer pointer; + template + using rebind_alloc = typename __alloctr_rebind<_Alloc, _Tp>::__type; + }; +} +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) { + template struct __alloc_traits + : std::allocator_traits<_Alloc> + { + typedef std::allocator_traits<_Alloc> _Base_type; + template + struct rebind { + typedef typename _Base_type::template rebind_alloc<_Tp> + other; + }; + }; +} +namespace std __attribute__ ((__visibility__ ("default"))) { + template + inline void _Construct(_T1* __p, _Args&&... __args) { + ::new(static_cast(__p)) _T1(std::forward<_Args>(__args)...); + } + template + struct _Vector_base { + typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type; + typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer pointer; + struct _Vector_impl + : public _Tp_alloc_type { + pointer _M_start; + pointer _M_finish; + }; + public: + _Vector_impl _M_impl; + }; + template > + class vector + : protected _Vector_base<_Tp, _Alloc> { + typedef _Vector_base<_Tp, _Alloc> _Base; + public: + typedef _Tp value_type; + typedef typename _Base::pointer pointer; + typedef size_t size_type; + size_type size() const; + void push_back(const value_type& __x) { + _M_emplace_back_aux(__x); + } + template + void _M_emplace_back_aux(_Args&&... __args); + size_type _M_check_len(); + }; + template template + void vector<_Tp, _Alloc>:: _M_emplace_back_aux(_Args&&... __args) { + const size_type __len = _M_check_len(); + pointer __new_start(static_cast(::operator new(__len * sizeof(_Tp)))); + pointer __new_temp(__new_start + size()); + ::new((void *)__new_temp) _Tp(std::forward<_Args>(__args)...); + pointer __cur = __new_start; + pointer __first = this->_M_impl._M_start; + pointer __last = this->_M_impl._M_finish; + for (; + __first != __last; + ++__first, ++__cur) std::_Construct(std::__addressof(*__cur), *__first); + } +} +using std::vector; +class DL { +public: + struct ChunkId { + int64 disk_id; + uint64 handle; + uint64 version; + string capability; + ChunkId(); + }; + struct ChunkInfo { + ChunkId id; + uint64 mtime; + uint32 length; + int32 space_used; + }; +}; +class FDB { + void CollectChunk(const DL::ChunkInfo& chunk, const int& location); +private: + struct ChunkData { + int location; + DL::ChunkInfo chunk_info; + }; + vector chunk_data_; +}; +void FDB::CollectChunk(const DL::ChunkInfo& chunk, const int& location) { + ChunkData chunk_data; + chunk_data_.push_back( chunk_data); +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/template/abstract1.C gcc-4.8.1/gcc/testsuite/g++.dg/template/abstract1.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/template/abstract1.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/template/abstract1.C 2013-07-30 08:30:12.307006000 -0500 @@ -0,0 +1,12 @@ +// PR c++/58022 + +template struct A { }; +template A & operator<< (A&, T); +template class foo; +template A & operator<<(A& o, const foo& l); +template class foo { + friend A& operator<< (A& o, const foo& l); +}; +class bar; +foo fb; +class bar { virtual void baz()=0; }; diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/template/access27.C gcc-4.8.1/gcc/testsuite/g++.dg/template/access27.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/template/access27.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/template/access27.C 2013-07-08 22:26:58.213071000 -0500 @@ -0,0 +1,17 @@ +// PR c++/57550 + +template bool Wrapper(double); +template void MakeHandler(bool (T)); + +class Handler +{ +public: + template static void SetPrimitiveHandlers() + { + MakeHandler(Wrapper >); + } +private : + template static bool Append(T); +}; + +template void Handler::SetPrimitiveHandlers(); diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/template/arg9.C gcc-4.8.1/gcc/testsuite/g++.dg/template/arg9.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/template/arg9.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/template/arg9.C 2013-07-03 15:22:16.527771000 -0500 @@ -0,0 +1,8 @@ +// PR c++/57771 +// { dg-do compile } + +template +struct S {}; + +S (4>>2)> s1; +S (4>>2)> s2; diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/template/delete2.C gcc-4.8.1/gcc/testsuite/g++.dg/template/delete2.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/template/delete2.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/template/delete2.C 2013-08-20 07:59:37.559809000 -0500 @@ -0,0 +1,26 @@ +// PR c++/58119 + +template +struct A +{ + operator T*(); + template + operator A(); +}; + +template +struct B +{ + operator T*(); + template + operator A*(); +}; + +int main() +{ + A a; + delete a; + + B b; + delete b; // { dg-error "template|delete" } +} diff -Naur gcc-4.8.1.orig/gcc/testsuite/g++.dg/template/using23.C gcc-4.8.1/gcc/testsuite/g++.dg/template/using23.C --- gcc-4.8.1.orig/gcc/testsuite/g++.dg/template/using23.C 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/g++.dg/template/using23.C 2013-07-09 12:51:35.112170000 -0500 @@ -0,0 +1,15 @@ +// PR c++/57831 + +struct A { + void f(); +}; +template struct B : T { + typedef T base; + using base::f; // If I write "using B::f" it's ok + void g( ) { + B::f(); // This is OK as expected + (this->*&T::f)(); // This is also OK + (this->*&B::f)(); // This causes error + } +}; +template struct B< A >; diff -Naur gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/defined_assignment_6.f90 gcc-4.8.1/gcc/testsuite/gfortran.dg/defined_assignment_6.f90 --- gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/defined_assignment_6.f90 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gfortran.dg/defined_assignment_6.f90 2013-06-04 02:11:12.753416000 -0500 @@ -0,0 +1,36 @@ +! { dg-do compile } +! +! PR fortran/57364 +! +! Contributed by Damian Rouson +! +module ref_counter_implementation + type ref_counter + contains + procedure :: assign + generic :: assignment(=) => assign + end type +contains + subroutine assign (lhs, rhs) + class (ref_counter), intent(inout) :: lhs + class (ref_counter), intent(in) :: rhs + end subroutine +end module +module foo_parent_implementation + use ref_counter_implementation ,only: ref_counter + type :: foo_parent + type(ref_counter) :: counter + end type +contains + type(foo_parent) function new_foo_parent() + end function +end module +module foo_implementation + use foo_parent_implementation ,only: foo_parent,new_foo_parent + type, extends(foo_parent) :: foo + end type +contains + type(foo) function new_foo() + new_foo%foo_parent = new_foo_parent() + end function +end module diff -Naur gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/defined_assignment_7.f90 gcc-4.8.1/gcc/testsuite/gfortran.dg/defined_assignment_7.f90 --- gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/defined_assignment_7.f90 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gfortran.dg/defined_assignment_7.f90 2013-06-11 11:18:13.173979000 -0500 @@ -0,0 +1,29 @@ +! { dg-compile } +! +! PR fortran/57508 +! +module ForTrilinos_ref_counter + type ref_counter + contains + procedure :: assign + generic :: assignment(=) => assign + end type +contains + subroutine assign (lhs, rhs) + class (ref_counter), intent(inout) :: lhs + class (ref_counter), intent(in) :: rhs + end subroutine +end module +module FEpetra_BlockMap + use ForTrilinos_ref_counter, only : ref_counter + type :: Epetra_BlockMap + type(ref_counter) :: counter + end type +contains + function from_struct() result(new_Epetra_BlockMap) + type(Epetra_BlockMap) :: new_Epetra_BlockMap + end function + type(Epetra_BlockMap) function create_arbitrary() + create_arbitrary = from_struct() + end function +end module diff -Naur gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/dot_product_2.f90 gcc-4.8.1/gcc/testsuite/gfortran.dg/dot_product_2.f90 --- gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/dot_product_2.f90 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gfortran.dg/dot_product_2.f90 2013-07-08 14:10:32.194953000 -0500 @@ -0,0 +1,38 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! +! PR fortran/57785 +! +! Contributed by Kontantinos Anagnostopoulos +! +! The implicit complex conjugate was missing for DOT_PRODUCT + + +! For the following, the compile-time simplification fails for SUM; +! see PR fortran/56342. Hence, a manually expanded SUM is used. + +!if (DOT_PRODUCT ((/ (1.0, 2.0), (2.0, 3.0) /), (/ (1.0, 1.0), (1.0, 4.0) /)) & +! /= SUM (CONJG ((/ (1.0, 2.0), (2.0, 3.0) /))*(/ (1.0, 1.0), (1.0, 4.0) /))) & +! call abort () +! +!if (ANY (MATMUL ((/ (1.0, 2.0), (2.0, 3.0) /), & +! RESHAPE ((/ (1.0, 1.0), (1.0, 4.0) /),(/2, 1/))) /= & +! SUM ((/ (1.0, 2.0), (2.0, 3.0) /)*(/ (1.0, 1.0), (1.0, 4.0) /)))) & +! call abort () + + +if (DOT_PRODUCT ((/ (1.0, 2.0), (2.0, 3.0) /), (/ (1.0, 1.0), (1.0, 4.0) /)) & + /= CONJG (cmplx(1.0, 2.0)) * cmplx(1.0, 1.0) & + + CONJG (cmplx(2.0, 3.0)) * cmplx(1.0, 4.0)) & + call abort () + +if (ANY (MATMUL ((/ (1.0, 2.0), (2.0, 3.0) /), & + RESHAPE ((/ (1.0, 1.0), (1.0, 4.0) /),(/2, 1/))) & + /= cmplx(1.0, 2.0) * cmplx(1.0, 1.0) & + + cmplx(2.0, 3.0) * cmplx(1.0, 4.0))) & + call abort () +end + + +! { dg-final { scan-tree-dump-not "abort" "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff -Naur gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/inline_sum_5.f90 gcc-4.8.1/gcc/testsuite/gfortran.dg/inline_sum_5.f90 --- gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/inline_sum_5.f90 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gfortran.dg/inline_sum_5.f90 2013-08-24 07:46:17.832897000 -0500 @@ -0,0 +1,33 @@ +! { dg-do run } +! +! PR fortran/57798 +! The call to sum used to be inlined into a loop with an uninitialized bound +! +! Original testcase by Stephan Kramer + +program test + implicit none + + call sub(2, 11) + + contains + + function func(m, n) + integer, intent(in):: m,n + real, dimension(m, n):: func + + func = 1.0 + + end function func + + subroutine sub(m, n) + integer, intent(in):: m, n + real, dimension(m,n):: y + + y = 1.0 + if (any(sum(y*func(m,n), dim=1) /= m)) call abort + + end subroutine sub + +end program test + diff -Naur gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/select_type_34.f90 gcc-4.8.1/gcc/testsuite/gfortran.dg/select_type_34.f90 --- gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/select_type_34.f90 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gfortran.dg/select_type_34.f90 2013-08-24 04:12:21.843607000 -0500 @@ -0,0 +1,10 @@ +! { dg-do compile } +! +! PR 58185: [4.8/4.9 Regression] [OOP] ICE when selector in SELECT TYPE is non-polymorphic +! +! Contributed by John + + integer :: array + select type (a => array) ! { dg-error "Selector shall be polymorphic" } + end select +end diff -Naur gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f90 gcc-4.8.1/gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f90 --- gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f90 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f90 2013-08-11 06:31:41.480740000 -0500 @@ -0,0 +1,20 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! +! PR 58058: [4.7/4.8/4.9 Regression] Memory leak with transfer function +! +! Contributed by Thomas Jourdan + + implicit none + + integer, dimension(3) :: t1 + character(len=64) :: str + + t1 = (/1,2,3/) + + str = transfer(t1,str) + +end + +! { dg-final { scan-tree-dump-times "__builtin_free" 1 "original" } } +! { dg-final { cleanup-tree-dump "original" } } diff -Naur gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/typebound_override_4.f90 gcc-4.8.1/gcc/testsuite/gfortran.dg/typebound_override_4.f90 --- gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/typebound_override_4.f90 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gfortran.dg/typebound_override_4.f90 2013-05-31 13:10:03.669091000 -0500 @@ -0,0 +1,34 @@ +! { dg-do compile } +! +! PR 57217: [4.7/4.8/4.9 Regression][OOP] Accepts invalid TBP overriding - lacking arguments check +! +! Contributed by Salvatore Filippone + +module base_mod + implicit none + type base_type + contains + procedure, pass(map) :: clone => base_clone + end type +contains + subroutine base_clone(map,mapout) + class(base_type) :: map + class(base_type) :: mapout + end subroutine +end module + +module r_mod + use base_mod + implicit none + type, extends(base_type) :: r_type + contains + procedure, pass(map) :: clone => r_clone ! { dg-error "Type/rank mismatch in argument" } + end type +contains + subroutine r_clone(map,mapout) + class(r_type) :: map + class(r_type) :: mapout + end subroutine +end module + +! { dg-final { cleanup-modules "base_mod r_mod" } } diff -Naur gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/use_29.f90 gcc-4.8.1/gcc/testsuite/gfortran.dg/use_29.f90 --- gcc-4.8.1.orig/gcc/testsuite/gfortran.dg/use_29.f90 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gfortran.dg/use_29.f90 2013-07-28 09:13:17.566941000 -0500 @@ -0,0 +1,15 @@ +! { dg-do compile } +! +! PR fortran/57435 +! +! Contributed by Lorenz Hüdepohl +! +module precision +end module precision + contains + use precision ! { dg-error "Unexpected USE statement in CONTAINS section" } +module stressten_rt ! { dg-error "Unexpected MODULE statement in CONTAINS section" } + use precision ! { dg-error "Unexpected USE statement in CONTAINS section" } + implicit none ! { dg-error "Unexpected IMPLICIT NONE statement in CONTAINS section" } + +! { dg-error "Unexpected end of file" "" { target "*-*-*" } 0 } diff -Naur gcc-4.8.1.orig/gcc/testsuite/gnat.dg/loop_optimization16.adb gcc-4.8.1/gcc/testsuite/gnat.dg/loop_optimization16.adb --- gcc-4.8.1.orig/gcc/testsuite/gnat.dg/loop_optimization16.adb 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gnat.dg/loop_optimization16.adb 2013-08-13 10:59:03.399464000 -0500 @@ -0,0 +1,24 @@ +-- { dg-do run } + +with Loop_Optimization16_Pkg; use Loop_Optimization16_Pkg; + +procedure Loop_Optimization16 is + + Counter : Natural := 0; + + C : constant Natural := F; + + subtype Index_T is Index_Base range 1 .. Index_Base (C); + +begin + + for I in Index_T'First .. Index_T'Last loop + Counter := Counter + 1; + exit when Counter > 200; + end loop; + + if Counter > 200 then + raise Program_Error; + end if; + +end Loop_Optimization16; diff -Naur gcc-4.8.1.orig/gcc/testsuite/gnat.dg/loop_optimization16_pkg.adb gcc-4.8.1/gcc/testsuite/gnat.dg/loop_optimization16_pkg.adb --- gcc-4.8.1.orig/gcc/testsuite/gnat.dg/loop_optimization16_pkg.adb 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gnat.dg/loop_optimization16_pkg.adb 2013-08-13 10:59:03.399464000 -0500 @@ -0,0 +1,8 @@ +package body Loop_Optimization16_Pkg is + + function F return Natural is + begin + return Natural (Index_Base'Last); + end; + +end Loop_Optimization16_Pkg; diff -Naur gcc-4.8.1.orig/gcc/testsuite/gnat.dg/loop_optimization16_pkg.ads gcc-4.8.1/gcc/testsuite/gnat.dg/loop_optimization16_pkg.ads --- gcc-4.8.1.orig/gcc/testsuite/gnat.dg/loop_optimization16_pkg.ads 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/gnat.dg/loop_optimization16_pkg.ads 2013-08-13 10:59:03.399464000 -0500 @@ -0,0 +1,7 @@ +package Loop_Optimization16_Pkg is + + type Index_Base is range 0 .. 127; + + function F return Natural; + +end Loop_Optimization16_Pkg; diff -Naur gcc-4.8.1.orig/gcc/testsuite/go.test/test/64bit.go gcc-4.8.1/gcc/testsuite/go.test/test/64bit.go --- gcc-4.8.1.orig/gcc/testsuite/go.test/test/64bit.go 2012-09-29 13:16:01.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/go.test/test/64bit.go 2013-06-26 17:42:47.881515000 -0500 @@ -594,6 +594,19 @@ "}\n" + "\n" +const binaryConstR0 = "func test%vBinaryR%v(a, add, sub, mul, div, mod, and, or, xor, andnot %v, dodiv bool) {\n" + + " const b %v = %v;\n" + + " const typ = `%s`;\n" + + " if n, op, want := a + b, `+`, add; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" + + " if n, op, want := a - b, `-`, sub; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" + + " if n, op, want := a * b, `*`, mul; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" + + " if n, op, want := a & b, `&`, and; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" + + " if n, op, want := a | b, `|`, or; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" + + " if n, op, want := a ^ b, `^`, xor; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" + + " if n, op, want := a &^ b, `&^`, andnot; n != want { ok=false; println(typ, `var`, a, op, `const`, b, `=`, n, `should be`, want); }\n" + + "}\n" + + "\n" + const shiftConstL = "func test%vShiftL%v(b uint64, left, right %v) {\n" + " const a %v = %v;\n" + " const typ = `%s`;\n" + @@ -621,12 +634,20 @@ func constTests() { for i, a := range int64Values { fmt.Fprintf(bout, binaryConstL, "Int64", i, "int64", "int64", a, "int64") - fmt.Fprintf(bout, binaryConstR, "Int64", i, "int64", "int64", a, "int64") + if a.hi == 0 && a.lo == 0 { + fmt.Fprintf(bout, binaryConstR0, "Int64", i, "int64", "int64", a, "int64") + } else { + fmt.Fprintf(bout, binaryConstR, "Int64", i, "int64", "int64", a, "int64") + } fmt.Fprintf(bout, shiftConstL, "Int64", i, "int64", "int64", a, "int64") } for i, a := range uint64Values { fmt.Fprintf(bout, binaryConstL, "Uint64", i, "uint64", "uint64", a, "uint64") - fmt.Fprintf(bout, binaryConstR, "Uint64", i, "uint64", "uint64", a, "uint64") + if a.hi == 0 && a.lo == 0 { + fmt.Fprintf(bout, binaryConstR0, "Uint64", i, "uint64", "uint64", a, "uint64") + } else { + fmt.Fprintf(bout, binaryConstR, "Uint64", i, "uint64", "uint64", a, "uint64") + } fmt.Fprintf(bout, shiftConstL, "Uint64", i, "uint64", "uint64", a, "uint64") } for i, a := range shiftValues { diff -Naur gcc-4.8.1.orig/gcc/testsuite/go.test/test/fixedbugs/bug086.go gcc-4.8.1/gcc/testsuite/go.test/test/fixedbugs/bug086.go --- gcc-4.8.1.orig/gcc/testsuite/go.test/test/fixedbugs/bug086.go 2012-09-29 13:16:01.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/go.test/test/fixedbugs/bug086.go 2013-08-07 14:00:55.550656000 -0500 @@ -6,12 +6,12 @@ package main -func f() int { // ERROR "return|control" +func f() int { if false { return 0; } // we should not be able to return successfully w/o a return statement -} +} // ERROR "return" func main() { print(f(), "\n"); diff -Naur gcc-4.8.1.orig/gcc/testsuite/go.test/test/fixedbugs/bug410.go gcc-4.8.1/gcc/testsuite/go.test/test/fixedbugs/bug410.go --- gcc-4.8.1.orig/gcc/testsuite/go.test/test/fixedbugs/bug410.go 2012-09-29 13:16:01.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/go.test/test/fixedbugs/bug410.go 2013-06-26 17:42:47.881515000 -0500 @@ -18,7 +18,7 @@ for s := range arr { x := make([]byte, 10) for i := 0; i < 100 ; i++ { - x[i] ^= k[i-arr[s].num%0] + x[i] ^= k[i-arr[s].num%3] } } } diff -Naur gcc-4.8.1.orig/gcc/testsuite/go.test/test/shift1.go gcc-4.8.1/gcc/testsuite/go.test/test/shift1.go --- gcc-4.8.1.orig/gcc/testsuite/go.test/test/shift1.go 2012-09-29 13:16:01.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/go.test/test/shift1.go 2013-06-25 11:53:38.994410000 -0500 @@ -23,7 +23,7 @@ // non-constant shift expressions var ( - e1 = g(2.0 << s) // ERROR "invalid" "as type interface" + e1 = g(2.0 << s) // ERROR "invalid|shift of non-integer operand" "as type interface" f1 = h(2 << s) // ERROR "invalid" "as type float64" g1 int64 = 1.1 << s // ERROR "truncated" ) @@ -36,3 +36,206 @@ b2 = 1.0 << c // ERROR "overflow" d2 = f(1.0 << c) // ERROR "overflow" ) + +var ( + // issues 4882, 4936. + a3 = 1.0< #include +#include + +//extern "C" { int printf(const char *,...); } #define CHECK_IF(expr) if(!(expr)) abort() #ifndef CLS_HAS_CXX_STRUCTORS @@ -19,7 +22,7 @@ cxx_struct (void) { a = b = 55; } }; -@interface Foo { +@interface Foo: NSObject { int c; cxx_struct s; } @@ -42,9 +45,11 @@ Class cls; cls = objc_getClass("Foo"); - CHECK_IF(cls->info & CLS_HAS_CXX_STRUCTORS); +// printf((const char *)"Foo info %lx\n",cls->info); + CHECK_IF((cls->info & CLS_HAS_CXX_STRUCTORS) != 0); cls = objc_getClass("Bar"); - CHECK_IF(!(cls->info & CLS_HAS_CXX_STRUCTORS)); +// printf((const char *)"Bar info %lx\n",cls->info); + CHECK_IF((cls->info & CLS_HAS_CXX_STRUCTORS) == 0); #else /* No test needed or available. */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/method-12.mm gcc-4.8.1/gcc/testsuite/obj-c++.dg/method-12.mm --- gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/method-12.mm 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/obj-c++.dg/method-12.mm 2013-07-16 08:24:02.909501000 -0500 @@ -2,6 +2,7 @@ /* Author: Ziemowit Laski */ /* { dg-options "-Wstrict-selector-match" } */ /* { dg-do compile } */ +/* { dg-skip-if "Object interface removed" { *-*-darwin[1-2]* && { lp64 } } { "-fnext-runtime" } { "" } } */ #include @@ -19,13 +20,13 @@ Class receiver; [receiver port]; /* { dg-warning "multiple methods named .\\+port. found" } */ - /* { dg-message "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 9 } */ - /* { dg-message "also found .\\+\\(Protocol \\*\\)port." "" { target *-*-* } 14 } */ + /* { dg-message "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 10 } */ + /* { dg-message "also found .\\+\\(Protocol \\*\\)port." "" { target *-*-* } 15 } */ [receiver starboard]; /* { dg-warning "no .\\+starboard. method found" } */ - /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 25 } */ - /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 25 } */ - /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 25 } */ + /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 26 } */ + /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 26 } */ + /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 26 } */ [Class port]; /* { dg-error ".Class. is not an Objective\\-C class name or alias" } */ } diff -Naur gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/proto-lossage-7.mm gcc-4.8.1/gcc/testsuite/obj-c++.dg/proto-lossage-7.mm --- gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/proto-lossage-7.mm 2010-09-14 19:08:59.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/obj-c++.dg/proto-lossage-7.mm 2013-07-16 08:24:02.909501000 -0500 @@ -1,12 +1,19 @@ /* Check that typedefs of ObjC classes preserve any @protocol qualifiers. */ /* { dg-do compile } */ + +#ifdef __NEXT_RUNTIME__ +#include +#define OBJECT NSObject +#else #include +#define OBJECT Object +#endif @protocol CanDoStuff; -typedef Object CanDoStuffType; -typedef Object *CanDoStuffTypePtr; +typedef OBJECT CanDoStuffType; +typedef OBJECT *CanDoStuffTypePtr; @protocol CanDoStuff - (int) dostuff; diff -Naur gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/strings/const-cfstring-5.mm gcc-4.8.1/gcc/testsuite/obj-c++.dg/strings/const-cfstring-5.mm --- gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/strings/const-cfstring-5.mm 2010-10-22 05:30:29.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/obj-c++.dg/strings/const-cfstring-5.mm 2013-07-16 08:24:02.909501000 -0500 @@ -6,16 +6,16 @@ /* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-options "-mconstant-cfstrings" } */ -#include +#include -@interface Foo: Object { +@interface Foo: NSObject { char *cString; unsigned int len; } + (Foo *)description; @end -@interface Bar: Object +@interface Bar: NSObject + (Foo *) getString: (int) which; @end diff -Naur gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/strings/const-str-12.mm gcc-4.8.1/gcc/testsuite/obj-c++.dg/strings/const-str-12.mm --- gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/strings/const-str-12.mm 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/obj-c++.dg/strings/const-str-12.mm 2013-07-16 08:24:02.909501000 -0500 @@ -5,17 +5,23 @@ /* { dg-options "-fconstant-string-class=Foo" } */ /* { dg-options "-mno-constant-cfstrings -fconstant-string-class=Foo" { target *-*-darwin* } } */ +#ifdef __NEXT_RUNTIME__ +#include +#define OBJECT NSObject +#else #include +#define OBJECT Object +#endif #include "../../objc-obj-c++-shared/objc-test-suite-types.h" -@interface Foo: Object { +@interface Foo: OBJECT { char *cString; unsigned int len; } + (id)description; @end -@interface Bar: Object +@interface Bar: OBJECT + (Foo *) getString: (int) which; @end diff -Naur gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/syntax-error-1.mm gcc-4.8.1/gcc/testsuite/obj-c++.dg/syntax-error-1.mm --- gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/syntax-error-1.mm 2010-10-05 14:23:33.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/obj-c++.dg/syntax-error-1.mm 2013-07-16 08:24:02.909501000 -0500 @@ -1,7 +1,13 @@ /* Graceful handling of a syntax error. */ /* { dg-do compile } */ +#ifdef __NEXT_RUNTIME__ +#include +#define OBJECT NSObject +#else #include +#define OBJECT Object +#endif class foo { public: @@ -12,7 +18,7 @@ extern void NXLog(const char *, ...); -@interface Test2 : Object { +@interface Test2 : OBJECT { } - (void) foo2; @end @@ -23,4 +29,4 @@ } /* { dg-error "stray .\}. between Objective\\-C\\+\\+ methods" } */ @end -/* { dg-error "expected constructor, destructor, or type conversion before" "" { target *-*-* } 22 } */ +/* { dg-error "expected constructor, destructor, or type conversion before" "" { target *-*-* } 28 } */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/torture/strings/const-str-10.mm gcc-4.8.1/gcc/testsuite/obj-c++.dg/torture/strings/const-str-10.mm --- gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/torture/strings/const-str-10.mm 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/obj-c++.dg/torture/strings/const-str-10.mm 2013-07-16 08:24:02.909501000 -0500 @@ -6,10 +6,10 @@ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */ -#include +#include #include "../../../objc-obj-c++-shared/runtime.h" /* For NEXT_OBJC_USE_NEW_INTERFACE. */ -@interface NSString: Object +@interface NSString: NSObject @end @interface NSSimpleCString : NSString { diff -Naur gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/torture/strings/const-str-11.mm gcc-4.8.1/gcc/testsuite/obj-c++.dg/torture/strings/const-str-11.mm --- gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/torture/strings/const-str-11.mm 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/obj-c++.dg/torture/strings/const-str-11.mm 2013-07-16 08:24:02.909501000 -0500 @@ -7,10 +7,10 @@ /* { dg-options "-fconstant-string-class=XStr" } */ /* { dg-options "-mno-constant-cfstrings -fconstant-string-class=XStr" { target *-*-darwin* } } */ -#include +#include #include "../../../objc-obj-c++-shared/runtime.h" /* For NEXT_OBJC_USE_NEW_INTERFACE. */ -@interface XString: Object { +@interface XString: NSObject { @protected char *bytes; } diff -Naur gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/torture/strings/const-str-9.mm gcc-4.8.1/gcc/testsuite/obj-c++.dg/torture/strings/const-str-9.mm --- gcc-4.8.1.orig/gcc/testsuite/obj-c++.dg/torture/strings/const-str-9.mm 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/obj-c++.dg/torture/strings/const-str-9.mm 2013-07-16 08:24:02.909501000 -0500 @@ -5,10 +5,10 @@ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */ -#include +#include #include "../../../objc-obj-c++-shared/runtime.h" /* For NEXT_OBJC_USE_NEW_INTERFACE. */ -@interface NSConstantString: Object { +@interface NSConstantString: NSObject { char *cString; unsigned int len; } diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/encode-7-next-64bit.m gcc-4.8.1/gcc/testsuite/objc.dg/encode-7-next-64bit.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/encode-7-next-64bit.m 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/encode-7-next-64bit.m 2013-07-16 08:24:02.909501000 -0500 @@ -4,24 +4,25 @@ /* { dg-require-effective-target lp64 } */ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ +/* { dg-additional-options "-framework Foundation" } */ #include #include #include -#include +#include #include "../objc-obj-c++-shared/runtime.h" -#define CHECK_IF(E) if (!(E)) abort () +extern int printf(char *,...); +void CHECK_IF(const char *s1, const char *s2) +{ + if (strcmp(s1,s2) != 0) { + printf ("'%s'\n'%s'\n",s1,s2); + abort (); + } +} @class NSDictionary, NSFont, NSError, _NSATSTypesetterGuts, NSString, NSMenu, NSArray; -typedef unsigned char UInt8; -typedef const signed long OSStatus; -typedef unsigned long CFIndex; -typedef unsigned int UInt32; -typedef UInt32 FourCharCode; -typedef FourCharCode OSType; - struct FSRef { UInt8 hidden[80]; }; @@ -99,10 +100,10 @@ unsigned int parameterMask; } NSErrorUserInfoFormatter; -typedef Object MyObj; -typedef Object *MyPtr; +typedef NSObject MyObj; +typedef NSObject *MyPtr; -@interface Foo: Object { +@interface Foo: NSObject { NSATSGlyphStorageRun r; } - (NSError *)_errorWithOSStatus:(OSStatus)inOSStatus ref1:(const FSRef *)inRef1 ref2:(const struct FSRef *)inRef2 @@ -114,7 +115,7 @@ - (id)str1:(const char *)str1 str2:(char *)str2 str3:(char *const)str3 str4:(const char *const)str4; - (oneway void)foo1:(Foo *)foo1 foo2:(const Foo *)foo2 foo3:(Foo *const)foo3 foo4:(const Foo *const)foo4; - (in const char *)sel1:(const SEL)sel1 id1:(const id)id1; -- (inout id)obj1:(const MyPtr)obj1 obj2:(Object *const)obj2 obj3:(MyObj *const)obj3; +- (inout id)obj1:(const MyPtr)obj1 obj2:(NSObject *const)obj2 obj3:(MyObj *const)obj3; + (ComponentInstance)_defaultScriptingComponent; - (NSString *)_formatCocoaErrorString:(NSString *)formatString parameters:(const char *)parameters applicableFormatters:(NSErrorUserInfoFormatter **)formatters count:(int)numFormatters; @@ -156,7 +157,7 @@ - (in const char *)sel1:(const SEL)sel1 id1:(const id)id1 { return "Hello"; } -- (inout id)obj1:(const MyPtr)obj1 obj2:(Object *const)obj2 obj3:(MyObj *const)obj3 { +- (inout id)obj1:(const MyPtr)obj1 obj2:(NSObject *const)obj2 obj3:(MyObj *const)obj3 { return self; } + (ComponentInstance)_defaultScriptingComponent { @@ -191,6 +192,8 @@ } @end +/* FIXME: we produce different output c.f. the system compiler on OSX10.6+ */ + int main(void) { Class fooClass = objc_getClass ("Foo"); Method meth; @@ -199,72 +202,76 @@ Ivar ivar; meth = class_getInstanceMethod (fooClass, @selector(_errorWithOSStatus:ref1:ref2:reading:)); - CHECK_IF (!strcmp (method_getTypeEncoding(meth), "@44@0:8q16r^{FSRef=[80C]}24r^{FSRef=[80C]}32c40")); + CHECK_IF (method_getTypeEncoding(meth), "@40@0:8i16r^{FSRef=[80C]}20r^{FSRef=[80C]}28c36"); meth = class_getInstanceMethod (fooClass, @selector(_attributeRunForCharacterAtIndex:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "r^{?=@@QQ^Qffff{_NSRect={_NSPoint=ff}{_NSSize=ff}}q^qQ^Q@@@:::****{?=b1b1b1b1b1b27}}24@0:8Q16")); + CHECK_IF (method_getTypeEncoding (meth), "r^{?=@@qq^qffff{_NSRect={_NSPoint=ff}{_NSSize=ff}}q^qQ^Q@@@:::****{?=b1b1b1b1b1b27}}24@0:8q16"); +/* clang produces: r^{?=@@qq^qffff{_NSRect={_NSPoint=ff}{_NSSize=ff}}q^qQ^Q@@@::^{objc_selector}****{?=b1b1b1b1b1b27}}24@0:8q16 */ meth = class_getInstanceMethod (fooClass, @selector(_getATSTypesetterGuts:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "r@24@0:8r:16")); + CHECK_IF (method_getTypeEncoding (meth), "r@24@0:8r:16"); +/* "@24@0:8r^{objc_selector=}16" */ meth = class_getInstanceMethod (fooClass, @selector(resumeWithSuspensionID:and:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "v32@0:8^{__NSAppleEventManagerSuspension=}16r^Q24")); + CHECK_IF (method_getTypeEncoding (meth), "v32@0:8^{__NSAppleEventManagerSuspension=}16r^q24"); meth = class_getInstanceMethod (fooClass, @selector(anotherMeth:and:and:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "r@40@0:8r:16r@24r@32")); + CHECK_IF (method_getTypeEncoding (meth), "r@40@0:8r:16r@24r@32"); meth = class_getInstanceMethod (fooClass, @selector(str1:str2:str3:str4:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "@48@0:8r*16*24*32r*40")); + CHECK_IF (method_getTypeEncoding (meth), "@48@0:8r*16*24*32r*40"); meth = class_getInstanceMethod (fooClass, @selector(foo1:foo2:foo3:foo4:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "Vv48@0:8@16r@24@32r@40")); + CHECK_IF (method_getTypeEncoding (meth), "Vv48@0:8@16r@24@32r@40"); meth = class_getInstanceMethod (fooClass, @selector(sel1:id1:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "rn*32@0:8r:16r@24")); + CHECK_IF (method_getTypeEncoding (meth), "rn*32@0:8r:16r@24"); meth = class_getInstanceMethod (fooClass, @selector(obj1:obj2:obj3:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "N@40@0:8r@16@24^{Object=#}32")); + CHECK_IF (method_getTypeEncoding (meth), "N@40@0:8r@16@24^{NSObject=#}32"); meth = class_getClassMethod (fooClass, @selector(_defaultScriptingComponent)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "^{ComponentInstanceRecord=[1q]}16@0:8")); + CHECK_IF (method_getTypeEncoding (meth), "^{ComponentInstanceRecord=[1q]}16@0:8"); meth = class_getInstanceMethod (fooClass, @selector(_formatCocoaErrorString:parameters:applicableFormatters:count:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "@44@0:8@16r*24^^{?}32i40")); + CHECK_IF (method_getTypeEncoding (meth), "@44@0:8@16r*24^^{?}32i40"); meth = class_getInstanceMethod (fooClass, @selector(formatter_func:run:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "^{?=^?@I}32@0:8@16r^^{?}24")); + CHECK_IF (method_getTypeEncoding (meth), "^{?=^?@I}32@0:8@16r^^{?}24"); meth = class_getInstanceMethod (fooClass, @selector(_forgetWord:inDictionary:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "c32@0:8nO@16nO@24")); + CHECK_IF (method_getTypeEncoding (meth), "c32@0:8nO@16nO@24"); meth = class_getInstanceMethod (fooClass, @selector(_registerServicesMenu:withSendTypes:andReturnTypes:addToList:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "v44@0:8@16r^*24r^*32c40")); + CHECK_IF (method_getTypeEncoding (meth), "v44@0:8@16r^*24r^*32c40"); meth = class_getClassMethod (fooClass, @selector(_proxySharePointer)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "^^{__CFSet}16@0:8")); + CHECK_IF (method_getTypeEncoding (meth), "^^{__CFSet}16@0:8"); meth = class_getInstanceMethod (fooClass, @selector(_checkGrammarInString:language:details:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "{_NSRange=II}40@0:8n@16nO@24oO^@32")); + CHECK_IF (method_getTypeEncoding (meth), "{_NSRange=II}40@0:8n@16nO@24oO^@32"); meth = class_getInstanceMethod (fooClass, @selector(_resolvePositionalStakeGlyphsForLineFragment:lineFragmentRect:minPosition:maxPosition:maxLineFragmentWidth:breakHint:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "B60@0:8^{__CTLine=}16{_NSRect={_NSPoint=ff}{_NSSize=ff}}24f40f44f48^Q52")); + CHECK_IF (method_getTypeEncoding (meth), "B60@0:8^{__CTLine=}16{_NSRect={_NSPoint=ff}{_NSSize=ff}}24f40f44f48^q52"); meth = class_getClassMethod (fooClass, @selector(findVoiceByIdentifier:returningCreator:returningID:)); - CHECK_IF (!strcmp (method_getTypeEncoding (meth), "c40@0:8@16^I24^I32")); + CHECK_IF (method_getTypeEncoding (meth), "c40@0:8@16^I24^I32"); ivars = class_copyIvarList (fooClass, &ivar_count); - CHECK_IF (ivar_count == 1); + if (ivar_count != 1) { + abort (); + } ivar = ivars[0]; - CHECK_IF (!strcmp (ivar_getName(ivar), "r")); - CHECK_IF (!strcmp (ivar_getTypeEncoding(ivar), + CHECK_IF (ivar_getName(ivar), "r"); + CHECK_IF (ivar_getTypeEncoding(ivar), "{?=\"_attributes\"@\"NSDictionary\"\"_font\"@\"NSFont\"\"_characterLength\"" - "Q\"_nominalGlyphLocation\"Q\"p\"^Q\"_defaultLineHeight\"f\"_defaultBaselineOffset\"" + "q\"_nominalGlyphLocation\"q\"p\"^q\"_defaultLineHeight\"f\"_defaultBaselineOffset\"" "f\"_horizExpansion\"f\"_baselineDelta\"f\"_attachmentBBox\"{_NSRect=\"origin\"" "{_NSPoint=\"x\"f\"y\"f}\"size\"{_NSSize=\"width\"f\"height\"f}}\"ll\"q\"llp\"^q\"ull\"" "Q\"ullp\"^Q\"a\"@\"a1\"@\"a2\"@\"b\":\"b1\":\"b2\":\"str1\"*\"str2\"*\"str3\"*\"str4\"" "*\"_rFlags\"{?=\"_isAttachmentRun\"b1\"_hasPositionalStake\"b1\"_isDefaultFace\"" - "b1\"_hasCombiningMarks\"b1\"_isScreenFont\"b1\"_reserved\"b27}}")); - + "b1\"_hasCombiningMarks\"b1\"_isScreenFont\"b1\"_reserved\"b27}}"); +/*"{?=\"_attributes\"@\"NSDictionary\"\"_font\"@\"NSFont\"\"_characterLength\"q\"_nominalGlyphLocation\"q\"p\"^q\"_defaultLineHeight\"f\"_defaultBaselineOffset\"f\"_horizExpansion\"f\"_baselineDelta\"f\"_attachmentBBox\"{_NSRect=\"origin\"{_NSPoint=\"x\"f\"y\"f}\"size\"{_NSSize=\"width\"f\"height\"f}}\"ll\"q\"llp\"^q\"ull\"Q\"ullp\"^Q\"a\"@\"a1\"@\"a2\"@\"b\":\"b1\":\"b2\"^{objc_selector}\"str1\"*\"str2\"*\"str3\"*\"str4\"*\"_rFlags\"{?=\"_isAttachmentRun\"b1\"_hasPositionalStake\"b1\"_isDefaultFace\"b1\"_hasCombiningMarks\"b1\"_isScreenFont\"b1\"_reserved\"b27}}"*/ return 0; } diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/image-info.m gcc-4.8.1/gcc/testsuite/objc.dg/image-info.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/image-info.m 2011-02-17 18:07:38.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/objc.dg/image-info.m 2013-07-16 08:24:02.909501000 -0500 @@ -7,20 +7,19 @@ /* { dg-skip-if "NeXT-only" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-options "-freplace-objc-classes" } */ -#include -#include +#include extern void abort(void); #define CHECK_IF(expr) if(!(expr)) abort(); -@interface Object (TEST_SUITE_C1) +@interface NSObject (TEST_SUITE_C1) - init; @end -@implementation Object (TEST_SUITE_C1) +@implementation NSObject (TEST_SUITE_C1) - init {return self;} @end -@interface Base: Object { +@interface Base: NSObject { @public int a; float b; diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/method-6.m gcc-4.8.1/gcc/testsuite/objc.dg/method-6.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/method-6.m 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/method-6.m 2013-07-16 08:24:02.909501000 -0500 @@ -4,14 +4,21 @@ /* { dg-do compile } */ /* { dg-options "-Wstrict-selector-match" } */ +#ifdef __NEXT_RUNTIME__ +#include +#define OBJECT NSObject +#else +#include #include +#define OBJECT Object +#endif @interface Base - (unsigned)port; @end @interface Derived: Base -- (Object *)port; +- (OBJECT *)port; + (Protocol *)port; - (id)starboard; @end @@ -20,13 +27,13 @@ Class receiver; [receiver port]; /* { dg-warning "multiple methods named .\\+port. found" } */ - /* { dg-message "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 10 } */ - /* { dg-message "also found .\\+\\(Protocol \\*\\)port." "" { target *-*-* } 15 } */ + /* { dg-message "using .\\-\\(unsigned( int)?\\)port." "" { target *-*-* } 17 } */ + /* { dg-message "also found .\\+\\(Protocol \\*\\)port." "" { target *-*-* } 22 } */ [receiver starboard]; /* { dg-warning "no .\\+starboard. method found" } */ - /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 26 } */ - /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 26 } */ - /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 26 } */ + /* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 33 } */ + /* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 33 } */ + /* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 33 } */ [Class port]; /* { dg-error ".Class. is not an Objective\\-C class name or alias" } */ } diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/no-extra-load.m gcc-4.8.1/gcc/testsuite/objc.dg/no-extra-load.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/no-extra-load.m 2010-03-25 17:25:05.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/no-extra-load.m 2013-07-16 08:24:02.909501000 -0500 @@ -1,7 +1,7 @@ /* { dg-do compile { target *-*-darwin* } } */ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ -#import +#include main() { [NSObject new]; } /* { dg-final { scan-assembler-not "L_objc_msgSend\\\$non_lazy_ptr" } } */ diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/objc-foreach-4.m gcc-4.8.1/gcc/testsuite/objc.dg/objc-foreach-4.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/objc-foreach-4.m 2011-01-09 10:24:46.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/objc.dg/objc-foreach-4.m 2013-07-16 08:24:02.909501000 -0500 @@ -1,17 +1,13 @@ /* Test for valid objc objects used in a for-each statement. */ /* FIXME: Run this test with the GNU runtime as well. */ -/* { dg-do compile { target *-*-darwin* } } */ +/* { dg-do run { target *-*-darwin* } } */ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ +/* { dg-additional-options "-framework Foundation" { target { *-*-darwin* } } } */ -#include -#include - -#if defined (__NEXT_RUNTIME__) && defined (__LP64__) -/* Fudge the class reference until we implement the compiler-side - const strings. */ -extern void *_NSConstantStringClassReference; -#endif +#include +#include +#include // gcc -o foo foo.m -framework Foundation diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/objc-foreach-5.m gcc-4.8.1/gcc/testsuite/objc.dg/objc-foreach-5.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/objc-foreach-5.m 2011-01-09 10:24:46.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/objc.dg/objc-foreach-5.m 2013-07-16 08:24:02.909501000 -0500 @@ -2,8 +2,10 @@ /* { dg-do compile { target *-*-darwin* } } */ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */ +/* { dg-additional-options "-framework Foundation" { target { *-*-darwin* } } } */ -#import +#include +#include NSArray * createTestVictim(unsigned capacity) { NSMutableArray * arr = [[NSMutableArray alloc] initWithCapacity:capacity]; diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/pr23214.m gcc-4.8.1/gcc/testsuite/objc.dg/pr23214.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/pr23214.m 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/pr23214.m 2013-07-16 08:24:02.909501000 -0500 @@ -3,14 +3,24 @@ /* { dg-do run } */ /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ +/* { dg-additional-options "-framework Foundation" { target { { *-*-darwin* } && objc2 } } } */ +#if defined (__NEXT_RUNTIME__) && defined(__OBJC2__) \ + && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) \ + && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1070 #include - -@interface Object (TS_CAT) +#define OBJECT NSObject +#else +#include +#define OBJECT Object +#include +#endif + +@interface OBJECT (TS_CAT) - test; @end -@implementation Object (TS_CAT) +@implementation OBJECT (TS_CAT) - test { return self; } @end @@ -20,7 +30,7 @@ @protocol B @end -@interface Dummy : Object +@interface Dummy : OBJECT @end int main () diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/proto-lossage-7.m gcc-4.8.1/gcc/testsuite/objc.dg/proto-lossage-7.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/proto-lossage-7.m 2010-09-14 19:08:59.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/proto-lossage-7.m 2013-07-16 08:24:02.909501000 -0500 @@ -1,12 +1,19 @@ /* Check that typedefs of ObjC classes preserve any @protocol qualifiers. */ /* { dg-do compile } */ + +#ifdef __NEXT_RUNTIME__ +#include +#define OBJECT NSObject +#else #include +#define OBJECT Object +#endif @protocol CanDoStuff; -typedef Object CanDoStuffType; -typedef Object *CanDoStuffTypePtr; +typedef OBJECT CanDoStuffType; +typedef OBJECT *CanDoStuffTypePtr; @protocol CanDoStuff - (int) dostuff; diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/strings/const-cfstring-5.m gcc-4.8.1/gcc/testsuite/objc.dg/strings/const-cfstring-5.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/strings/const-cfstring-5.m 2010-10-22 05:30:29.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/strings/const-cfstring-5.m 2013-07-16 08:24:02.909501000 -0500 @@ -6,16 +6,16 @@ /* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-options "-mconstant-cfstrings" } */ -#include +#include -@interface Foo: Object { +@interface Foo: NSObject { char *cString; unsigned int len; } + (Foo *)description; @end -@interface Bar: Object +@interface Bar: NSObject + (Foo *) getString: (int) which; @end diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/strings/const-str-12b.m gcc-4.8.1/gcc/testsuite/objc.dg/strings/const-str-12b.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/strings/const-str-12b.m 2011-01-11 04:14:48.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/objc.dg/strings/const-str-12b.m 2013-07-16 08:24:02.909501000 -0500 @@ -5,17 +5,23 @@ /* { dg-options "-fconstant-string-class=Foo" } */ /* { dg-options "-mno-constant-cfstrings -fconstant-string-class=Foo" { target *-*-darwin* } } */ +#ifdef __NEXT_RUNTIME__ +#include +#define OBJECT NSObject +#else #include +#define OBJECT Object +#endif #include "../../objc-obj-c++-shared/objc-test-suite-types.h" -@interface Foo: Object { +@interface Foo: OBJECT { char *cString; unsigned int len; } + (id)description; @end -@interface Bar: Object +@interface Bar: OBJECT + (Foo *) getString: (int) which; @end diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/symtab-1.m gcc-4.8.1/gcc/testsuite/objc.dg/symtab-1.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/symtab-1.m 2011-02-17 18:07:38.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/objc.dg/symtab-1.m 2013-07-16 08:24:02.909501000 -0500 @@ -4,9 +4,9 @@ /* { dg-do compile { target { *-*-darwin* } } } */ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ -#include +#include -@interface Base: Object +@interface Base: NSObject - (void)setValues; @end diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/torture/strings/const-str-10.m gcc-4.8.1/gcc/testsuite/objc.dg/torture/strings/const-str-10.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/torture/strings/const-str-10.m 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/torture/strings/const-str-10.m 2013-07-16 08:24:02.909501000 -0500 @@ -6,10 +6,10 @@ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */ -#include +#include #include "../../../objc-obj-c++-shared/runtime.h" /* For NEXT_OBJC_USE_NEW_INTERFACE. */ -@interface NSString: Object +@interface NSString: NSObject @end @interface NSSimpleCString : NSString { diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/torture/strings/const-str-11.m gcc-4.8.1/gcc/testsuite/objc.dg/torture/strings/const-str-11.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/torture/strings/const-str-11.m 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/torture/strings/const-str-11.m 2013-07-16 08:24:02.909501000 -0500 @@ -7,10 +7,10 @@ /* { dg-options "-fconstant-string-class=XStr" } */ /* { dg-options "-mno-constant-cfstrings -fconstant-string-class=XStr" { target *-*-darwin* } } */ -#include +#include #include "../../../objc-obj-c++-shared/runtime.h" /* For NEXT_OBJC_USE_NEW_INTERFACE. */ -@interface XString: Object { +@interface XString: NSObject { @protected char *bytes; } diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/torture/strings/const-str-9.m gcc-4.8.1/gcc/testsuite/objc.dg/torture/strings/const-str-9.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/torture/strings/const-str-9.m 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/torture/strings/const-str-9.m 2013-07-16 08:24:02.909501000 -0500 @@ -5,10 +5,10 @@ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */ -#include +#include #include "../../../objc-obj-c++-shared/runtime.h" /* For NEXT_OBJC_USE_NEW_INTERFACE. */ -@interface NSConstantString: Object { +@interface NSConstantString: NSObject { char *cString; unsigned int len; } diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/zero-link-1.m gcc-4.8.1/gcc/testsuite/objc.dg/zero-link-1.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/zero-link-1.m 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/zero-link-1.m 2013-07-16 08:24:02.909501000 -0500 @@ -5,13 +5,12 @@ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-options "-fzero-link" } */ -#include -#include +#include extern void abort(void); #define CHECK_IF(expr) if(!(expr)) abort(); -@interface Base: Object +@interface Base: NSObject + (int) getValue; @end diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/zero-link-2.m gcc-4.8.1/gcc/testsuite/objc.dg/zero-link-2.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/zero-link-2.m 2011-02-17 18:07:38.000000000 -0600 +++ gcc-4.8.1/gcc/testsuite/objc.dg/zero-link-2.m 2013-07-16 08:24:02.909501000 -0500 @@ -5,12 +5,12 @@ /* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-options "-fno-zero-link" } */ -#include +#include extern void abort(void); #define CHECK_IF(expr) if(!(expr)) abort(); -@interface Base: Object +@interface Base: NSObject + (int) getValue; @end diff -Naur gcc-4.8.1.orig/gcc/testsuite/objc.dg/zero-link-3.m gcc-4.8.1/gcc/testsuite/objc.dg/zero-link-3.m --- gcc-4.8.1.orig/gcc/testsuite/objc.dg/zero-link-3.m 2011-06-06 17:46:58.000000000 -0500 +++ gcc-4.8.1/gcc/testsuite/objc.dg/zero-link-3.m 2013-07-16 08:24:02.909501000 -0500 @@ -2,15 +2,23 @@ /* Contributed by Ziemowit Laski . */ /* { dg-do run { target *-*-darwin* } } */ -/* { dg-options "-fzero-link" } */ +/* { dg-additional-options "-fzero-link" } */ +/* { dg-additional-options "-framework Foundation" { target { *-*-darwin* } } } */ /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ +#ifdef __NEXT_RUNTIME__ +#include +#define OBJECT NSObject +#else #include +#include +#define OBJECT Object +#endif extern void abort(void); #define CHECK_IF(expr) if(!(expr)) abort(); -@interface Base: Object +@interface Base: OBJECT + (int) getValue; @end diff -Naur gcc-4.8.1.orig/gcc/tlink.c gcc-4.8.1/gcc/tlink.c --- gcc-4.8.1.orig/gcc/tlink.c 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/tlink.c 2013-06-20 12:12:17.412846000 -0500 @@ -817,18 +817,18 @@ void do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED) { - int exit = tlink_execute ("ld", ld_argv, ldout, lderrout); + int ret = tlink_execute ("ld", ld_argv, ldout, lderrout); tlink_init (); - if (exit) + if (ret) { int i = 0; /* Until collect does a better job of figuring out which are object files, assume that everything on the command line could be. */ if (read_repo_files (ld_argv)) - while (exit && i++ < MAX_ITERATIONS) + while (ret && i++ < MAX_ITERATIONS) { if (tlink_verbose >= 3) { @@ -843,7 +843,7 @@ break; if (tlink_verbose) fprintf (stderr, _("collect: relinking\n")); - exit = tlink_execute ("ld", ld_argv, ldout, lderrout); + ret = tlink_execute ("ld", ld_argv, ldout, lderrout); } } @@ -851,10 +851,10 @@ unlink (ldout); dump_ld_file (lderrout, stderr); unlink (lderrout); - if (exit) + if (ret) { - error ("ld returned %d exit status", exit); - collect_exit (exit); + error ("ld returned %d exit status", ret); + exit (ret); } else { diff -Naur gcc-4.8.1.orig/gcc/tree-call-cdce.c gcc-4.8.1/gcc/tree-call-cdce.c --- gcc-4.8.1.orig/gcc/tree-call-cdce.c 2013-02-20 09:19:13.000000000 -0600 +++ gcc-4.8.1/gcc/tree-call-cdce.c 2013-08-16 04:04:52.452768000 -0500 @@ -726,15 +726,28 @@ return false and do not do any transformation for the call. */ if (nconds == 0) - return false; + { + conds.release (); + return false; + } bi_call_bb = gimple_bb (bi_call); - /* Now find the join target bb -- split - bi_call_bb if needed. */ - bi_call_bsi = gsi_for_stmt (bi_call); + /* Now find the join target bb -- split bi_call_bb if needed. */ + if (stmt_ends_bb_p (bi_call)) + { + /* If the call must be the last in the bb, don't split the block, + it could e.g. have EH edges. */ + join_tgt_in_edge_from_call = find_fallthru_edge (bi_call_bb->succs); + if (join_tgt_in_edge_from_call == NULL) + { + conds.release (); + return false; + } + } + else + join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call); - join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call); bi_call_bsi = gsi_for_stmt (bi_call); join_tgt_bb = join_tgt_in_edge_from_call->dest; diff -Naur gcc-4.8.1.orig/gcc/tree-parloops.c gcc-4.8.1/gcc/tree-parloops.c --- gcc-4.8.1.orig/gcc/tree-parloops.c 2013-05-07 03:11:46.000000000 -0500 +++ gcc-4.8.1/gcc/tree-parloops.c 2013-08-18 10:24:12.566692000 -0500 @@ -478,9 +478,12 @@ if (gsi == NULL) return NULL; addr = TREE_OPERAND (*var_p, 0); - name = make_temp_ssa_name (TREE_TYPE (addr), NULL, - get_name (TREE_OPERAND - (TREE_OPERAND (*var_p, 0), 0))); + const char *obj_name + = get_name (TREE_OPERAND (TREE_OPERAND (*var_p, 0), 0)); + if (obj_name) + name = make_temp_ssa_name (TREE_TYPE (addr), NULL, obj_name); + else + name = make_ssa_name (TREE_TYPE (addr), NULL); stmt = gimple_build_assign (name, addr); gsi_insert_on_edge_immediate (entry, stmt); @@ -679,6 +682,12 @@ dta.changed = true; } } + else if (gimple_clobber_p (stmt)) + { + stmt = gimple_build_nop (); + gsi_replace (gsi, stmt, false); + dta.changed = true; + } else { dta.gsi = gsi; diff -Naur gcc-4.8.1.orig/gcc/tree-sra.c gcc-4.8.1/gcc/tree-sra.c --- gcc-4.8.1.orig/gcc/tree-sra.c 2013-05-23 08:25:23.000000000 -0500 +++ gcc-4.8.1/gcc/tree-sra.c 2013-08-14 15:36:12.151519000 -0500 @@ -1440,6 +1440,7 @@ { tree prev_base = base; tree off; + tree mem_ref; HOST_WIDE_INT base_offset; unsigned HOST_WIDE_INT misalign; unsigned int align; @@ -1490,7 +1491,12 @@ if (align < TYPE_ALIGN (exp_type)) exp_type = build_aligned_type (exp_type, align); - return fold_build2_loc (loc, MEM_REF, exp_type, base, off); + mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off); + if (TREE_THIS_VOLATILE (prev_base)) + TREE_THIS_VOLATILE (mem_ref) = 1; + if (TREE_SIDE_EFFECTS (prev_base)) + TREE_SIDE_EFFECTS (mem_ref) = 1; + return mem_ref; } /* Construct a memory reference to a part of an aggregate BASE at the given diff -Naur gcc-4.8.1.orig/gcc/tree-tailcall.c gcc-4.8.1/gcc/tree-tailcall.c --- gcc-4.8.1.orig/gcc/tree-tailcall.c 2013-03-06 17:26:42.000000000 -0600 +++ gcc-4.8.1/gcc/tree-tailcall.c 2013-08-23 02:35:01.611004000 -0500 @@ -328,8 +328,10 @@ case NEGATE_EXPR: if (FLOAT_TYPE_P (TREE_TYPE (op0))) *m = build_real (TREE_TYPE (op0), dconstm1); - else + else if (INTEGRAL_TYPE_P (TREE_TYPE (op0))) *m = build_int_cst (TREE_TYPE (op0), -1); + else + return false; *ass_var = dest; return true; @@ -341,8 +343,10 @@ { if (FLOAT_TYPE_P (TREE_TYPE (non_ass_var))) *m = build_real (TREE_TYPE (non_ass_var), dconstm1); - else + else if (INTEGRAL_TYPE_P (TREE_TYPE (non_ass_var))) *m = build_int_cst (TREE_TYPE (non_ass_var), -1); + else + return false; *a = fold_build1 (NEGATE_EXPR, TREE_TYPE (non_ass_var), non_ass_var); } @@ -570,6 +574,11 @@ if (!tail_recursion && (m || a)) return; + /* For pointers don't allow additions or multiplications. */ + if ((m || a) + && POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))) + return; + nw = XNEW (struct tailcall); nw->call_gsi = gsi; diff -Naur gcc-4.8.1.orig/gcc/tree-vect-patterns.c gcc-4.8.1/gcc/tree-vect-patterns.c --- gcc-4.8.1.orig/gcc/tree-vect-patterns.c 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/tree-vect-patterns.c 2013-06-12 08:01:29.647807000 -0500 @@ -638,7 +638,10 @@ && vect_handle_widen_op_by_const (last_stmt, MULT_EXPR, oprnd1, &oprnd0, stmts, type, &half_type0, def_stmt0)) - half_type1 = half_type0; + { + half_type1 = half_type0; + oprnd1 = fold_convert (half_type1, oprnd1); + } else return NULL; } diff -Naur gcc-4.8.1.orig/gcc/tree-vect-stmts.c gcc-4.8.1/gcc/tree-vect-stmts.c --- gcc-4.8.1.orig/gcc/tree-vect-stmts.c 2013-03-05 03:37:56.000000000 -0600 +++ gcc-4.8.1/gcc/tree-vect-stmts.c 2013-06-27 10:41:34.547790000 -0500 @@ -3796,6 +3796,7 @@ enum vect_def_type dt; stmt_vec_info prev_stmt_info = NULL; tree dataref_ptr = NULL_TREE; + gimple ptr_incr = NULL; int nunits = TYPE_VECTOR_SUBPARTS (vectype); int ncopies; int j; @@ -4040,7 +4041,6 @@ for (j = 0; j < ncopies; j++) { gimple new_stmt; - gimple ptr_incr; if (j == 0) { @@ -4313,7 +4313,7 @@ tree dummy; enum dr_alignment_support alignment_support_scheme; tree dataref_ptr = NULL_TREE; - gimple ptr_incr; + gimple ptr_incr = NULL; int nunits = TYPE_VECTOR_SUBPARTS (vectype); int ncopies; int i, j, group_size; diff -Naur gcc-4.8.1.orig/gcc/version.c gcc-4.8.1/gcc/version.c --- gcc-4.8.1.orig/gcc/version.c 2013-01-10 14:38:27.000000000 -0600 +++ gcc-4.8.1/gcc/version.c 2013-08-28 12:51:08.218924417 -0500 @@ -32,4 +32,4 @@ Makefile. */ const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION; -const char pkgversion_string[] = PKGVERSION; +const char pkgversion_string[] = "(GCC for Cross-LFS 4.8.1.20130828) "; diff -Naur gcc-4.8.1.orig/libffi/doc/libffi.info gcc-4.8.1/libffi/doc/libffi.info --- gcc-4.8.1.orig/libffi/doc/libffi.info 2013-05-31 05:05:08.000000000 -0500 +++ gcc-4.8.1/libffi/doc/libffi.info 1969-12-31 18:00:00.000000000 -0600 @@ -1,617 +0,0 @@ -This is doc/libffi.info, produced by makeinfo version 4.13 from -/d/gcc-4.8.1/gcc-4.8.1/libffi/doc/libffi.texi. - -This manual is for Libffi, a portable foreign-function interface -library. - - Copyright (C) 2008, 2010, 2011 Red Hat, Inc. - - Permission is granted to copy, distribute and/or modify this - document 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. A copy of the license is - included in the section entitled "GNU General Public License". - - -INFO-DIR-SECTION Development -START-INFO-DIR-ENTRY -* libffi: (libffi). Portable foreign-function interface library. -END-INFO-DIR-ENTRY - - -File: libffi.info, Node: Top, Next: Introduction, Up: (dir) - -libffi -****** - -This manual is for Libffi, a portable foreign-function interface -library. - - Copyright (C) 2008, 2010, 2011 Red Hat, Inc. - - Permission is granted to copy, distribute and/or modify this - document 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. A copy of the license is - included in the section entitled "GNU General Public License". - - -* Menu: - -* Introduction:: What is libffi? -* Using libffi:: How to use libffi. -* Missing Features:: Things libffi can't do. -* Index:: Index. - - -File: libffi.info, Node: Introduction, Next: Using libffi, Prev: Top, Up: Top - -1 What is libffi? -***************** - -Compilers for high level languages generate code that follow certain -conventions. These conventions are necessary, in part, for separate -compilation to work. One such convention is the "calling convention". -The calling convention is a set of assumptions made by the compiler -about where function arguments will be found on entry to a function. A -calling convention also specifies where the return value for a function -is found. The calling convention is also sometimes called the "ABI" or -"Application Binary Interface". - - Some programs may not know at the time of compilation what arguments -are to be passed to a function. For instance, an interpreter may be -told at run-time about the number and types of arguments used to call a -given function. `Libffi' can be used in such programs to provide a -bridge from the interpreter program to compiled code. - - The `libffi' library provides a portable, high level programming -interface to various calling conventions. This allows a programmer to -call any function specified by a call interface description at run time. - - FFI stands for Foreign Function Interface. A foreign function -interface is the popular name for the interface that allows code -written in one language to call code written in another language. The -`libffi' library really only provides the lowest, machine dependent -layer of a fully featured foreign function interface. A layer must -exist above `libffi' that handles type conversions for values passed -between the two languages. - - -File: libffi.info, Node: Using libffi, Next: Missing Features, Prev: Introduction, Up: Top - -2 Using libffi -************** - -* Menu: - -* The Basics:: The basic libffi API. -* Simple Example:: A simple example. -* Types:: libffi type descriptions. -* Multiple ABIs:: Different passing styles on one platform. -* The Closure API:: Writing a generic function. -* Closure Example:: A closure example. - - -File: libffi.info, Node: The Basics, Next: Simple Example, Up: Using libffi - -2.1 The Basics -============== - -`Libffi' assumes that you have a pointer to the function you wish to -call and that you know the number and types of arguments to pass it, as -well as the return type of the function. - - The first thing you must do is create an `ffi_cif' object that -matches the signature of the function you wish to call. This is a -separate step because it is common to make multiple calls using a -single `ffi_cif'. The "cif" in `ffi_cif' stands for Call InterFace. -To prepare a call interface object, use the function `ffi_prep_cif'. - - -- Function: ffi_status ffi_prep_cif (ffi_cif *CIF, ffi_abi ABI, - unsigned int NARGS, ffi_type *RTYPE, ffi_type **ARGTYPES) - This initializes CIF according to the given parameters. - - ABI is the ABI to use; normally `FFI_DEFAULT_ABI' is what you - want. *note Multiple ABIs:: for more information. - - NARGS is the number of arguments that this function accepts. - - RTYPE is a pointer to an `ffi_type' structure that describes the - return type of the function. *Note Types::. - - ARGTYPES is a vector of `ffi_type' pointers. ARGTYPES must have - NARGS elements. If NARGS is 0, this argument is ignored. - - `ffi_prep_cif' returns a `libffi' status code, of type - `ffi_status'. This will be either `FFI_OK' if everything worked - properly; `FFI_BAD_TYPEDEF' if one of the `ffi_type' objects is - incorrect; or `FFI_BAD_ABI' if the ABI parameter is invalid. - - If the function being called is variadic (varargs) then -`ffi_prep_cif_var' must be used instead of `ffi_prep_cif'. - - -- Function: ffi_status ffi_prep_cif_var (ffi_cif *CIF, ffi_abi - varabi, unsigned int NFIXEDARGS, unsigned int varntotalargs, - ffi_type *RTYPE, ffi_type **ARGTYPES) - This initializes CIF according to the given parameters for a call - to a variadic function. In general it's operation is the same as - for `ffi_prep_cif' except that: - - NFIXEDARGS is the number of fixed arguments, prior to any variadic - arguments. It must be greater than zero. - - NTOTALARGS the total number of arguments, including variadic and - fixed arguments. - - Note that, different cif's must be prepped for calls to the same - function when different numbers of arguments are passed. - - Also note that a call to `ffi_prep_cif_var' with - NFIXEDARGS=NOTOTALARGS is NOT equivalent to a call to - `ffi_prep_cif'. - - - To call a function using an initialized `ffi_cif', use the -`ffi_call' function: - - -- Function: void ffi_call (ffi_cif *CIF, void *FN, void *RVALUE, void - **AVALUES) - This calls the function FN according to the description given in - CIF. CIF must have already been prepared using `ffi_prep_cif'. - - RVALUE is a pointer to a chunk of memory that will hold the result - of the function call. This must be large enough to hold the - result and must be suitably aligned; it is the caller's - responsibility to ensure this. If CIF declares that the function - returns `void' (using `ffi_type_void'), then RVALUE is ignored. - If RVALUE is `NULL', then the return value is discarded. - - AVALUES is a vector of `void *' pointers that point to the memory - locations holding the argument values for a call. If CIF declares - that the function has no arguments (i.e., NARGS was 0), then - AVALUES is ignored. Note that argument values may be modified by - the callee (for instance, structs passed by value); the burden of - copying pass-by-value arguments is placed on the caller. - - -File: libffi.info, Node: Simple Example, Next: Types, Prev: The Basics, Up: Using libffi - -2.2 Simple Example -================== - -Here is a trivial example that calls `puts' a few times. - - #include - #include - - int main() - { - ffi_cif cif; - ffi_type *args[1]; - void *values[1]; - char *s; - int rc; - - /* Initialize the argument info vectors */ - args[0] = &ffi_type_pointer; - values[0] = &s; - - /* Initialize the cif */ - if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) - { - s = "Hello World!"; - ffi_call(&cif, puts, &rc, values); - /* rc now holds the result of the call to puts */ - - /* values holds a pointer to the function's arg, so to - call puts() again all we need to do is change the - value of s */ - s = "This is cool!"; - ffi_call(&cif, puts, &rc, values); - } - - return 0; - } - - -File: libffi.info, Node: Types, Next: Multiple ABIs, Prev: Simple Example, Up: Using libffi - -2.3 Types -========= - -* Menu: - -* Primitive Types:: Built-in types. -* Structures:: Structure types. -* Type Example:: Structure type example. - - -File: libffi.info, Node: Primitive Types, Next: Structures, Up: Types - -2.3.1 Primitive Types ---------------------- - -`Libffi' provides a number of built-in type descriptors that can be -used to describe argument and return types: - -`ffi_type_void' - The type `void'. This cannot be used for argument types, only for - return values. - -`ffi_type_uint8' - An unsigned, 8-bit integer type. - -`ffi_type_sint8' - A signed, 8-bit integer type. - -`ffi_type_uint16' - An unsigned, 16-bit integer type. - -`ffi_type_sint16' - A signed, 16-bit integer type. - -`ffi_type_uint32' - An unsigned, 32-bit integer type. - -`ffi_type_sint32' - A signed, 32-bit integer type. - -`ffi_type_uint64' - An unsigned, 64-bit integer type. - -`ffi_type_sint64' - A signed, 64-bit integer type. - -`ffi_type_float' - The C `float' type. - -`ffi_type_double' - The C `double' type. - -`ffi_type_uchar' - The C `unsigned char' type. - -`ffi_type_schar' - The C `signed char' type. (Note that there is not an exact - equivalent to the C `char' type in `libffi'; ordinarily you should - either use `ffi_type_schar' or `ffi_type_uchar' depending on - whether `char' is signed.) - -`ffi_type_ushort' - The C `unsigned short' type. - -`ffi_type_sshort' - The C `short' type. - -`ffi_type_uint' - The C `unsigned int' type. - -`ffi_type_sint' - The C `int' type. - -`ffi_type_ulong' - The C `unsigned long' type. - -`ffi_type_slong' - The C `long' type. - -`ffi_type_longdouble' - On platforms that have a C `long double' type, this is defined. - On other platforms, it is not. - -`ffi_type_pointer' - A generic `void *' pointer. You should use this for all pointers, - regardless of their real type. - - Each of these is of type `ffi_type', so you must take the address -when passing to `ffi_prep_cif'. - - -File: libffi.info, Node: Structures, Next: Type Example, Prev: Primitive Types, Up: Types - -2.3.2 Structures ----------------- - -Although `libffi' has no special support for unions or bit-fields, it -is perfectly happy passing structures back and forth. You must first -describe the structure to `libffi' by creating a new `ffi_type' object -for it. - - -- ffi_type: - The `ffi_type' has the following members: - `size_t size' - This is set by `libffi'; you should initialize it to zero. - - `unsigned short alignment' - This is set by `libffi'; you should initialize it to zero. - - `unsigned short type' - For a structure, this should be set to `FFI_TYPE_STRUCT'. - - `ffi_type **elements' - This is a `NULL'-terminated array of pointers to `ffi_type' - objects. There is one element per field of the struct. - - -File: libffi.info, Node: Type Example, Prev: Structures, Up: Types - -2.3.3 Type Example ------------------- - -The following example initializes a `ffi_type' object representing the -`tm' struct from Linux's `time.h'. - - Here is how the struct is defined: - - struct tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - /* Those are for future use. */ - long int __tm_gmtoff__; - __const char *__tm_zone__; - }; - - Here is the corresponding code to describe this struct to `libffi': - - { - ffi_type tm_type; - ffi_type *tm_type_elements[12]; - int i; - - tm_type.size = tm_type.alignment = 0; - tm_type.elements = &tm_type_elements; - - for (i = 0; i < 9; i++) - tm_type_elements[i] = &ffi_type_sint; - - tm_type_elements[9] = &ffi_type_slong; - tm_type_elements[10] = &ffi_type_pointer; - tm_type_elements[11] = NULL; - - /* tm_type can now be used to represent tm argument types and - return types for ffi_prep_cif() */ - } - - -File: libffi.info, Node: Multiple ABIs, Next: The Closure API, Prev: Types, Up: Using libffi - -2.4 Multiple ABIs -================= - -A given platform may provide multiple different ABIs at once. For -instance, the x86 platform has both `stdcall' and `fastcall' functions. - - `libffi' provides some support for this. However, this is -necessarily platform-specific. - - -File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Multiple ABIs, Up: Using libffi - -2.5 The Closure API -=================== - -`libffi' also provides a way to write a generic function - a function -that can accept and decode any combination of arguments. This can be -useful when writing an interpreter, or to provide wrappers for -arbitrary functions. - - This facility is called the "closure API". Closures are not -supported on all platforms; you can check the `FFI_CLOSURES' define to -determine whether they are supported on the current platform. - - Because closures work by assembling a tiny function at runtime, they -require special allocation on platforms that have a non-executable -heap. Memory management for closures is handled by a pair of functions: - - -- Function: void *ffi_closure_alloc (size_t SIZE, void **CODE) - Allocate a chunk of memory holding SIZE bytes. This returns a - pointer to the writable address, and sets *CODE to the - corresponding executable address. - - SIZE should be sufficient to hold a `ffi_closure' object. - - -- Function: void ffi_closure_free (void *WRITABLE) - Free memory allocated using `ffi_closure_alloc'. The argument is - the writable address that was returned. - - Once you have allocated the memory for a closure, you must construct -a `ffi_cif' describing the function call. Finally you can prepare the -closure function: - - -- Function: ffi_status ffi_prep_closure_loc (ffi_closure *CLOSURE, - ffi_cif *CIF, void (*FUN) (ffi_cif *CIF, void *RET, void - **ARGS, void *USER_DATA), void *USER_DATA, void *CODELOC) - Prepare a closure function. - - CLOSURE is the address of a `ffi_closure' object; this is the - writable address returned by `ffi_closure_alloc'. - - CIF is the `ffi_cif' describing the function parameters. - - USER_DATA is an arbitrary datum that is passed, uninterpreted, to - your closure function. - - CODELOC is the executable address returned by `ffi_closure_alloc'. - - FUN is the function which will be called when the closure is - invoked. It is called with the arguments: - CIF - The `ffi_cif' passed to `ffi_prep_closure_loc'. - - RET - A pointer to the memory used for the function's return value. - FUN must fill this, unless the function is declared as - returning `void'. - - ARGS - A vector of pointers to memory holding the arguments to the - function. - - USER_DATA - The same USER_DATA that was passed to `ffi_prep_closure_loc'. - - `ffi_prep_closure_loc' will return `FFI_OK' if everything went ok, - and something else on error. - - After calling `ffi_prep_closure_loc', you can cast CODELOC to the - appropriate pointer-to-function type. - - You may see old code referring to `ffi_prep_closure'. This function -is deprecated, as it cannot handle the need for separate writable and -executable addresses. - - -File: libffi.info, Node: Closure Example, Prev: The Closure API, Up: Using libffi - -2.6 Closure Example -=================== - -A trivial example that creates a new `puts' by binding `fputs' with -`stdin'. - - #include - #include - - /* Acts like puts with the file given at time of enclosure. */ - void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[], - FILE *stream) - { - *ret = fputs(*(char **)args[0], stream); - } - - int main() - { - ffi_cif cif; - ffi_type *args[1]; - ffi_closure *closure; - - int (*bound_puts)(char *); - int rc; - - /* Allocate closure and bound_puts */ - closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts); - - if (closure) - { - /* Initialize the argument info vectors */ - args[0] = &ffi_type_pointer; - - /* Initialize the cif */ - if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) - { - /* Initialize the closure, setting stream to stdout */ - if (ffi_prep_closure_loc(closure, &cif, puts_binding, - stdout, bound_puts) == FFI_OK) - { - rc = bound_puts("Hello World!"); - /* rc now holds the result of the call to fputs */ - } - } - } - - /* Deallocate both closure, and bound_puts */ - ffi_closure_free(closure); - - return 0; - } - - -File: libffi.info, Node: Missing Features, Next: Index, Prev: Using libffi, Up: Top - -3 Missing Features -****************** - -`libffi' is missing a few features. We welcome patches to add support -for these. - - * Variadic closures. - - * There is no support for bit fields in structures. - - * The closure API is - - * The "raw" API is undocumented. - - Note that variadic support is very new and tested on a relatively -small number of platforms. - - -File: libffi.info, Node: Index, Prev: Missing Features, Up: Top - -Index -***** - -[index] -* Menu: - -* : Structures. (line 12) -* ABI: Introduction. (line 13) -* Application Binary Interface: Introduction. (line 13) -* calling convention: Introduction. (line 13) -* cif: The Basics. (line 14) -* closure API: The Closure API. (line 13) -* closures: The Closure API. (line 13) -* FFI: Introduction. (line 31) -* ffi_call: The Basics. (line 63) -* ffi_closure_alloc: The Closure API. (line 19) -* ffi_closure_free: The Closure API. (line 26) -* FFI_CLOSURES: The Closure API. (line 13) -* ffi_prep_cif: The Basics. (line 16) -* ffi_prep_cif_var: The Basics. (line 39) -* ffi_prep_closure_loc: The Closure API. (line 34) -* ffi_status <1>: The Closure API. (line 37) -* ffi_status: The Basics. (line 18) -* ffi_type: Structures. (line 11) -* ffi_type_double: Primitive Types. (line 41) -* ffi_type_float: Primitive Types. (line 38) -* ffi_type_longdouble: Primitive Types. (line 71) -* ffi_type_pointer: Primitive Types. (line 75) -* ffi_type_schar: Primitive Types. (line 47) -* ffi_type_sint: Primitive Types. (line 62) -* ffi_type_sint16: Primitive Types. (line 23) -* ffi_type_sint32: Primitive Types. (line 29) -* ffi_type_sint64: Primitive Types. (line 35) -* ffi_type_sint8: Primitive Types. (line 17) -* ffi_type_slong: Primitive Types. (line 68) -* ffi_type_sshort: Primitive Types. (line 56) -* ffi_type_uchar: Primitive Types. (line 44) -* ffi_type_uint: Primitive Types. (line 59) -* ffi_type_uint16: Primitive Types. (line 20) -* ffi_type_uint32: Primitive Types. (line 26) -* ffi_type_uint64: Primitive Types. (line 32) -* ffi_type_uint8: Primitive Types. (line 14) -* ffi_type_ulong: Primitive Types. (line 65) -* ffi_type_ushort: Primitive Types. (line 53) -* ffi_type_void: Primitive Types. (line 10) -* Foreign Function Interface: Introduction. (line 31) -* void <1>: The Closure API. (line 20) -* void: The Basics. (line 65) - - - -Tag Table: -Node: Top722 -Node: Introduction1470 -Node: Using libffi3106 -Node: The Basics3592 -Node: Simple Example7234 -Node: Types8261 -Node: Primitive Types8544 -Node: Structures10364 -Node: Type Example11224 -Node: Multiple ABIs12447 -Node: The Closure API12818 -Node: Closure Example15762 -Node: Missing Features17321 -Node: Index17774 - -End Tag Table diff -Naur gcc-4.8.1.orig/libffi/src/powerpc/ffi.c gcc-4.8.1/libffi/src/powerpc/ffi.c --- gcc-4.8.1.orig/libffi/src/powerpc/ffi.c 2013-02-06 11:32:41.000000000 -0600 +++ gcc-4.8.1/libffi/src/powerpc/ffi.c 2013-06-24 19:09:22.878901000 -0500 @@ -127,6 +127,9 @@ int i; ffi_type **ptr; +#ifndef __NO_FPRS__ + double double_tmp; +#endif union { void **v; char **c; @@ -146,7 +149,6 @@ 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); @@ -542,11 +544,12 @@ { char *where = next_arg.c; +#ifndef __LITTLE_ENDIAN__ /* Structures with size less than eight bytes are passed left-padded. */ if ((*ptr)->size < 8) where += 8 - (*ptr)->size; - +#endif memcpy (where, *p_argv.c, (*ptr)->size); next_arg.ul += words; if (next_arg.ul == gpr_end.ul) @@ -1208,6 +1211,7 @@ case FFI_TYPE_SINT8: case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ /* there are 8 gpr registers used to pass values */ if (ng < 8) { @@ -1221,9 +1225,10 @@ pst++; } break; - +#endif case FFI_TYPE_SINT16: case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ /* there are 8 gpr registers used to pass values */ if (ng < 8) { @@ -1237,7 +1242,7 @@ pst++; } break; - +#endif case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: case FFI_TYPE_POINTER: @@ -1367,22 +1372,25 @@ { case FFI_TYPE_SINT8: case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ avalue[i] = (char *) pst + 7; pst++; break; - +#endif case FFI_TYPE_SINT16: case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ avalue[i] = (char *) pst + 6; pst++; break; - +#endif case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: +#ifndef __LITTLE_ENDIAN__ avalue[i] = (char *) pst + 4; pst++; break; - +#endif case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: case FFI_TYPE_POINTER: @@ -1391,11 +1399,13 @@ break; case FFI_TYPE_STRUCT: +#ifndef __LITTLE_ENDIAN__ /* Structures with size less than eight bytes are passed left-padded. */ if (arg_types[i]->size < 8) avalue[i] = (char *) pst + 8 - arg_types[i]->size; else +#endif avalue[i] = pst; pst += (arg_types[i]->size + 7) / 8; break; diff -Naur gcc-4.8.1.orig/libffi/src/powerpc/linux64_closure.S gcc-4.8.1/libffi/src/powerpc/linux64_closure.S --- gcc-4.8.1.orig/libffi/src/powerpc/linux64_closure.S 2012-10-30 22:45:34.000000000 -0500 +++ gcc-4.8.1/libffi/src/powerpc/linux64_closure.S 2013-06-24 19:09:22.878901000 -0500 @@ -132,7 +132,11 @@ blr nop # case FFI_TYPE_INT +#ifdef __LITTLE_ENDIAN__ + lwa %r3, 112+0(%r1) +#else lwa %r3, 112+4(%r1) +#endif mtlr %r0 addi %r1, %r1, 240 blr @@ -152,33 +156,57 @@ lfd %f2, 112+8(%r1) b .Lfinish # case FFI_TYPE_UINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3, 112+0(%r1) +#else lbz %r3, 112+7(%r1) +#endif mtlr %r0 addi %r1, %r1, 240 blr # case FFI_TYPE_SINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3, 112+0(%r1) +#else lbz %r3, 112+7(%r1) +#endif extsb %r3,%r3 mtlr %r0 b .Lfinish # case FFI_TYPE_UINT16 +#ifdef __LITTLE_ENDIAN__ + lhz %r3, 112+0(%r1) +#else lhz %r3, 112+6(%r1) +#endif mtlr %r0 .Lfinish: addi %r1, %r1, 240 blr # case FFI_TYPE_SINT16 +#ifdef __LITTLE_ENDIAN__ + lha %r3, 112+0(%r1) +#else lha %r3, 112+6(%r1) +#endif mtlr %r0 addi %r1, %r1, 240 blr # case FFI_TYPE_UINT32 +#ifdef __LITTLE_ENDIAN__ + lwz %r3, 112+0(%r1) +#else lwz %r3, 112+4(%r1) +#endif mtlr %r0 addi %r1, %r1, 240 blr # case FFI_TYPE_SINT32 +#ifdef __LITTLE_ENDIAN__ + lwa %r3, 112+0(%r1) +#else lwa %r3, 112+4(%r1) +#endif mtlr %r0 addi %r1, %r1, 240 blr diff -Naur gcc-4.8.1.orig/libffi/src/powerpc/ppc_closure.S gcc-4.8.1/libffi/src/powerpc/ppc_closure.S --- gcc-4.8.1.orig/libffi/src/powerpc/ppc_closure.S 2012-03-04 15:11:09.000000000 -0600 +++ gcc-4.8.1/libffi/src/powerpc/ppc_closure.S 2013-06-24 19:09:22.878901000 -0500 @@ -159,25 +159,41 @@ #endif # case FFI_TYPE_UINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3,112+0(%r1) +#else lbz %r3,112+3(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr # case FFI_TYPE_SINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3,112+0(%r1) +#else lbz %r3,112+3(%r1) +#endif extsb %r3,%r3 mtlr %r0 b .Lfinish # case FFI_TYPE_UINT16 +#ifdef __LITTLE_ENDIAN__ + lhz %r3,112+0(%r1) +#else lhz %r3,112+2(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr # case FFI_TYPE_SINT16 +#ifdef __LITTLE_ENDIAN__ + lha %r3,112+0(%r1) +#else lha %r3,112+2(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr @@ -239,9 +255,15 @@ # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct. lwz %r3,112+0(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + addi %r1,%r1,144 + blr +#else srwi %r3,%r3,8 mtlr %r0 b .Lfinish +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct. lwz %r3,112+0(%r1) @@ -252,20 +274,35 @@ # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,24 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,16 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,8 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct. lwz %r3,112+0(%r1) @@ -273,6 +310,7 @@ mtlr %r0 b .Lfinish +#ifndef __LITTLE_ENDIAN__ .Lstruct567: subfic %r6,%r5,32 srw %r4,%r4,%r5 @@ -282,6 +320,7 @@ mtlr %r0 addi %r1,%r1,144 blr +#endif .Luint128: lwz %r6,112+12(%r1) diff -Naur gcc-4.8.1.orig/libgcc/config/aarch64/sfp-machine.h gcc-4.8.1/libgcc/config/aarch64/sfp-machine.h --- gcc-4.8.1.orig/libgcc/config/aarch64/sfp-machine.h 2013-02-04 13:06:20.000000000 -0600 +++ gcc-4.8.1/libgcc/config/aarch64/sfp-machine.h 2013-08-01 16:15:18.425750000 -0500 @@ -2,21 +2,26 @@ Copyright (C) 2009-2013 Free Software Foundation, Inc. Contributed by ARM Ltd. - This file is part of GCC. +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 - . */ +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 +. */ #define _FP_W_TYPE_SIZE 64 #define _FP_W_TYPE unsigned long diff -Naur gcc-4.8.1.orig/libgcc/config/aarch64/sync-cache.c gcc-4.8.1/libgcc/config/aarch64/sync-cache.c --- gcc-4.8.1.orig/libgcc/config/aarch64/sync-cache.c 2013-03-01 08:01:58.000000000 -0600 +++ gcc-4.8.1/libgcc/config/aarch64/sync-cache.c 2013-08-01 16:15:18.425750000 -0500 @@ -2,21 +2,26 @@ Copyright (C) 2012-2013 Free Software Foundation, Inc. Contributed by ARM Ltd. - This file is part of GCC. +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 - . */ +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 +. */ void __aarch64_sync_cache_range (const void *, const void *); diff -Naur gcc-4.8.1.orig/libgcc/config/avr/lib1funcs-fixed.S gcc-4.8.1/libgcc/config/avr/lib1funcs-fixed.S --- gcc-4.8.1.orig/libgcc/config/avr/lib1funcs-fixed.S 2013-02-12 08:55:16.000000000 -0600 +++ gcc-4.8.1/libgcc/config/avr/lib1funcs-fixed.S 2013-07-19 06:15:26.382992000 -0500 @@ -1464,12 +1464,13 @@ ;; Add-Saturate 2^{-RP-1} add A0, C0 brvc 0f - ldi A0, 0x7f + ldi C0, 0x7f + rjmp 9f 0: ;; Mask out bits beyond RP lsl C0 neg C0 and C0, A0 - mov C1, __tmp_reg__ +9: mov C1, __tmp_reg__ ret ENDF __roundqq3 #endif /* L_roundqq3 */ @@ -1488,12 +1489,13 @@ ;; Add-Saturate 2^{-RP-1} add A0, C0 brcc 0f - ldi A0, 0xff + ldi C0, 0xff + rjmp 9f 0: ;; Mask out bits beyond RP lsl C0 neg C0 and C0, A0 - mov C1, __tmp_reg__ +9: mov C1, __tmp_reg__ ret ENDF __rounduqq3 #endif /* L_rounduqq3 */ @@ -1565,16 +1567,17 @@ DEFUN __round_s2_const brvc 2f - ldi A1, 0x7f + ldi C1, 0x7f rjmp 1f ;; FALLTHRU (Barrier) ENDF __round_s2_const DEFUN __round_u2_const brcc 2f - ldi A1, 0xff + ldi C1, 0xff 1: - ldi A0, 0xff + ldi C0, 0xff + rjmp 9f 2: ;; Saturation is performed now. ;; Currently, we have C[] = 2^{-RP-1} @@ -1586,7 +1589,7 @@ ;; Clear the bits beyond the rounding point. and C0, A0 and C1, A1 - ret +9: ret ENDF __round_u2_const #endif /* L_round_2_const */ @@ -1681,18 +1684,19 @@ DEFUN __round_s4_const brvc 2f - ldi A3, 0x7f + ldi C3, 0x7f rjmp 1f ;; FALLTHRU (Barrier) ENDF __round_s4_const DEFUN __round_u4_const brcc 2f - ldi A3, 0xff + ldi C3, 0xff 1: - ldi A2, 0xff - ldi A1, 0xff - ldi A0, 0xff + ldi C2, 0xff + ldi C1, 0xff + ldi C0, 0xff + rjmp 9f 2: ;; Saturation is performed now. ;; Currently, we have C[] = 2^{-RP-1} @@ -1707,7 +1711,7 @@ and C1, A1 and C2, A2 and C3, A3 - ret +9: ret ENDF __round_u4_const #endif /* L_round_4_const */ @@ -1847,12 +1851,13 @@ 1: ;; Unsigned brcc 3f ;; Unsigned overflow: A[] = 0xff... -2: ldi A7, 0xff - ldi A6, 0xff - wmov A0, A6 - wmov A2, A6 - wmov A4, A6 - bld A7, 7 +2: ldi C7, 0xff + ldi C6, 0xff + wmov C0, C6 + wmov C2, C6 + wmov C4, C6 + bld C7, 7 + rjmp 9f 3: ;; C[] = -C[] - C[] push A0 @@ -1869,7 +1874,7 @@ and C5, A5 and C6, A6 and C7, A7 - ;; Epilogue +9: ;; Epilogue pop r29 pop r28 pop r17 diff -Naur gcc-4.8.1.orig/libgcc/config/i386/cpuinfo.c gcc-4.8.1/libgcc/config/i386/cpuinfo.c --- gcc-4.8.1.orig/libgcc/config/i386/cpuinfo.c 2013-03-07 19:02:29.000000000 -0600 +++ gcc-4.8.1/libgcc/config/i386/cpuinfo.c 2013-08-01 16:15:18.425750000 -0500 @@ -14,9 +14,14 @@ 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 -. */ +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 +. */ #include "cpuid.h" #include "tsystem.h" diff -Naur gcc-4.8.1.orig/libgcc/config/ia64/unwind-ia64.h gcc-4.8.1/libgcc/config/ia64/unwind-ia64.h --- gcc-4.8.1.orig/libgcc/config/ia64/unwind-ia64.h 2013-02-04 13:06:20.000000000 -0600 +++ gcc-4.8.1/libgcc/config/ia64/unwind-ia64.h 2013-08-01 16:15:18.425750000 -0500 @@ -2,21 +2,26 @@ Contributed by Andrew MacLeod Andrew Haley - This file is part of GCC. +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 - . */ +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 +. */ #ifdef __VMS__ /* On VMS, long is a 32 bit type. */ diff -Naur gcc-4.8.1.orig/libgcc/config/mips/vr4120-div.S gcc-4.8.1/libgcc/config/mips/vr4120-div.S --- gcc-4.8.1.orig/libgcc/config/mips/vr4120-div.S 2013-02-04 13:06:20.000000000 -0600 +++ gcc-4.8.1/libgcc/config/mips/vr4120-div.S 2013-08-01 16:15:18.425750000 -0500 @@ -3,18 +3,23 @@ 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. +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. -You should have received a copy of the GNU General Public License - along with GCC; see the file COPYING3. If not see +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 . */ /* This file contains functions which implement divsi3 and modsi3 for diff -Naur gcc-4.8.1.orig/libgcc/config/rs6000/ibm-ldouble.c gcc-4.8.1/libgcc/config/rs6000/ibm-ldouble.c --- gcc-4.8.1.orig/libgcc/config/rs6000/ibm-ldouble.c 2013-02-04 13:06:20.000000000 -0600 +++ gcc-4.8.1/libgcc/config/rs6000/ibm-ldouble.c 2013-06-18 20:18:38.348158000 -0500 @@ -42,10 +42,10 @@ represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a NaN is don't-care. - This code currently assumes big-endian. */ + This code currently assumes the most significant double is in + the lower numbered register or lower addressed memory. */ -#if (!defined (__LITTLE_ENDIAN__) \ - && (defined (__MACH__) || defined (__powerpc__) || defined (_AIX))) +#if defined (__MACH__) || defined (__powerpc__) || defined (_AIX) #define fabs(x) __builtin_fabs(x) #define isless(x, y) __builtin_isless (x, y) diff -Naur gcc-4.8.1.orig/libgcc/config/s390/linux-unwind.h gcc-4.8.1/libgcc/config/s390/linux-unwind.h --- gcc-4.8.1.orig/libgcc/config/s390/linux-unwind.h 2013-02-04 13:06:20.000000000 -0600 +++ gcc-4.8.1/libgcc/config/s390/linux-unwind.h 2013-07-31 02:24:06.307503000 -0500 @@ -31,6 +31,8 @@ s390_fallback_frame_state (struct _Unwind_Context *context, _Unwind_FrameState *fs) { + static const unsigned char dwarf_to_fpr_map[16] = + { 0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14, 9, 11, 13, 15 }; unsigned char *pc = context->ra; long new_cfa; int i; @@ -112,7 +114,7 @@ { fs->regs.reg[16+i].how = REG_SAVED_OFFSET; fs->regs.reg[16+i].loc.offset = - (long)®s->fprs[i] - new_cfa; + (long)®s->fprs[dwarf_to_fpr_map[i]] - new_cfa; } /* Load return addr from PSW into dummy register 32. */ diff -Naur gcc-4.8.1.orig/libgcc/config/tilepro/atomic.h gcc-4.8.1/libgcc/config/tilepro/atomic.h --- gcc-4.8.1.orig/libgcc/config/tilepro/atomic.h 2013-02-04 13:06:20.000000000 -0600 +++ gcc-4.8.1/libgcc/config/tilepro/atomic.h 2013-06-08 11:30:50.617938000 -0500 @@ -92,8 +92,6 @@ compare-and-exchange routine, so may be potentially less efficient. */ #endif -#include -#include #ifdef __tilegx__ #include #else @@ -122,9 +120,9 @@ /* 64-bit integer compare-and-exchange. */ static __inline __attribute__ ((always_inline)) - int64_t arch_atomic_val_compare_and_exchange_8 (volatile int64_t * mem, - int64_t oldval, - int64_t newval) + long long arch_atomic_val_compare_and_exchange_8 (volatile long long + *mem, long long oldval, + long long newval) { #ifdef __tilegx__ __insn_mtspr (SPR_CMPEXCH_VALUE, oldval); @@ -139,7 +137,7 @@ "R04" (newval_lo), "R05" (newval_hi), "m" (*mem):"r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "memory"); - return ((uint64_t) result_hi) << 32 | result_lo; + return ((long long) result_hi) << 32 | result_lo; #endif } @@ -150,11 +148,11 @@ #define arch_atomic_val_compare_and_exchange(mem, o, n) \ - ({ \ + __extension__ ({ \ (__typeof(*(mem)))(__typeof(*(mem)-*(mem))) \ ((sizeof(*(mem)) == 8) ? \ arch_atomic_val_compare_and_exchange_8( \ - (volatile int64_t*)(mem), (__typeof((o)-(o)))(o), \ + (volatile long long*)(mem), (__typeof((o)-(o)))(o), \ (__typeof((n)-(n)))(n)) : \ (sizeof(*(mem)) == 4) ? \ arch_atomic_val_compare_and_exchange_4( \ @@ -164,7 +162,7 @@ }) #define arch_atomic_bool_compare_and_exchange(mem, o, n) \ - ({ \ + __extension__ ({ \ __typeof(o) __o = (o); \ __builtin_expect( \ __o == arch_atomic_val_compare_and_exchange((mem), __o, (n)), 1); \ @@ -174,7 +172,7 @@ /* Loop with compare_and_exchange until we guess the correct value. Normally "expr" will be an expression using __old and __value. */ #define __arch_atomic_update_cmpxchg(mem, value, expr) \ - ({ \ + __extension__ ({ \ __typeof(value) __value = (value); \ __typeof(*(mem)) *__mem = (mem), __old = *__mem, __guess; \ do { \ @@ -189,12 +187,14 @@ /* Generic atomic op with 8- or 4-byte variant. The _mask, _addend, and _expr arguments are ignored on tilegx. */ #define __arch_atomic_update(mem, value, op, _mask, _addend, _expr) \ - ({ \ + __extension__ ({ \ ((__typeof(*(mem))) \ ((sizeof(*(mem)) == 8) ? (__typeof(*(mem)-*(mem)))__insn_##op( \ - (void *)(mem), (int64_t)(__typeof((value)-(value)))(value)) : \ + (volatile void *)(mem), \ + (long long)(__typeof((value)-(value)))(value)) : \ (sizeof(*(mem)) == 4) ? (int)__insn_##op##4( \ - (void *)(mem), (int32_t)(__typeof((value)-(value)))(value)) : \ + (volatile void *)(mem), \ + (int)(__typeof((value)-(value)))(value)) : \ __arch_atomic_error_bad_argument_size())); \ }) @@ -224,7 +224,7 @@ /* Generic atomic op with 8- or 4-byte variant. The _op argument is ignored on tilepro. */ #define __arch_atomic_update(mem, value, _op, mask, addend, expr) \ - ({ \ + __extension__ ({ \ (__typeof(*(mem)))(__typeof(*(mem)-*(mem))) \ ((sizeof(*(mem)) == 8) ? \ __arch_atomic_update_cmpxchg((mem), (value), (expr)) : \ @@ -263,13 +263,13 @@ __arch_atomic_update_cmpxchg(mem, mask, ~(__old & __value)) #define arch_atomic_bit_set(mem, bit) \ - ({ \ + __extension__ ({ \ __typeof(*(mem)) __mask = (__typeof(*(mem)))1 << (bit); \ __mask & arch_atomic_or((mem), __mask); \ }) #define arch_atomic_bit_clear(mem, bit) \ - ({ \ + __extension__ ({ \ __typeof(*(mem)) __mask = (__typeof(*(mem)))1 << (bit); \ __mask & arch_atomic_and((mem), ~__mask); \ }) diff -Naur gcc-4.8.1.orig/libgcc/config.host gcc-4.8.1/libgcc/config.host --- gcc-4.8.1.orig/libgcc/config.host 2013-02-04 13:06:20.000000000 -0600 +++ gcc-4.8.1/libgcc/config.host 2013-07-09 16:35:57.248336000 -0500 @@ -316,7 +316,7 @@ md_unwind_header=alpha/vms-unwind.h ;; arm-wrs-vxworks) - tmake_file="$tmake_file arm/t-arm arm/t-vxworks t-fdpbit" + tmake_file="$tmake_file arm/t-arm arm/t-vxworks t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp" extra_parts="$extra_parts crti.o crtn.o" ;; arm*-*-netbsdelf*) @@ -834,7 +834,7 @@ tmake_file="$tmake_file rs6000/t-netbsd rs6000/t-crtstuff" ;; powerpc-*-eabispe*) - tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic" + tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic t-fdpbit" extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o" ;; powerpc-*-eabisimaltivec*) @@ -865,7 +865,7 @@ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff t-crtstuff-pic t-fdpbit" extra_parts="$extra_parts crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o" ;; -powerpc-*-linux* | powerpc64-*-linux*) +powerpc*-*-linux*) tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-savresfgpr rs6000/t-crtstuff rs6000/t-linux t-softfp-sfdf t-softfp-excl t-dfprules rs6000/t-ppc64-fp t-softfp t-slibgcc-libgcc" extra_parts="$extra_parts ecrti.o ecrtn.o ncrti.o ncrtn.o" md_unwind_header=rs6000/linux-unwind.h diff -Naur gcc-4.8.1.orig/libgcc/unwind-dw2.c gcc-4.8.1/libgcc/unwind-dw2.c --- gcc-4.8.1.orig/libgcc/unwind-dw2.c 2013-03-14 04:13:36.000000000 -0500 +++ gcc-4.8.1/libgcc/unwind-dw2.c 2013-05-31 18:21:46.982106000 -0500 @@ -59,6 +59,35 @@ #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO) #endif +/* ??? For the public function interfaces, we tend to gcc_assert that the + column numbers are in range. For the dwarf2 unwind info this does happen, + although so far in a case that doesn't actually matter. + + See PR49146, in which a call from x86_64 ms abi to x86_64 unix abi stores + the call-saved xmm registers and annotates them. We havn't bothered + providing support for the xmm registers for the x86_64 port primarily + because the 64-bit windows targets don't use dwarf2 unwind, using sjlj or + SEH instead. Adding the support for unix targets would generally be a + waste. However, some runtime libraries supplied with ICC do contain such + an unorthodox transition, as well as the unwind info to match. This loss + of register restoration doesn't matter in practice, because the exception + is caught in the native unix abi, where all of the xmm registers are + call clobbered. + + Ideally, we'd record some bit to notice when we're failing to restore some + register recorded in the unwind info, but to do that we need annotation on + the unix->ms abi edge, so that we know when the register data may be + discarded. And since this edge is also within the ICC library, we're + unlikely to be able to get the new annotation. + + Barring a magic solution to restore the ms abi defined 128-bit xmm registers + (as distictly opposed to the full runtime width) without causing extra + overhead for normal unix abis, the best solution seems to be to simply + ignore unwind data for unknown columns. */ + +#define UNWIND_COLUMN_IN_RANGE(x) \ + __builtin_expect((x) <= DWARF_FRAME_REGISTERS, 1) + #ifdef REG_VALUE_IN_UNWIND_CONTEXT typedef _Unwind_Word _Unwind_Context_Reg_Val; @@ -939,14 +968,19 @@ reg = insn & 0x3f; insn_ptr = read_uleb128 (insn_ptr, &utmp); offset = (_Unwind_Sword) utmp * fs->data_align; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how - = REG_SAVED_OFFSET; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + { + fs->regs.reg[reg].how = REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + } } else if ((insn & 0xc0) == DW_CFA_restore) { reg = insn & 0x3f; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + fs->regs.reg[reg].how = REG_UNSAVED; } else switch (insn) { @@ -977,26 +1011,35 @@ insn_ptr = read_uleb128 (insn_ptr, ®); insn_ptr = read_uleb128 (insn_ptr, &utmp); offset = (_Unwind_Sword) utmp * fs->data_align; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how - = REG_SAVED_OFFSET; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + { + fs->regs.reg[reg].how = REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + } break; case DW_CFA_restore_extended: insn_ptr = read_uleb128 (insn_ptr, ®); /* FIXME, this is wrong; the CIE might have said that the register was saved somewhere. */ - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + fs->regs.reg[reg].how = REG_UNSAVED; break; case DW_CFA_same_value: insn_ptr = read_uleb128 (insn_ptr, ®); - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + fs->regs.reg[reg].how = REG_UNSAVED; break; case DW_CFA_undefined: insn_ptr = read_uleb128 (insn_ptr, ®); - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNDEFINED; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + fs->regs.reg[reg].how = REG_UNDEFINED; break; case DW_CFA_nop: @@ -1007,9 +1050,12 @@ _uleb128_t reg2; insn_ptr = read_uleb128 (insn_ptr, ®); insn_ptr = read_uleb128 (insn_ptr, ®2); - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = - (_Unwind_Word)reg2; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + { + fs->regs.reg[reg].how = REG_SAVED_REG; + fs->regs.reg[reg].loc.reg = (_Unwind_Word)reg2; + } } break; @@ -1067,8 +1113,12 @@ case DW_CFA_expression: insn_ptr = read_uleb128 (insn_ptr, ®); - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + { + fs->regs.reg[reg].how = REG_SAVED_EXP; + fs->regs.reg[reg].loc.exp = insn_ptr; + } insn_ptr = read_uleb128 (insn_ptr, &utmp); insn_ptr += utmp; break; @@ -1078,9 +1128,12 @@ insn_ptr = read_uleb128 (insn_ptr, ®); insn_ptr = read_sleb128 (insn_ptr, &stmp); offset = stmp * fs->data_align; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how - = REG_SAVED_OFFSET; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + { + fs->regs.reg[reg].how = REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + } break; case DW_CFA_def_cfa_sf: @@ -1103,25 +1156,34 @@ insn_ptr = read_uleb128 (insn_ptr, ®); insn_ptr = read_uleb128 (insn_ptr, &utmp); offset = (_Unwind_Sword) utmp * fs->data_align; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how - = REG_SAVED_VAL_OFFSET; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + { + fs->regs.reg[reg].how = REG_SAVED_VAL_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + } break; case DW_CFA_val_offset_sf: insn_ptr = read_uleb128 (insn_ptr, ®); insn_ptr = read_sleb128 (insn_ptr, &stmp); offset = stmp * fs->data_align; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how - = REG_SAVED_VAL_OFFSET; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + { + fs->regs.reg[reg].how = REG_SAVED_VAL_OFFSET; + fs->regs.reg[reg].loc.offset = offset; + } break; case DW_CFA_val_expression: insn_ptr = read_uleb128 (insn_ptr, ®); - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how - = REG_SAVED_VAL_EXP; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + { + fs->regs.reg[reg].how = REG_SAVED_VAL_EXP; + fs->regs.reg[reg].loc.exp = insn_ptr; + } insn_ptr = read_uleb128 (insn_ptr, &utmp); insn_ptr += utmp; break; @@ -1147,9 +1209,12 @@ insn_ptr = read_uleb128 (insn_ptr, ®); insn_ptr = read_uleb128 (insn_ptr, &utmp); offset = (_Unwind_Word) utmp * fs->data_align; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how - = REG_SAVED_OFFSET; - fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset; + reg = DWARF_REG_TO_UNWIND_COLUMN (reg); + if (UNWIND_COLUMN_IN_RANGE (reg)) + { + fs->regs.reg[reg].how = REG_SAVED_OFFSET; + fs->regs.reg[reg].loc.offset = -offset; + } break; default: diff -Naur gcc-4.8.1.orig/libgfortran/config/fpu-387.h gcc-4.8.1/libgfortran/config/fpu-387.h --- gcc-4.8.1.orig/libgfortran/config/fpu-387.h 2013-01-14 12:20:58.000000000 -0600 +++ gcc-4.8.1/libgfortran/config/fpu-387.h 2013-06-21 08:25:46.124005000 -0500 @@ -73,7 +73,7 @@ /* We need a single SSE instruction here so the handler can safely skip over it. */ - __asm__ volatile ("movaps %xmm0,%xmm0"); + __asm__ __volatile__ ("movaps\t%xmm0,%xmm0"); sigaction (SIGILL, &oact, NULL); @@ -95,42 +95,42 @@ #define _FPU_MASK_OM 0x08 #define _FPU_MASK_UM 0x10 #define _FPU_MASK_PM 0x20 +#define _FPU_MASK_ALL 0x3f + +#define _FPU_EX_ALL 0x3f void set_fpu (void) { + int excepts = 0; unsigned short cw; - asm volatile ("fnstcw %0" : "=m" (cw)); + __asm__ __volatile__ ("fstcw\t%0" : "=m" (cw)); - cw |= (_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM - | _FPU_MASK_UM | _FPU_MASK_PM); + if (options.fpe & GFC_FPE_INVALID) excepts |= _FPU_MASK_IM; + if (options.fpe & GFC_FPE_DENORMAL) excepts |= _FPU_MASK_DM; + if (options.fpe & GFC_FPE_ZERO) excepts |= _FPU_MASK_ZM; + if (options.fpe & GFC_FPE_OVERFLOW) excepts |= _FPU_MASK_OM; + if (options.fpe & GFC_FPE_UNDERFLOW) excepts |= _FPU_MASK_UM; + if (options.fpe & GFC_FPE_INEXACT) excepts |= _FPU_MASK_PM; - if (options.fpe & GFC_FPE_INVALID) cw &= ~_FPU_MASK_IM; - if (options.fpe & GFC_FPE_DENORMAL) cw &= ~_FPU_MASK_DM; - if (options.fpe & GFC_FPE_ZERO) cw &= ~_FPU_MASK_ZM; - if (options.fpe & GFC_FPE_OVERFLOW) cw &= ~_FPU_MASK_OM; - if (options.fpe & GFC_FPE_UNDERFLOW) cw &= ~_FPU_MASK_UM; - if (options.fpe & GFC_FPE_INEXACT) cw &= ~_FPU_MASK_PM; + cw |= _FPU_MASK_ALL; + cw &= ~excepts; - asm volatile ("fldcw %0" : : "m" (cw)); + __asm__ __volatile__ ("fnclex\n\tfldcw\t%0" : : "m" (cw)); if (has_sse()) { unsigned int cw_sse; - asm volatile ("%vstmxcsr %0" : "=m" (cw_sse)); + __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse)); + + /* The SSE exception masks are shifted by 7 bits. */ + cw_sse |= _FPU_MASK_ALL << 7; + cw_sse &= ~(excepts << 7); - cw_sse &= 0xffff0000; - cw_sse |= (_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM - | _FPU_MASK_UM | _FPU_MASK_PM ) << 7; - - if (options.fpe & GFC_FPE_INVALID) cw_sse &= ~(_FPU_MASK_IM << 7); - if (options.fpe & GFC_FPE_DENORMAL) cw_sse &= ~(_FPU_MASK_DM << 7); - if (options.fpe & GFC_FPE_ZERO) cw_sse &= ~(_FPU_MASK_ZM << 7); - if (options.fpe & GFC_FPE_OVERFLOW) cw_sse &= ~(_FPU_MASK_OM << 7); - if (options.fpe & GFC_FPE_UNDERFLOW) cw_sse &= ~(_FPU_MASK_UM << 7); - if (options.fpe & GFC_FPE_INEXACT) cw_sse &= ~(_FPU_MASK_PM << 7); + /* Clear stalled exception flags. */ + cw_sse &= ~_FPU_EX_ALL; - asm volatile ("%vldmxcsr %0" : : "m" (cw_sse)); + __asm__ __volatile__ ("%vldmxcsr\t%0" : : "m" (cw_sse)); } } diff -Naur gcc-4.8.1.orig/libgo/configure gcc-4.8.1/libgo/configure --- gcc-4.8.1.orig/libgo/configure 2013-02-11 13:03:04.000000000 -0600 +++ gcc-4.8.1/libgo/configure 2013-06-18 18:50:42.020320000 -0500 @@ -2496,7 +2496,7 @@ ac_config_headers="$ac_config_headers config.h" -libtool_VERSION=3:1:0 +libtool_VERSION=4:0:0 # Default to --enable-multilib diff -Naur gcc-4.8.1.orig/libgo/configure.ac gcc-4.8.1/libgo/configure.ac --- gcc-4.8.1.orig/libgo/configure.ac 2013-02-11 13:03:04.000000000 -0600 +++ gcc-4.8.1/libgo/configure.ac 2013-06-18 18:50:42.020320000 -0500 @@ -11,7 +11,7 @@ AC_CONFIG_SRCDIR(Makefile.am) AC_CONFIG_HEADER(config.h) -libtool_VERSION=3:1:0 +libtool_VERSION=4:0:0 AC_SUBST(libtool_VERSION) AM_ENABLE_MULTILIB(, ..) diff -Naur gcc-4.8.1.orig/libgo/go/archive/tar/common.go gcc-4.8.1/libgo/go/archive/tar/common.go --- gcc-4.8.1.orig/libgo/go/archive/tar/common.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/archive/tar/common.go 2013-07-16 01:55:04.520470000 -0500 @@ -9,12 +9,14 @@ // References: // http://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5 // http://www.gnu.org/software/tar/manual/html_node/Standard.html +// http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html package tar import ( "errors" "fmt" "os" + "path" "time" ) @@ -33,6 +35,8 @@ TypeCont = '7' // reserved TypeXHeader = 'x' // extended header TypeXGlobalHeader = 'g' // global extended header + TypeGNULongName = 'L' // Next file has a long name + TypeGNULongLink = 'K' // Next file symlinks to a file w/ a long name ) // A Header represents a single header in a tar archive. @@ -54,55 +58,172 @@ ChangeTime time.Time // status change time } +// File name constants from the tar spec. +const ( + fileNameSize = 100 // Maximum number of bytes in a standard tar name. + fileNamePrefixSize = 155 // Maximum number of ustar extension bytes. +) + +// FileInfo returns an os.FileInfo for the Header. +func (h *Header) FileInfo() os.FileInfo { + return headerFileInfo{h} +} + +// headerFileInfo implements os.FileInfo. +type headerFileInfo struct { + h *Header +} + +func (fi headerFileInfo) Size() int64 { return fi.h.Size } +func (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() } +func (fi headerFileInfo) ModTime() time.Time { return fi.h.ModTime } +func (fi headerFileInfo) Sys() interface{} { return fi.h } + +// Name returns the base name of the file. +func (fi headerFileInfo) Name() string { + if fi.IsDir() { + return path.Clean(fi.h.Name) + } + return fi.h.Name +} + +// Mode returns the permission and mode bits for the headerFileInfo. +func (fi headerFileInfo) Mode() (mode os.FileMode) { + // Set file permission bits. + mode = os.FileMode(fi.h.Mode).Perm() + + // Set setuid, setgid and sticky bits. + if fi.h.Mode&c_ISUID != 0 { + // setuid + mode |= os.ModeSetuid + } + if fi.h.Mode&c_ISGID != 0 { + // setgid + mode |= os.ModeSetgid + } + if fi.h.Mode&c_ISVTX != 0 { + // sticky + mode |= os.ModeSticky + } + + // Set file mode bits. + // clear perm, setuid, setgid and sticky bits. + m := os.FileMode(fi.h.Mode) &^ 07777 + if m == c_ISDIR { + // directory + mode |= os.ModeDir + } + if m == c_ISFIFO { + // named pipe (FIFO) + mode |= os.ModeNamedPipe + } + if m == c_ISLNK { + // symbolic link + mode |= os.ModeSymlink + } + if m == c_ISBLK { + // device file + mode |= os.ModeDevice + } + if m == c_ISCHR { + // Unix character device + mode |= os.ModeDevice + mode |= os.ModeCharDevice + } + if m == c_ISSOCK { + // Unix domain socket + mode |= os.ModeSocket + } + + switch fi.h.Typeflag { + case TypeLink, TypeSymlink: + // hard link, symbolic link + mode |= os.ModeSymlink + case TypeChar: + // character device node + mode |= os.ModeDevice + mode |= os.ModeCharDevice + case TypeBlock: + // block device node + mode |= os.ModeDevice + case TypeDir: + // directory + mode |= os.ModeDir + case TypeFifo: + // fifo node + mode |= os.ModeNamedPipe + } + + return mode +} + // sysStat, if non-nil, populates h from system-dependent fields of fi. var sysStat func(fi os.FileInfo, h *Header) error // Mode constants from the tar spec. const ( - c_ISDIR = 040000 - c_ISFIFO = 010000 - c_ISREG = 0100000 - c_ISLNK = 0120000 - c_ISBLK = 060000 - c_ISCHR = 020000 - c_ISSOCK = 0140000 + c_ISUID = 04000 // Set uid + c_ISGID = 02000 // Set gid + c_ISVTX = 01000 // Save text (sticky bit) + c_ISDIR = 040000 // Directory + c_ISFIFO = 010000 // FIFO + c_ISREG = 0100000 // Regular file + c_ISLNK = 0120000 // Symbolic link + c_ISBLK = 060000 // Block special file + c_ISCHR = 020000 // Character special file + c_ISSOCK = 0140000 // Socket ) // FileInfoHeader creates a partially-populated Header from fi. // If fi describes a symlink, FileInfoHeader records link as the link target. +// If fi describes a directory, a slash is appended to the name. func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) { if fi == nil { return nil, errors.New("tar: FileInfo is nil") } + fm := fi.Mode() h := &Header{ Name: fi.Name(), ModTime: fi.ModTime(), - Mode: int64(fi.Mode().Perm()), // or'd with c_IS* constants later + Mode: int64(fm.Perm()), // or'd with c_IS* constants later } switch { - case fi.Mode()&os.ModeType == 0: + case fm.IsRegular(): h.Mode |= c_ISREG h.Typeflag = TypeReg h.Size = fi.Size() case fi.IsDir(): h.Typeflag = TypeDir h.Mode |= c_ISDIR - case fi.Mode()&os.ModeSymlink != 0: + h.Name += "/" + case fm&os.ModeSymlink != 0: h.Typeflag = TypeSymlink h.Mode |= c_ISLNK h.Linkname = link - case fi.Mode()&os.ModeDevice != 0: - if fi.Mode()&os.ModeCharDevice != 0 { + case fm&os.ModeDevice != 0: + if fm&os.ModeCharDevice != 0 { h.Mode |= c_ISCHR h.Typeflag = TypeChar } else { h.Mode |= c_ISBLK h.Typeflag = TypeBlock } - case fi.Mode()&os.ModeSocket != 0: + case fm&os.ModeNamedPipe != 0: + h.Typeflag = TypeFifo + h.Mode |= c_ISFIFO + case fm&os.ModeSocket != 0: h.Mode |= c_ISSOCK default: - return nil, fmt.Errorf("archive/tar: unknown file mode %v", fi.Mode()) + return nil, fmt.Errorf("archive/tar: unknown file mode %v", fm) + } + if fm&os.ModeSetuid != 0 { + h.Mode |= c_ISUID + } + if fm&os.ModeSetgid != 0 { + h.Mode |= c_ISGID + } + if fm&os.ModeSticky != 0 { + h.Mode |= c_ISVTX } if sysStat != nil { return h, sysStat(fi, h) diff -Naur gcc-4.8.1.orig/libgo/go/archive/tar/reader.go gcc-4.8.1/libgo/go/archive/tar/reader.go --- gcc-4.8.1.orig/libgo/go/archive/tar/reader.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/archive/tar/reader.go 2013-07-16 01:55:04.520470000 -0500 @@ -14,6 +14,7 @@ "io/ioutil" "os" "strconv" + "strings" "time" ) @@ -21,24 +22,12 @@ ErrHeader = errors.New("archive/tar: invalid tar header") ) +const maxNanoSecondIntSize = 9 + // A Reader provides sequential access to the contents of a tar archive. // A tar archive consists of a sequence of files. // The Next method advances to the next file in the archive (including the first), // and then it can be treated as an io.Reader to access the file's data. -// -// Example: -// tr := tar.NewReader(r) -// for { -// hdr, err := tr.Next() -// if err == io.EOF { -// // end of tar archive -// break -// } -// if err != nil { -// // handle error -// } -// io.Copy(data, tr) -// } type Reader struct { r io.Reader err error @@ -55,13 +44,183 @@ if tr.err == nil { tr.skipUnread() } - if tr.err == nil { + if tr.err != nil { + return hdr, tr.err + } + hdr = tr.readHeader() + if hdr == nil { + return hdr, tr.err + } + // Check for PAX/GNU header. + switch hdr.Typeflag { + case TypeXHeader: + // PAX extended header + headers, err := parsePAX(tr) + if err != nil { + return nil, err + } + // We actually read the whole file, + // but this skips alignment padding + tr.skipUnread() hdr = tr.readHeader() + mergePAX(hdr, headers) + return hdr, nil + case TypeGNULongName: + // We have a GNU long name header. Its contents are the real file name. + realname, err := ioutil.ReadAll(tr) + if err != nil { + return nil, err + } + hdr, err := tr.Next() + hdr.Name = cString(realname) + return hdr, err + case TypeGNULongLink: + // We have a GNU long link header. + realname, err := ioutil.ReadAll(tr) + if err != nil { + return nil, err + } + hdr, err := tr.Next() + hdr.Linkname = cString(realname) + return hdr, err } return hdr, tr.err } -// Parse bytes as a NUL-terminated C-style string. +// mergePAX merges well known headers according to PAX standard. +// In general headers with the same name as those found +// in the header struct overwrite those found in the header +// struct with higher precision or longer values. Esp. useful +// for name and linkname fields. +func mergePAX(hdr *Header, headers map[string]string) error { + for k, v := range headers { + switch k { + case "path": + hdr.Name = v + case "linkpath": + hdr.Linkname = v + case "gname": + hdr.Gname = v + case "uname": + hdr.Uname = v + case "uid": + uid, err := strconv.ParseInt(v, 10, 0) + if err != nil { + return err + } + hdr.Uid = int(uid) + case "gid": + gid, err := strconv.ParseInt(v, 10, 0) + if err != nil { + return err + } + hdr.Gid = int(gid) + case "atime": + t, err := parsePAXTime(v) + if err != nil { + return err + } + hdr.AccessTime = t + case "mtime": + t, err := parsePAXTime(v) + if err != nil { + return err + } + hdr.ModTime = t + case "ctime": + t, err := parsePAXTime(v) + if err != nil { + return err + } + hdr.ChangeTime = t + case "size": + size, err := strconv.ParseInt(v, 10, 0) + if err != nil { + return err + } + hdr.Size = int64(size) + } + + } + return nil +} + +// parsePAXTime takes a string of the form %d.%d as described in +// the PAX specification. +func parsePAXTime(t string) (time.Time, error) { + buf := []byte(t) + pos := bytes.IndexByte(buf, '.') + var seconds, nanoseconds int64 + var err error + if pos == -1 { + seconds, err = strconv.ParseInt(t, 10, 0) + if err != nil { + return time.Time{}, err + } + } else { + seconds, err = strconv.ParseInt(string(buf[:pos]), 10, 0) + if err != nil { + return time.Time{}, err + } + nano_buf := string(buf[pos+1:]) + // Pad as needed before converting to a decimal. + // For example .030 -> .030000000 -> 30000000 nanoseconds + if len(nano_buf) < maxNanoSecondIntSize { + // Right pad + nano_buf += strings.Repeat("0", maxNanoSecondIntSize-len(nano_buf)) + } else if len(nano_buf) > maxNanoSecondIntSize { + // Right truncate + nano_buf = nano_buf[:maxNanoSecondIntSize] + } + nanoseconds, err = strconv.ParseInt(string(nano_buf), 10, 0) + if err != nil { + return time.Time{}, err + } + } + ts := time.Unix(seconds, nanoseconds) + return ts, nil +} + +// parsePAX parses PAX headers. +// If an extended header (type 'x') is invalid, ErrHeader is returned +func parsePAX(r io.Reader) (map[string]string, error) { + buf, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + headers := make(map[string]string) + // Each record is constructed as + // "%d %s=%s\n", length, keyword, value + for len(buf) > 0 { + // or the header was empty to start with. + var sp int + // The size field ends at the first space. + sp = bytes.IndexByte(buf, ' ') + if sp == -1 { + return nil, ErrHeader + } + // Parse the first token as a decimal integer. + n, err := strconv.ParseInt(string(buf[:sp]), 10, 0) + if err != nil { + return nil, ErrHeader + } + // Extract everything between the decimal and the n -1 on the + // beginning to to eat the ' ', -1 on the end to skip the newline. + var record []byte + record, buf = buf[sp+1:n-1], buf[n:] + // The first equals is guaranteed to mark the end of the key. + // Everything else is value. + eq := bytes.IndexByte(record, '=') + if eq == -1 { + return nil, ErrHeader + } + key, value := record[:eq], record[eq+1:] + headers[string(key)] = string(value) + } + return headers, nil +} + +// cString parses bytes as a NUL-terminated C-style string. // If a NUL byte is not found then the whole slice is returned as a string. func cString(b []byte) string { n := 0 @@ -99,7 +258,7 @@ return int64(x) } -// Skip any unread bytes in the existing file entry, as well as any alignment padding. +// skipUnread skips any unread bytes in the existing file entry, as well as any alignment padding. func (tr *Reader) skipUnread() { nr := tr.nb + tr.pad // number of bytes to skip tr.nb, tr.pad = 0, 0 diff -Naur gcc-4.8.1.orig/libgo/go/archive/tar/reader_test.go gcc-4.8.1/libgo/go/archive/tar/reader_test.go --- gcc-4.8.1.orig/libgo/go/archive/tar/reader_test.go 2012-02-01 13:26:59.000000000 -0600 +++ gcc-4.8.1/libgo/go/archive/tar/reader_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -10,6 +10,8 @@ "fmt" "io" "os" + "reflect" + "strings" "testing" "time" ) @@ -108,6 +110,38 @@ }, }, }, + { + file: "testdata/pax.tar", + headers: []*Header{ + { + Name: "a/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", + Mode: 0664, + Uid: 1000, + Gid: 1000, + Uname: "shane", + Gname: "shane", + Size: 7, + ModTime: time.Unix(1350244992, 23960108), + ChangeTime: time.Unix(1350244992, 23960108), + AccessTime: time.Unix(1350244992, 23960108), + Typeflag: TypeReg, + }, + { + Name: "a/b", + Mode: 0777, + Uid: 1000, + Gid: 1000, + Uname: "shane", + Gname: "shane", + Size: 0, + ModTime: time.Unix(1350266320, 910238425), + ChangeTime: time.Unix(1350266320, 910238425), + AccessTime: time.Unix(1350266320, 910238425), + Typeflag: TypeSymlink, + Linkname: "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", + }, + }, + }, } func TestReader(t *testing.T) { @@ -133,7 +167,7 @@ } hdr, err := tr.Next() if err == io.EOF { - break + continue testLoop } if hdr != nil || err != nil { t.Errorf("test %d: Unexpected entry or error: hdr=%v err=%v", i, hdr, err) @@ -260,3 +294,73 @@ t.Errorf("Didn't process all files\nexpected: %d\nprocessed %d\n", len(test.headers), nread) } } + +func TestParsePAXHeader(t *testing.T) { + paxTests := [][3]string{ + {"a", "a=name", "10 a=name\n"}, // Test case involving multiple acceptable lengths + {"a", "a=name", "9 a=name\n"}, // Test case involving multiple acceptable length + {"mtime", "mtime=1350244992.023960108", "30 mtime=1350244992.023960108\n"}} + for _, test := range paxTests { + key, expected, raw := test[0], test[1], test[2] + reader := bytes.NewBuffer([]byte(raw)) + headers, err := parsePAX(reader) + if err != nil { + t.Errorf("Couldn't parse correctly formatted headers: %v", err) + continue + } + if strings.EqualFold(headers[key], expected) { + t.Errorf("mtime header incorrectly parsed: got %s, wanted %s", headers[key], expected) + continue + } + trailer := make([]byte, 100) + n, err := reader.Read(trailer) + if err != io.EOF || n != 0 { + t.Error("Buffer wasn't consumed") + } + } + badHeader := bytes.NewBuffer([]byte("3 somelongkey=")) + if _, err := parsePAX(badHeader); err != ErrHeader { + t.Fatal("Unexpected success when parsing bad header") + } +} + +func TestParsePAXTime(t *testing.T) { + // Some valid PAX time values + timestamps := map[string]time.Time{ + "1350244992.023960108": time.Unix(1350244992, 23960108), // The commoon case + "1350244992.02396010": time.Unix(1350244992, 23960100), // Lower precision value + "1350244992.0239601089": time.Unix(1350244992, 23960108), // Higher precision value + "1350244992": time.Unix(1350244992, 0), // Low precision value + } + for input, expected := range timestamps { + ts, err := parsePAXTime(input) + if err != nil { + t.Fatal(err) + } + if !ts.Equal(expected) { + t.Fatalf("Time parsing failure %s %s", ts, expected) + } + } +} + +func TestMergePAX(t *testing.T) { + hdr := new(Header) + // Test a string, integer, and time based value. + headers := map[string]string{ + "path": "a/b/c", + "uid": "1000", + "mtime": "1350244992.023960108", + } + err := mergePAX(hdr, headers) + if err != nil { + t.Fatal(err) + } + want := &Header{ + Name: "a/b/c", + Uid: 1000, + ModTime: time.Unix(1350244992, 23960108), + } + if !reflect.DeepEqual(hdr, want) { + t.Errorf("incorrect merge: got %+v, want %+v", hdr, want) + } +} diff -Naur gcc-4.8.1.orig/libgo/go/archive/tar/tar_test.go gcc-4.8.1/libgo/go/archive/tar/tar_test.go --- gcc-4.8.1.orig/libgo/go/archive/tar/tar_test.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/archive/tar/tar_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -14,13 +14,13 @@ ) func TestFileInfoHeader(t *testing.T) { - fi, err := os.Lstat("testdata/small.txt") + fi, err := os.Stat("testdata/small.txt") if err != nil { t.Fatal(err) } h, err := FileInfoHeader(fi, "") if err != nil { - t.Fatalf("on small.txt: %v", err) + t.Fatalf("FileInfoHeader: %v", err) } if g, e := h.Name, "small.txt"; g != e { t.Errorf("Name = %q; want %q", g, e) @@ -36,6 +36,30 @@ } } +func TestFileInfoHeaderDir(t *testing.T) { + fi, err := os.Stat("testdata") + if err != nil { + t.Fatal(err) + } + h, err := FileInfoHeader(fi, "") + if err != nil { + t.Fatalf("FileInfoHeader: %v", err) + } + if g, e := h.Name, "testdata/"; g != e { + t.Errorf("Name = %q; want %q", g, e) + } + // Ignoring c_ISGID for golang.org/issue/4867 + if g, e := h.Mode&^c_ISGID, int64(fi.Mode().Perm())|c_ISDIR; g != e { + t.Errorf("Mode = %#o; want %#o", g, e) + } + if g, e := h.Size, int64(0); g != e { + t.Errorf("Size = %v; want %v", g, e) + } + if g, e := h.ModTime, fi.ModTime(); !g.Equal(e) { + t.Errorf("ModTime = %v; want %v", g, e) + } +} + func TestFileInfoHeaderSymlink(t *testing.T) { h, err := FileInfoHeader(symlink{}, "some-target") if err != nil { @@ -98,3 +122,150 @@ t.Errorf("Data mismatch.\n got %q\nwant %q", rData, data) } } + +type headerRoundTripTest struct { + h *Header + fm os.FileMode +} + +func TestHeaderRoundTrip(t *testing.T) { + golden := []headerRoundTripTest{ + // regular file. + { + h: &Header{ + Name: "test.txt", + Mode: 0644 | c_ISREG, + Size: 12, + ModTime: time.Unix(1360600916, 0), + Typeflag: TypeReg, + }, + fm: 0644, + }, + // hard link. + { + h: &Header{ + Name: "hard.txt", + Mode: 0644 | c_ISLNK, + Size: 0, + ModTime: time.Unix(1360600916, 0), + Typeflag: TypeLink, + }, + fm: 0644 | os.ModeSymlink, + }, + // symbolic link. + { + h: &Header{ + Name: "link.txt", + Mode: 0777 | c_ISLNK, + Size: 0, + ModTime: time.Unix(1360600852, 0), + Typeflag: TypeSymlink, + }, + fm: 0777 | os.ModeSymlink, + }, + // character device node. + { + h: &Header{ + Name: "dev/null", + Mode: 0666 | c_ISCHR, + Size: 0, + ModTime: time.Unix(1360578951, 0), + Typeflag: TypeChar, + }, + fm: 0666 | os.ModeDevice | os.ModeCharDevice, + }, + // block device node. + { + h: &Header{ + Name: "dev/sda", + Mode: 0660 | c_ISBLK, + Size: 0, + ModTime: time.Unix(1360578954, 0), + Typeflag: TypeBlock, + }, + fm: 0660 | os.ModeDevice, + }, + // directory. + { + h: &Header{ + Name: "dir/", + Mode: 0755 | c_ISDIR, + Size: 0, + ModTime: time.Unix(1360601116, 0), + Typeflag: TypeDir, + }, + fm: 0755 | os.ModeDir, + }, + // fifo node. + { + h: &Header{ + Name: "dev/initctl", + Mode: 0600 | c_ISFIFO, + Size: 0, + ModTime: time.Unix(1360578949, 0), + Typeflag: TypeFifo, + }, + fm: 0600 | os.ModeNamedPipe, + }, + // setuid. + { + h: &Header{ + Name: "bin/su", + Mode: 0755 | c_ISREG | c_ISUID, + Size: 23232, + ModTime: time.Unix(1355405093, 0), + Typeflag: TypeReg, + }, + fm: 0755 | os.ModeSetuid, + }, + // setguid. + { + h: &Header{ + Name: "group.txt", + Mode: 0750 | c_ISREG | c_ISGID, + Size: 0, + ModTime: time.Unix(1360602346, 0), + Typeflag: TypeReg, + }, + fm: 0750 | os.ModeSetgid, + }, + // sticky. + { + h: &Header{ + Name: "sticky.txt", + Mode: 0600 | c_ISREG | c_ISVTX, + Size: 7, + ModTime: time.Unix(1360602540, 0), + Typeflag: TypeReg, + }, + fm: 0600 | os.ModeSticky, + }, + } + + for i, g := range golden { + fi := g.h.FileInfo() + h2, err := FileInfoHeader(fi, "") + if err != nil { + t.Error(err) + continue + } + if got, want := h2.Name, g.h.Name; got != want { + t.Errorf("i=%d: Name: got %v, want %v", i, got, want) + } + if got, want := h2.Size, g.h.Size; got != want { + t.Errorf("i=%d: Size: got %v, want %v", i, got, want) + } + if got, want := h2.Mode, g.h.Mode; got != want { + t.Errorf("i=%d: Mode: got %o, want %o", i, got, want) + } + if got, want := fi.Mode(), g.fm; got != want { + t.Errorf("i=%d: fi.Mode: got %o, want %o", i, got, want) + } + if got, want := h2.ModTime, g.h.ModTime; got != want { + t.Errorf("i=%d: ModTime: got %v, want %v", i, got, want) + } + if sysh, ok := fi.Sys().(*Header); !ok || sysh != g.h { + t.Errorf("i=%d: Sys didn't return original *Header", i) + } + } +} diff -Naur gcc-4.8.1.orig/libgo/go/archive/tar/testdata/pax.tar gcc-4.8.1/libgo/go/archive/tar/testdata/pax.tar --- gcc-4.8.1.orig/libgo/go/archive/tar/testdata/pax.tar 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/archive/tar/testdata/pax.tar 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,10 @@ +a/PaxHeaders.6887/12345678910111213141516171819202122232425262728293031323334353637383940414243444540000644000175000017500000000044612036615200022461 xustar0000000000000000204 path=a/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 +30 mtime=1350244992.023960108 +30 atime=1350244992.023960108 +30 ctime=1350244992.023960108 +a/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525350000664000175000017500000000000712036615200023454 0ustar00shaneshane00000000000000shaner +a/PaxHeaders.6887/b0000644000175000017500000000045012036666720012440 xustar0000000000000000206 linkpath=123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 +30 mtime=1350266320.910238425 +30 atime=1350266320.910238425 +30 ctime=1350266320.910238425 +a/b0000777000175000017500000000000012036666720024004 21234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545ustar00shaneshane00000000000000 \ No newline at end of file diff -Naur gcc-4.8.1.orig/libgo/go/archive/tar/testdata/ustar.tar gcc-4.8.1/libgo/go/archive/tar/testdata/ustar.tar --- gcc-4.8.1.orig/libgo/go/archive/tar/testdata/ustar.tar 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/archive/tar/testdata/ustar.tar 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,2 @@ +file.txt0000644000076500000240000000000612104402656045134 0ustar00shanestaff00000000000000longname/longname/longname/longname/longname/longname/longname/longname/longname/longname/longname/longname/longname/longname/longnamehello + \ No newline at end of file diff -Naur gcc-4.8.1.orig/libgo/go/archive/tar/writer.go gcc-4.8.1/libgo/go/archive/tar/writer.go --- gcc-4.8.1.orig/libgo/go/archive/tar/writer.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/archive/tar/writer.go 2013-07-16 01:55:04.520470000 -0500 @@ -8,10 +8,14 @@ // - catch more errors (no first header, etc.) import ( + "bytes" "errors" "fmt" "io" + "os" + "path" "strconv" + "strings" "time" ) @@ -19,23 +23,13 @@ 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") + errNameTooLong = errors.New("archive/tar: name too long") ) // A Writer provides sequential writing of a tar archive in POSIX.1 format. // A tar archive consists of a sequence of files. // Call WriteHeader to begin a new file, and then call Write to supply that file's data, // writing at most hdr.Size bytes in total. -// -// Example: -// tw := tar.NewWriter(w) -// hdr := new(tar.Header) -// hdr.Size = length of data in bytes -// // populate other hdr fields as desired -// if err := tw.WriteHeader(hdr); err != nil { -// // handle error -// } -// io.Copy(tw, data) -// tw.Close() type Writer struct { w io.Writer err error @@ -130,15 +124,31 @@ if tw.err != nil { return tw.err } - + // Decide whether or not to use PAX extensions + // TODO(shanemhansen): we might want to use PAX headers for + // subsecond time resolution, but for now let's just capture + // the long name/long symlink use case. + suffix := hdr.Name + prefix := "" + if len(hdr.Name) > fileNameSize || len(hdr.Linkname) > fileNameSize { + var err error + prefix, suffix, err = tw.splitUSTARLongName(hdr.Name) + // Either we were unable to pack the long name into ustar format + // or the link name is too long; use PAX headers. + if err == errNameTooLong || len(hdr.Linkname) > fileNameSize { + if err := tw.writePAXHeader(hdr); err != nil { + return err + } + } else if err != nil { + return err + } + } tw.nb = int64(hdr.Size) tw.pad = -tw.nb & (blockSize - 1) // blockSize is a power of two header := make([]byte, blockSize) s := slicer(header) - - // TODO(dsymonds): handle names longer than 100 chars - copy(s.next(100), []byte(hdr.Name)) + tw.cString(s.next(fileNameSize), suffix) // Handle out of range ModTime carefully. var modTime int64 @@ -159,11 +169,15 @@ tw.cString(s.next(32), hdr.Gname) // 297:329 tw.numeric(s.next(8), hdr.Devmajor) // 329:337 tw.numeric(s.next(8), hdr.Devminor) // 337:345 - + tw.cString(s.next(155), prefix) // 345:500 // Use the GNU magic instead of POSIX magic if we used any GNU extensions. if tw.usedBinary { copy(header[257:265], []byte("ustar \x00")) } + // Use the ustar magic if we used ustar long names. + if len(prefix) > 0 { + copy(header[257:265], []byte("ustar\000")) + } // The chksum field is terminated by a NUL and a space. // This is different from the other octal fields. @@ -181,6 +195,78 @@ return tw.err } +// writeUSTARLongName splits a USTAR long name hdr.Name. +// name must be < 256 characters. errNameTooLong is returned +// if hdr.Name can't be split. The splitting heuristic +// is compatible with gnu tar. +func (tw *Writer) splitUSTARLongName(name string) (prefix, suffix string, err error) { + length := len(name) + if length > fileNamePrefixSize+1 { + length = fileNamePrefixSize + 1 + } else if name[length-1] == '/' { + length-- + } + i := strings.LastIndex(name[:length], "/") + nlen := length - i - 1 + if i <= 0 || nlen > fileNameSize || nlen == 0 { + err = errNameTooLong + return + } + prefix, suffix = name[:i], name[i+1:] + return +} + +// writePaxHeader writes an extended pax header to the +// archive. +func (tw *Writer) writePAXHeader(hdr *Header) error { + // Prepare extended header + ext := new(Header) + ext.Typeflag = TypeXHeader + // Setting ModTime is required for reader parsing to + // succeed, and seems harmless enough. + ext.ModTime = hdr.ModTime + // The spec asks that we namespace our pseudo files + // with the current pid. + pid := os.Getpid() + dir, file := path.Split(hdr.Name) + ext.Name = path.Join(dir, + fmt.Sprintf("PaxHeaders.%d", pid), file)[0:100] + // Construct the body + var buf bytes.Buffer + if len(hdr.Name) > fileNameSize { + fmt.Fprint(&buf, paxHeader("path="+hdr.Name)) + } + if len(hdr.Linkname) > fileNameSize { + fmt.Fprint(&buf, paxHeader("linkpath="+hdr.Linkname)) + } + ext.Size = int64(len(buf.Bytes())) + if err := tw.WriteHeader(ext); err != nil { + return err + } + if _, err := tw.Write(buf.Bytes()); err != nil { + return err + } + if err := tw.Flush(); err != nil { + return err + } + return nil +} + +// paxHeader formats a single pax record, prefixing it with the appropriate length +func paxHeader(msg string) string { + const padding = 2 // Extra padding for space and newline + size := len(msg) + padding + size += len(strconv.Itoa(size)) + record := fmt.Sprintf("%d %s\n", size, msg) + if len(record) != size { + // Final adjustment if adding size increased + // the number of digits in size + size = len(record) + record = fmt.Sprintf("%d %s\n", size, msg) + } + return record +} + // Write writes to the current entry in the tar archive. // Write returns the error ErrWriteTooLong if more than // hdr.Size bytes are written after WriteHeader. diff -Naur gcc-4.8.1.orig/libgo/go/archive/tar/writer_test.go gcc-4.8.1/libgo/go/archive/tar/writer_test.go --- gcc-4.8.1.orig/libgo/go/archive/tar/writer_test.go 2012-03-30 16:27:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/archive/tar/writer_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -9,6 +9,7 @@ "fmt" "io" "io/ioutil" + "os" "strings" "testing" "testing/iotest" @@ -101,6 +102,27 @@ }, }, }, + // This file was produced using gnu tar 1.17 + // gnutar -b 4 --format=ustar (longname/)*15 + file.txt + { + file: "testdata/ustar.tar", + entries: []*writerTestEntry{ + { + header: &Header{ + Name: strings.Repeat("longname/", 15) + "file.txt", + Mode: 0644, + Uid: 0765, + Gid: 024, + Size: 06, + ModTime: time.Unix(1360135598, 0), + Typeflag: '0', + Uname: "shane", + Gname: "staff", + }, + contents: "hello\n", + }, + }, + }, } // Render byte array in a two-character hexadecimal string, spaced for easy visual inspection. @@ -180,3 +202,61 @@ } } } + +func TestPax(t *testing.T) { + // Create an archive with a large name + fileinfo, err := os.Stat("testdata/small.txt") + if err != nil { + t.Fatal(err) + } + hdr, err := FileInfoHeader(fileinfo, "") + if err != nil { + t.Fatalf("os.Stat: %v", err) + } + // Force a PAX long name to be written + longName := strings.Repeat("ab", 100) + contents := strings.Repeat(" ", int(hdr.Size)) + hdr.Name = longName + var buf bytes.Buffer + writer := NewWriter(&buf) + if err := writer.WriteHeader(hdr); err != nil { + t.Fatal(err) + } + if _, err = writer.Write([]byte(contents)); err != nil { + t.Fatal(err) + } + if err := writer.Close(); err != nil { + t.Fatal(err) + } + // Simple test to make sure PAX extensions are in effect + if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) { + t.Fatal("Expected at least one PAX header to be written.") + } + // Test that we can get a long name back out of the archive. + reader := NewReader(&buf) + hdr, err = reader.Next() + if err != nil { + t.Fatal(err) + } + if hdr.Name != longName { + t.Fatal("Couldn't recover long file name") + } +} + +func TestPAXHeader(t *testing.T) { + medName := strings.Repeat("CD", 50) + longName := strings.Repeat("AB", 100) + paxTests := [][2]string{ + {"name=/etc/hosts", "19 name=/etc/hosts\n"}, + {"a=b", "6 a=b\n"}, // Single digit length + {"a=names", "11 a=names\n"}, // Test case involving carries + {"name=" + longName, fmt.Sprintf("210 name=%s\n", longName)}, + {"name=" + medName, fmt.Sprintf("110 name=%s\n", medName)}} + + for _, test := range paxTests { + key, expected := test[0], test[1] + if result := paxHeader(key); result != expected { + t.Fatalf("paxHeader: got %s, expected %s", result, expected) + } + } +} diff -Naur gcc-4.8.1.orig/libgo/go/archive/zip/reader.go gcc-4.8.1/libgo/go/archive/zip/reader.go --- gcc-4.8.1.orig/libgo/go/archive/zip/reader.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/archive/zip/reader.go 2013-07-16 01:55:04.520470000 -0500 @@ -353,6 +353,11 @@ if err != nil { return nil, err } + + // Make sure directoryOffset points to somewhere in our file. + if o := int64(d.directoryOffset); o < 0 || o >= size { + return nil, ErrFormat + } return d, nil } @@ -407,7 +412,7 @@ if b[i] == 'P' && b[i+1] == 'K' && b[i+2] == 0x05 && b[i+3] == 0x06 { // n is length of comment n := int(b[i+directoryEndLen-2]) | int(b[i+directoryEndLen-1])<<8 - if n+directoryEndLen+i == len(b) { + if n+directoryEndLen+i <= len(b) { return i } } diff -Naur gcc-4.8.1.orig/libgo/go/archive/zip/reader_test.go gcc-4.8.1/libgo/go/archive/zip/reader_test.go --- gcc-4.8.1.orig/libgo/go/archive/zip/reader_test.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/archive/zip/reader_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -64,6 +64,24 @@ }, }, { + Name: "test-trailing-junk.zip", + Comment: "This is a zipfile comment.", + File: []ZipTestFile{ + { + Name: "test.txt", + Content: []byte("This is a test text file.\n"), + Mtime: "09-05-10 12:12:02", + Mode: 0644, + }, + { + Name: "gophercolor16x16.png", + File: "gophercolor16x16.png", + Mtime: "09-05-10 15:52:58", + Mode: 0644, + }, + }, + }, + { Name: "r.zip", Source: returnRecursiveZip, File: []ZipTestFile{ @@ -262,7 +280,7 @@ } } if err != zt.Error { - t.Errorf("error=%v, want %v", err, zt.Error) + t.Errorf("%s: error=%v, want %v", zt.Name, err, zt.Error) return } diff -Naur gcc-4.8.1.orig/libgo/go/archive/zip/struct.go gcc-4.8.1/libgo/go/archive/zip/struct.go --- gcc-4.8.1.orig/libgo/go/archive/zip/struct.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/archive/zip/struct.go 2013-07-16 01:55:04.520470000 -0500 @@ -64,8 +64,15 @@ zip64ExtraId = 0x0001 // zip64 Extended Information Extra Field ) +// FileHeader describes a file within a zip file. +// See the zip spec for details. type FileHeader struct { - Name string + // Name is the name of the file. + // It must be a relative path: it must not start with a drive + // letter (e.g. C:) or leading slash, and only forward slashes + // are allowed. + Name string + CreatorVersion uint16 ReaderVersion uint16 Flags uint16 diff -Naur gcc-4.8.1.orig/libgo/go/archive/zip/testdata/test-trailing-junk.zip gcc-4.8.1/libgo/go/archive/zip/testdata/test-trailing-junk.zip --- gcc-4.8.1.orig/libgo/go/archive/zip/testdata/test-trailing-junk.zip 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/archive/zip/testdata/test-trailing-junk.zip 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,10 @@ +PKa%=À×íÃtest.txtUT qü‚Lvü‚Lux õ ÉÈ,V¢D…’Ôâ QQ¢–™“ªÇPK +~%=þ1ÕTgophercolor16x16.pngUT :0ƒL;0ƒLux õ‰PNG + + IHDRísO/gAMAÖØÔOX2tEXtSoftwareAdobe ImageReadyqÉe<£IDATxÚt“_HSQÀ¿{ÏîÆu[VÚ*%mlQVô_#·""°zˆAK +£‚bE/¡ƒzI*†5ÿd˜¢‘.œ/S’Â鶆(Ú]¶í^uÙŸÓ9›­òƒïž{¿?¿ó}ß9—ÁC¦Øív°Ùl—Ï:z#¯ÐX”äeßÄ—e%‡œVWáv»½™ñŠÌ––Vôº½Íáh¨½d4à¸åÜo°Ci‘¤ólþ&–`h555^ŠÀðà@gó §Åë@ü:æ³U âÄŽƒ‚ÁpûQWÝVöÆX,J6kI(€e™cºuwoVaY +aÏè'|äÐ^|¢l'~ÓT'\Ï°oȉ/ZN +ëó6°f³9™G5Ù‚&‡/+Ño1í0ÁȇV¤„ÊŠÝŒªA£ÕB<‘€pdÎWV”3ó×74eµÀ0 GÞK¯^8ÓëŠ%aq Á´_ÝÚP©8`H€JÉ£sm=óR¨ŽØP”èØÛ÷CA9L°¤ïxŠ7æ&“R8 £’§Q‚,õý©€Íœè\P¾óÄÙ3É«”)*ù€wJaF‚h,ºü\ê +ü@DzÕå²ù¦E@(åŠÆâ°o{1˜v&ÃWàêÕ‹Ç]îÑñ%ZzzP,Ki [@Dç‚ ,û¯K¡@ðàÖM4 )Iúî›DVæ¯djcC0‚‘Z³æ415§'¤%gn««W{{yºG!²r + Gû¸µï×ÇQáåÁûg³*(//OW ŠbB’¤Ú§íýM‡÷äÎÎLø0x70Ü‹¯ººzÒjµfÿL‚ dV»Hô¹Ë3aûæð<ÿ »»û3±…ôz=½tY­ý`¨ ‹çbêIEND®B`‚PKa%=À×íätest.txtUTqü‚Lux õPK +~%=þ1ÕT¤[gophercolor16x16.pngUT:0ƒLux õPK¨ºThis is a zipfile comment.some nonsense diff -Naur gcc-4.8.1.orig/libgo/go/archive/zip/writer.go gcc-4.8.1/libgo/go/archive/zip/writer.go --- gcc-4.8.1.orig/libgo/go/archive/zip/writer.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/archive/zip/writer.go 2013-07-16 01:55:04.520470000 -0500 @@ -163,6 +163,9 @@ // Create adds a file to the zip file using the provided name. // It returns a Writer to which the file contents should be written. +// The name must be a relative path: it must not start with a drive +// letter (e.g. C:) or leading slash, and only forward slashes are +// allowed. // The file's contents must be written to the io.Writer before the next // call to Create, CreateHeader, or Close. func (w *Writer) Create(name string) (io.Writer, error) { diff -Naur gcc-4.8.1.orig/libgo/go/bufio/bufio.go gcc-4.8.1/libgo/go/bufio/bufio.go --- gcc-4.8.1.orig/libgo/go/bufio/bufio.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/bufio/bufio.go 2013-07-16 01:55:04.520470000 -0500 @@ -274,11 +274,10 @@ return b.buf, ErrBufferFull } } - panic("not reached") } // ReadLine is a low-level line-reading primitive. Most callers should use -// ReadBytes('\n') or ReadString('\n') instead. +// ReadBytes('\n') or ReadString('\n') instead or use a Scanner. // // ReadLine tries to return a single line, not including the end-of-line bytes. // If the line was too long for the buffer then isPrefix is set and the @@ -331,6 +330,7 @@ // it returns the data read before the error and the error itself (often io.EOF). // ReadBytes returns err != nil if and only if the returned data does not end in // delim. +// For simple uses, a Scanner may be more convenient. func (b *Reader) ReadBytes(delim byte) (line []byte, err error) { // Use ReadSlice to look for array, // accumulating full buffers. @@ -378,6 +378,7 @@ // it returns the data read before the error and the error itself (often io.EOF). // ReadString returns err != nil if and only if the returned data does not end in // delim. +// For simple uses, a Scanner may be more convenient. func (b *Reader) ReadString(delim byte) (line string, err error) { bytes, err := b.ReadBytes(delim) return string(bytes), err diff -Naur gcc-4.8.1.orig/libgo/go/bufio/bufio_test.go gcc-4.8.1/libgo/go/bufio/bufio_test.go --- gcc-4.8.1.orig/libgo/go/bufio/bufio_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/bufio/bufio_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -7,6 +7,7 @@ import ( . "bufio" "bytes" + "errors" "fmt" "io" "io/ioutil" @@ -434,9 +435,12 @@ t.Errorf("Write hello to %v: %v", w, e) continue } - e = buf.Flush() - if e != w.expect { - t.Errorf("Flush %v: got %v, wanted %v", w, e, w.expect) + // Two flushes, to verify the error is sticky. + for i := 0; i < 2; i++ { + e = buf.Flush() + if e != w.expect { + t.Errorf("Flush %d/2 %v: got %v, wanted %v", i+1, w, e, w.expect) + } } } } @@ -953,7 +957,7 @@ t.Fatal("read did not panic") case error: if !strings.Contains(err.Error(), "reader returned negative count from Read") { - t.Fatal("wrong panic: %v", err) + t.Fatalf("wrong panic: %v", err) } default: t.Fatalf("unexpected panic value: %T(%v)", err, err) @@ -962,6 +966,43 @@ b.Read(make([]byte, 100)) } +var errFake = errors.New("fake error") + +type errorThenGoodReader struct { + didErr bool + nread int +} + +func (r *errorThenGoodReader) Read(p []byte) (int, error) { + r.nread++ + if !r.didErr { + r.didErr = true + return 0, errFake + } + return len(p), nil +} + +func TestReaderClearError(t *testing.T) { + r := &errorThenGoodReader{} + b := NewReader(r) + buf := make([]byte, 1) + if _, err := b.Read(nil); err != nil { + t.Fatalf("1st nil Read = %v; want nil", err) + } + if _, err := b.Read(buf); err != errFake { + t.Fatalf("1st Read = %v; want errFake", err) + } + if _, err := b.Read(nil); err != nil { + t.Fatalf("2nd nil Read = %v; want nil", err) + } + if _, err := b.Read(buf); err != nil { + t.Fatalf("3rd Read with buffer = %v; want nil", err) + } + if r.nread != 2 { + t.Errorf("num reads = %d; want 2", r.nread) + } +} + // An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have. type onlyReader struct { r io.Reader diff -Naur gcc-4.8.1.orig/libgo/go/bufio/example_test.go gcc-4.8.1/libgo/go/bufio/example_test.go --- gcc-4.8.1.orig/libgo/go/bufio/example_test.go 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/bufio/example_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,74 @@ +// Copyright 2013 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 bufio_test + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +// The simplest use of a Scanner, to read standard input as a set of lines. +func ExampleScanner_lines() { + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + fmt.Println(scanner.Text()) // Println will add back the final '\n' + } + if err := scanner.Err(); err != nil { + fmt.Fprintln(os.Stderr, "reading standard input:", err) + } +} + +// Use a Scanner to implement a simple word-count utility by scanning the +// input as a sequence of space-delimited tokens. +func ExampleScanner_words() { + // An artificial input source. + const input = "Now is the winter of our discontent,\nMade glorious summer by this sun of York.\n" + scanner := bufio.NewScanner(strings.NewReader(input)) + // Set the split function for the scanning operation. + scanner.Split(bufio.ScanWords) + // Count the words. + count := 0 + for scanner.Scan() { + count++ + } + if err := scanner.Err(); err != nil { + fmt.Fprintln(os.Stderr, "reading input:", err) + } + fmt.Printf("%d\n", count) + // Output: 15 +} + +// Use a Scanner with a custom split function (built by wrapping ScanWords) to validate +// 32-bit decimal input. +func ExampleScanner_custom() { + // An artificial input source. + const input = "1234 5678 1234567901234567890" + scanner := bufio.NewScanner(strings.NewReader(input)) + // Create a custom split function by wrapping the existing ScanWords function. + split := func(data []byte, atEOF bool) (advance int, token []byte, err error) { + advance, token, err = bufio.ScanWords(data, atEOF) + if err == nil && token != nil { + _, err = strconv.ParseInt(string(token), 10, 32) + } + return + } + // Set the split function for the scanning operation. + scanner.Split(split) + // Validate the input + for scanner.Scan() { + fmt.Printf("%s\n", scanner.Text()) + } + + if err := scanner.Err(); err != nil { + fmt.Printf("Invalid input: %s", err) + } + // Output: + // 1234 + // 5678 + // Invalid input: strconv.ParseInt: parsing "1234567901234567890": value out of range +} diff -Naur gcc-4.8.1.orig/libgo/go/bufio/export_test.go gcc-4.8.1/libgo/go/bufio/export_test.go --- gcc-4.8.1.orig/libgo/go/bufio/export_test.go 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/bufio/export_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,27 @@ +// Copyright 2013 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 bufio + +// Exported for testing only. +import ( + "unicode/utf8" +) + +var IsSpace = isSpace + +func (s *Scanner) MaxTokenSize(n int) { + if n < utf8.UTFMax || n > 1e9 { + panic("bad max token size") + } + if n < len(s.buf) { + s.buf = make([]byte, n) + } + s.maxTokenSize = n +} + +// ErrOrEOF is like Err, but returns EOF. Used to test a corner case. +func (s *Scanner) ErrOrEOF() error { + return s.err +} diff -Naur gcc-4.8.1.orig/libgo/go/bufio/scan.go gcc-4.8.1/libgo/go/bufio/scan.go --- gcc-4.8.1.orig/libgo/go/bufio/scan.go 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/bufio/scan.go 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,346 @@ +// Copyright 2013 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 bufio + +import ( + "bytes" + "errors" + "io" + "unicode/utf8" +) + +// Scanner provides a convenient interface for reading data such as +// a file of newline-delimited lines of text. Successive calls to +// the Scan method will step through the 'tokens' of a file, skipping +// the bytes between the tokens. The specification of a token is +// defined by a split function of type SplitFunc; the default split +// function breaks the input into lines with line termination stripped. Split +// functions are defined in this package for scanning a file into +// lines, bytes, UTF-8-encoded runes, and space-delimited words. The +// client may instead provide a custom split function. +// +// Scanning stops unrecoverably at EOF, the first I/O error, or a token too +// large to fit in the buffer. When a scan stops, the reader may have +// advanced arbitrarily far past the last token. Programs that need more +// control over error handling or large tokens, or must run sequential scans +// on a reader, should use bufio.Reader instead. +// +type Scanner struct { + r io.Reader // The reader provided by the client. + split SplitFunc // The function to split the tokens. + maxTokenSize int // Maximum size of a token; modified by tests. + token []byte // Last token returned by split. + buf []byte // Buffer used as argument to split. + start int // First non-processed byte in buf. + end int // End of data in buf. + err error // Sticky error. +} + +// SplitFunc is the signature of the split function used to tokenize the +// input. The arguments are an initial substring of the remaining unprocessed +// data and a flag, atEOF, that reports whether the Reader has no more data +// to give. The return values are the number of bytes to advance the input +// and the next token to return to the user, plus an error, if any. If the +// data does not yet hold a complete token, for instance if it has no newline +// while scanning lines, SplitFunc can return (0, nil) to signal the Scanner +// to read more data into the slice and try again with a longer slice +// starting at the same point in the input. +// +// If the returned error is non-nil, scanning stops and the error +// is returned to the client. +// +// The function is never called with an empty data slice unless atEOF +// is true. If atEOF is true, however, data may be non-empty and, +// as always, holds unprocessed text. +type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error) + +// Errors returned by Scanner. +var ( + ErrTooLong = errors.New("bufio.Scanner: token too long") + ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count") + ErrAdvanceTooFar = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input") +) + +const ( + // Maximum size used to buffer a token. The actual maximum token size + // may be smaller as the buffer may need to include, for instance, a newline. + MaxScanTokenSize = 64 * 1024 +) + +// NewScanner returns a new Scanner to read from r. +// The split function defaults to ScanLines. +func NewScanner(r io.Reader) *Scanner { + return &Scanner{ + r: r, + split: ScanLines, + maxTokenSize: MaxScanTokenSize, + buf: make([]byte, 4096), // Plausible starting size; needn't be large. + } +} + +// Err returns the first non-EOF error that was encountered by the Scanner. +func (s *Scanner) Err() error { + if s.err == io.EOF { + return nil + } + return s.err +} + +// Bytes returns the most recent token generated by a call to Scan. +// The underlying array may point to data that will be overwritten +// by a subsequent call to Scan. It does no allocation. +func (s *Scanner) Bytes() []byte { + return s.token +} + +// Text returns the most recent token generated by a call to Scan +// as a newly allocated string holding its bytes. +func (s *Scanner) Text() string { + return string(s.token) +} + +// Scan advances the Scanner to the next token, which will then be +// available through the Bytes or Text method. It returns false when the +// scan stops, either by reaching the end of the input or an error. +// After Scan returns false, the Err method will return any error that +// occurred during scanning, except that if it was io.EOF, Err +// will return nil. +func (s *Scanner) Scan() bool { + // Loop until we have a token. + for { + // See if we can get a token with what we already have. + if s.end > s.start { + advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil) + if err != nil { + s.setErr(err) + return false + } + if !s.advance(advance) { + return false + } + s.token = token + if token != nil { + return true + } + } + // We cannot generate a token with what we are holding. + // If we've already hit EOF or an I/O error, we are done. + if s.err != nil { + // Shut it down. + s.start = 0 + s.end = 0 + return false + } + // Must read more data. + // First, shift data to beginning of buffer if there's lots of empty space + // or space is neded. + if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) { + copy(s.buf, s.buf[s.start:s.end]) + s.end -= s.start + s.start = 0 + } + // Is the buffer full? If so, resize. + if s.end == len(s.buf) { + if len(s.buf) >= s.maxTokenSize { + s.setErr(ErrTooLong) + return false + } + newSize := len(s.buf) * 2 + if newSize > s.maxTokenSize { + newSize = s.maxTokenSize + } + newBuf := make([]byte, newSize) + copy(newBuf, s.buf[s.start:s.end]) + s.buf = newBuf + s.end -= s.start + s.start = 0 + continue + } + // Finally we can read some input. Make sure we don't get stuck with + // a misbehaving Reader. Officially we don't need to do this, but let's + // be extra careful: Scanner is for safe, simple jobs. + for loop := 0; ; { + n, err := s.r.Read(s.buf[s.end:len(s.buf)]) + s.end += n + if err != nil { + s.setErr(err) + break + } + if n > 0 { + break + } + loop++ + if loop > 100 { + s.setErr(io.ErrNoProgress) + break + } + } + } +} + +// advance consumes n bytes of the buffer. It reports whether the advance was legal. +func (s *Scanner) advance(n int) bool { + if n < 0 { + s.setErr(ErrNegativeAdvance) + return false + } + if n > s.end-s.start { + s.setErr(ErrAdvanceTooFar) + return false + } + s.start += n + return true +} + +// setErr records the first error encountered. +func (s *Scanner) setErr(err error) { + if s.err == nil || s.err == io.EOF { + s.err = err + } +} + +// Split sets the split function for the Scanner. If called, it must be +// called before Scan. The default split function is ScanLines. +func (s *Scanner) Split(split SplitFunc) { + s.split = split +} + +// Split functions + +// ScanBytes is a split function for a Scanner that returns each byte as a token. +func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF && len(data) == 0 { + return 0, nil, nil + } + return 1, data[0:1], nil +} + +var errorRune = []byte(string(utf8.RuneError)) + +// ScanRunes is a split function for a Scanner that returns each +// UTF-8-encoded rune as a token. The sequence of runes returned is +// equivalent to that from a range loop over the input as a string, which +// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd". +// Because of the Scan interface, this makes it impossible for the client to +// distinguish correctly encoded replacement runes from encoding errors. +func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF && len(data) == 0 { + return 0, nil, nil + } + + // Fast path 1: ASCII. + if data[0] < utf8.RuneSelf { + return 1, data[0:1], nil + } + + // Fast path 2: Correct UTF-8 decode without error. + _, width := utf8.DecodeRune(data) + if width > 1 { + // It's a valid encoding. Width cannot be one for a correctly encoded + // non-ASCII rune. + return width, data[0:width], nil + } + + // We know it's an error: we have width==1 and implicitly r==utf8.RuneError. + // Is the error because there wasn't a full rune to be decoded? + // FullRune distinguishes correctly between erroneous and incomplete encodings. + if !atEOF && !utf8.FullRune(data) { + // Incomplete; get more bytes. + return 0, nil, nil + } + + // We have a real UTF-8 encoding error. Return a properly encoded error rune + // but advance only one byte. This matches the behavior of a range loop over + // an incorrectly encoded string. + return 1, errorRune, nil +} + +// dropCR drops a terminal \r from the data. +func dropCR(data []byte) []byte { + if len(data) > 0 && data[len(data)-1] == '\r' { + return data[0 : len(data)-1] + } + return data +} + +// ScanLines is a split function for a Scanner that returns each line of +// text, stripped of any trailing end-of-line marker. The returned line may +// be empty. The end-of-line marker is one optional carriage return followed +// by one mandatory newline. In regular expression notation, it is `\r?\n`. +// The last non-empty line of input will be returned even if it has no +// newline. +func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF && len(data) == 0 { + return 0, nil, nil + } + if i := bytes.IndexByte(data, '\n'); i >= 0 { + // We have a full newline-terminated line. + return i + 1, dropCR(data[0:i]), nil + } + // If we're at EOF, we have a final, non-terminated line. Return it. + if atEOF { + return len(data), dropCR(data), nil + } + // Request more data. + return 0, nil, nil +} + +// isSpace returns whether the character is a Unicode white space character. +// We avoid dependency on the unicode package, but check validity of the implementation +// in the tests. +func isSpace(r rune) bool { + if r <= '\u00FF' { + // Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs. + switch r { + case ' ', '\t', '\n', '\v', '\f', '\r': + return true + case '\u0085', '\u00A0': + return true + } + return false + } + // High-valued ones. + if '\u2000' <= r && r <= '\u200a' { + return true + } + switch r { + case '\u1680', '\u180e', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000': + return true + } + return false +} + +// ScanWords is a split function for a Scanner that returns each +// space-separated word of text, with surrounding spaces deleted. It will +// never return an empty string. The definition of space is set by +// unicode.IsSpace. +func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) { + // Skip leading spaces. + start := 0 + for width := 0; start < len(data); start += width { + var r rune + r, width = utf8.DecodeRune(data[start:]) + if !isSpace(r) { + break + } + } + if atEOF && len(data) == 0 { + return 0, nil, nil + } + // Scan until space, marking end of word. + for width, i := 0, start; i < len(data); i += width { + var r rune + r, width = utf8.DecodeRune(data[i:]) + if isSpace(r) { + return i + width, data[start:i], nil + } + } + // If we're at EOF, we have a final, non-empty, non-terminated word. Return it. + if atEOF && len(data) > start { + return len(data), data[start:], nil + } + // Request more data. + return 0, nil, nil +} diff -Naur gcc-4.8.1.orig/libgo/go/bufio/scan_test.go gcc-4.8.1/libgo/go/bufio/scan_test.go --- gcc-4.8.1.orig/libgo/go/bufio/scan_test.go 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/bufio/scan_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,406 @@ +// Copyright 2013 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 bufio_test + +import ( + . "bufio" + "bytes" + "errors" + "io" + "strings" + "testing" + "unicode" + "unicode/utf8" +) + +// Test white space table matches the Unicode definition. +func TestSpace(t *testing.T) { + for r := rune(0); r <= utf8.MaxRune; r++ { + if IsSpace(r) != unicode.IsSpace(r) { + t.Fatalf("white space property disagrees: %#U should be %t", r, unicode.IsSpace(r)) + } + } +} + +var scanTests = []string{ + "", + "a", + "¼", + "☹", + "\x81", // UTF-8 error + "\uFFFD", // correctly encoded RuneError + "abcdefgh", + "abc def\n\t\tgh ", + "abc¼☹\x81\uFFFD日本語\x82abc", +} + +func TestScanByte(t *testing.T) { + for n, test := range scanTests { + buf := bytes.NewBufferString(test) + s := NewScanner(buf) + s.Split(ScanBytes) + var i int + for i = 0; s.Scan(); i++ { + if b := s.Bytes(); len(b) != 1 || b[0] != test[i] { + t.Errorf("#%d: %d: expected %q got %q", n, i, test, b) + } + } + if i != len(test) { + t.Errorf("#%d: termination expected at %d; got %d", n, len(test), i) + } + err := s.Err() + if err != nil { + t.Errorf("#%d: %v", n, err) + } + } +} + +// Test that the rune splitter returns same sequence of runes (not bytes) as for range string. +func TestScanRune(t *testing.T) { + for n, test := range scanTests { + buf := bytes.NewBufferString(test) + s := NewScanner(buf) + s.Split(ScanRunes) + var i, runeCount int + var expect rune + // Use a string range loop to validate the sequence of runes. + for i, expect = range string(test) { + if !s.Scan() { + break + } + runeCount++ + got, _ := utf8.DecodeRune(s.Bytes()) + if got != expect { + t.Errorf("#%d: %d: expected %q got %q", n, i, expect, got) + } + } + if s.Scan() { + t.Errorf("#%d: scan ran too long, got %q", n, s.Text()) + } + testRuneCount := utf8.RuneCountInString(test) + if runeCount != testRuneCount { + t.Errorf("#%d: termination expected at %d; got %d", n, testRuneCount, runeCount) + } + err := s.Err() + if err != nil { + t.Errorf("#%d: %v", n, err) + } + } +} + +var wordScanTests = []string{ + "", + " ", + "\n", + "a", + " a ", + "abc def", + " abc def ", + " abc\tdef\nghi\rjkl\fmno\vpqr\u0085stu\u00a0\n", +} + +// Test that the word splitter returns the same data as strings.Fields. +func TestScanWords(t *testing.T) { + for n, test := range wordScanTests { + buf := bytes.NewBufferString(test) + s := NewScanner(buf) + s.Split(ScanWords) + words := strings.Fields(test) + var wordCount int + for wordCount = 0; wordCount < len(words); wordCount++ { + if !s.Scan() { + break + } + got := s.Text() + if got != words[wordCount] { + t.Errorf("#%d: %d: expected %q got %q", n, wordCount, words[wordCount], got) + } + } + if s.Scan() { + t.Errorf("#%d: scan ran too long, got %q", n, s.Text()) + } + if wordCount != len(words) { + t.Errorf("#%d: termination expected at %d; got %d", n, len(words), wordCount) + } + err := s.Err() + if err != nil { + t.Errorf("#%d: %v", n, err) + } + } +} + +// slowReader is a reader that returns only a few bytes at a time, to test the incremental +// reads in Scanner.Scan. +type slowReader struct { + max int + buf *bytes.Buffer +} + +func (sr *slowReader) Read(p []byte) (n int, err error) { + if len(p) > sr.max { + p = p[0:sr.max] + } + return sr.buf.Read(p) +} + +// genLine writes to buf a predictable but non-trivial line of text of length +// n, including the terminal newline and an occasional carriage return. +// If addNewline is false, the \r and \n are not emitted. +func genLine(buf *bytes.Buffer, lineNum, n int, addNewline bool) { + buf.Reset() + doCR := lineNum%5 == 0 + if doCR { + n-- + } + for i := 0; i < n-1; i++ { // Stop early for \n. + c := 'a' + byte(lineNum+i) + if c == '\n' || c == '\r' { // Don't confuse us. + c = 'N' + } + buf.WriteByte(c) + } + if addNewline { + if doCR { + buf.WriteByte('\r') + } + buf.WriteByte('\n') + } + return +} + +// Test the line splitter, including some carriage returns but no long lines. +func TestScanLongLines(t *testing.T) { + const smallMaxTokenSize = 256 // Much smaller for more efficient testing. + // Build a buffer of lots of line lengths up to but not exceeding smallMaxTokenSize. + tmp := new(bytes.Buffer) + buf := new(bytes.Buffer) + lineNum := 0 + j := 0 + for i := 0; i < 2*smallMaxTokenSize; i++ { + genLine(tmp, lineNum, j, true) + if j < smallMaxTokenSize { + j++ + } else { + j-- + } + buf.Write(tmp.Bytes()) + lineNum++ + } + s := NewScanner(&slowReader{1, buf}) + s.Split(ScanLines) + s.MaxTokenSize(smallMaxTokenSize) + j = 0 + for lineNum := 0; s.Scan(); lineNum++ { + genLine(tmp, lineNum, j, false) + if j < smallMaxTokenSize { + j++ + } else { + j-- + } + line := tmp.String() // We use the string-valued token here, for variety. + if s.Text() != line { + t.Errorf("%d: bad line: %d %d\n%.100q\n%.100q\n", lineNum, len(s.Bytes()), len(line), s.Text(), line) + } + } + err := s.Err() + if err != nil { + t.Fatal(err) + } +} + +// Test that the line splitter errors out on a long line. +func TestScanLineTooLong(t *testing.T) { + const smallMaxTokenSize = 256 // Much smaller for more efficient testing. + // Build a buffer of lots of line lengths up to but not exceeding smallMaxTokenSize. + tmp := new(bytes.Buffer) + buf := new(bytes.Buffer) + lineNum := 0 + j := 0 + for i := 0; i < 2*smallMaxTokenSize; i++ { + genLine(tmp, lineNum, j, true) + j++ + buf.Write(tmp.Bytes()) + lineNum++ + } + s := NewScanner(&slowReader{3, buf}) + s.Split(ScanLines) + s.MaxTokenSize(smallMaxTokenSize) + j = 0 + for lineNum := 0; s.Scan(); lineNum++ { + genLine(tmp, lineNum, j, false) + if j < smallMaxTokenSize { + j++ + } else { + j-- + } + line := tmp.Bytes() + if !bytes.Equal(s.Bytes(), line) { + t.Errorf("%d: bad line: %d %d\n%.100q\n%.100q\n", lineNum, len(s.Bytes()), len(line), s.Bytes(), line) + } + } + err := s.Err() + if err != ErrTooLong { + t.Fatalf("expected ErrTooLong; got %s", err) + } +} + +// Test that the line splitter handles a final line without a newline. +func testNoNewline(text string, lines []string, t *testing.T) { + buf := bytes.NewBufferString(text) + s := NewScanner(&slowReader{7, buf}) + s.Split(ScanLines) + for lineNum := 0; s.Scan(); lineNum++ { + line := lines[lineNum] + if s.Text() != line { + t.Errorf("%d: bad line: %d %d\n%.100q\n%.100q\n", lineNum, len(s.Bytes()), len(line), s.Bytes(), line) + } + } + err := s.Err() + if err != nil { + t.Fatal(err) + } +} + +var noNewlineLines = []string{ + "abcdefghijklmn\nopqrstuvwxyz", +} + +// Test that the line splitter handles a final line without a newline. +func TestScanLineNoNewline(t *testing.T) { + const text = "abcdefghijklmn\nopqrstuvwxyz" + lines := []string{ + "abcdefghijklmn", + "opqrstuvwxyz", + } + testNoNewline(text, lines, t) +} + +// Test that the line splitter handles a final line with a carriage return but nonewline. +func TestScanLineReturnButNoNewline(t *testing.T) { + const text = "abcdefghijklmn\nopqrstuvwxyz\r" + lines := []string{ + "abcdefghijklmn", + "opqrstuvwxyz", + } + testNoNewline(text, lines, t) +} + +// Test that the line splitter handles a final empty line. +func TestScanLineEmptyFinalLine(t *testing.T) { + const text = "abcdefghijklmn\nopqrstuvwxyz\n\n" + lines := []string{ + "abcdefghijklmn", + "opqrstuvwxyz", + "", + } + testNoNewline(text, lines, t) +} + +// Test that the line splitter handles a final empty line with a carriage return but no newline. +func TestScanLineEmptyFinalLineWithCR(t *testing.T) { + const text = "abcdefghijklmn\nopqrstuvwxyz\n\r" + lines := []string{ + "abcdefghijklmn", + "opqrstuvwxyz", + "", + } + testNoNewline(text, lines, t) +} + +var testError = errors.New("testError") + +// Test the correct error is returned when the split function errors out. +func TestSplitError(t *testing.T) { + // Create a split function that delivers a little data, then a predictable error. + numSplits := 0 + const okCount = 7 + errorSplit := func(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF { + panic("didn't get enough data") + } + if numSplits >= okCount { + return 0, nil, testError + } + numSplits++ + return 1, data[0:1], nil + } + // Read the data. + const text = "abcdefghijklmnopqrstuvwxyz" + buf := bytes.NewBufferString(text) + s := NewScanner(&slowReader{1, buf}) + s.Split(errorSplit) + var i int + for i = 0; s.Scan(); i++ { + if len(s.Bytes()) != 1 || text[i] != s.Bytes()[0] { + t.Errorf("#%d: expected %q got %q", i, text[i], s.Bytes()[0]) + } + } + // Check correct termination location and error. + if i != okCount { + t.Errorf("unexpected termination; expected %d tokens got %d", okCount, i) + } + err := s.Err() + if err != testError { + t.Fatalf("expected %q got %v", testError, err) + } +} + +// Test that an EOF is overridden by a user-generated scan error. +func TestErrAtEOF(t *testing.T) { + s := NewScanner(strings.NewReader("1 2 33")) + // This spitter will fail on last entry, after s.err==EOF. + split := func(data []byte, atEOF bool) (advance int, token []byte, err error) { + advance, token, err = ScanWords(data, atEOF) + if len(token) > 1 { + if s.ErrOrEOF() != io.EOF { + t.Fatal("not testing EOF") + } + err = testError + } + return + } + s.Split(split) + for s.Scan() { + } + if s.Err() != testError { + t.Fatal("wrong error:", s.Err()) + } +} + +// Test for issue 5268. +type alwaysError struct{} + +func (alwaysError) Read(p []byte) (int, error) { + return 0, io.ErrUnexpectedEOF +} + +func TestNonEOFWithEmptyRead(t *testing.T) { + scanner := NewScanner(alwaysError{}) + for scanner.Scan() { + t.Fatal("read should fail") + } + err := scanner.Err() + if err != io.ErrUnexpectedEOF { + t.Errorf("unexpected error: %v", err) + } +} + +// Test that Scan finishes if we have endless empty reads. +type endlessZeros struct{} + +func (endlessZeros) Read(p []byte) (int, error) { + return 0, nil +} + +func TestBadReader(t *testing.T) { + scanner := NewScanner(endlessZeros{}) + for scanner.Scan() { + t.Fatal("read should fail") + } + err := scanner.Err() + if err != io.ErrNoProgress { + t.Errorf("unexpected error: %v", err) + } +} diff -Naur gcc-4.8.1.orig/libgo/go/builtin/builtin.go gcc-4.8.1/libgo/go/builtin/builtin.go --- gcc-4.8.1.orig/libgo/go/builtin/builtin.go 2012-12-21 19:15:33.000000000 -0600 +++ gcc-4.8.1/libgo/go/builtin/builtin.go 2013-07-16 01:55:04.520470000 -0500 @@ -13,6 +13,12 @@ // bool is the set of boolean values, true and false. type bool bool +// true and false are the two untyped boolean values. +const ( + true = 0 == 0 // Untyped bool. + false = 0 != 0 // Untyped bool. +) + // uint8 is the set of all unsigned 8-bit integers. // Range: 0 through 255. type uint8 uint8 @@ -85,6 +91,15 @@ // used, by convention, to distinguish character values from integer values. type rune rune +// iota is a predeclared identifier representing the untyped integer ordinal +// number of the current const specification in a (usually parenthesized) +// const declaration. It is zero-indexed. +const iota = 0 // Untyped int. + +// nil is a predeclared identifier representing the zero value for a +// pointer, channel, func, interface, map, or slice type. +var nil Type // Type must be a pointer, channel, func, interface, map, or slice type + // Type is here for the purposes of documentation only. It is a stand-in // for any Go type, but represents the same type for any given function // invocation. @@ -114,6 +129,8 @@ // result of append, often in the variable holding the slice itself: // slice = append(slice, elem1, elem2) // slice = append(slice, anotherSlice...) +// As a special case, it is legal to append a string to a byte slice, like this: +// slice = append([]byte("hello "), "world"...) func append(slice []Type, elems ...Type) []Type // The copy built-in function copies elements from a source slice into a diff -Naur gcc-4.8.1.orig/libgo/go/bytes/buffer.go gcc-4.8.1/libgo/go/bytes/buffer.go --- gcc-4.8.1.orig/libgo/go/bytes/buffer.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/bytes/buffer.go 2013-07-16 01:55:04.520470000 -0500 @@ -87,6 +87,13 @@ var buf []byte if b.buf == nil && n <= len(b.bootstrap) { buf = b.bootstrap[0:] + } else if m+n <= cap(b.buf)/2 { + // We can slide things down instead of allocating a new + // slice. We only need m+n <= cap(b.buf) to slide, but + // we instead let capacity get twice as large so we + // don't spend all our time copying. + copy(b.buf[:], b.buf[b.off:]) + buf = b.buf[:m] } else { // not enough space anywhere buf = makeSlice(2*cap(b.buf) + n) @@ -112,20 +119,18 @@ b.buf = b.buf[0:m] } -// Write appends the contents of p to the buffer. The return -// value n is the length of p; err is always nil. -// If the buffer becomes too large, Write will panic with -// ErrTooLarge. +// Write appends the contents of p to the buffer, growing the buffer as +// needed. The return value n is the length of p; err is always nil. If the +// buffer becomes too large, Write will panic with ErrTooLarge. func (b *Buffer) Write(p []byte) (n int, err error) { b.lastRead = opInvalid m := b.grow(len(p)) return copy(b.buf[m:], p), nil } -// WriteString appends the contents of s to the buffer. The return -// value n is the length of s; err is always nil. -// If the buffer becomes too large, WriteString will panic with -// ErrTooLarge. +// WriteString appends the contents of s to the buffer, growing the buffer as +// needed. The return value n is the length of s; err is always nil. If the +// buffer becomes too large, WriteString will panic with ErrTooLarge. func (b *Buffer) WriteString(s string) (n int, err error) { b.lastRead = opInvalid m := b.grow(len(s)) @@ -138,12 +143,10 @@ // underlying buffer. const MinRead = 512 -// ReadFrom reads data from r until EOF and appends it to the buffer. -// The return value n is the number of bytes read. -// Any error except io.EOF encountered during the read -// is also returned. -// If the buffer becomes too large, ReadFrom will panic with -// ErrTooLarge. +// ReadFrom reads data from r until EOF and appends it to the buffer, growing +// the buffer as needed. The return value n is the number of bytes read. Any +// error except io.EOF encountered during the read is also returned. If the +// buffer becomes too large, ReadFrom will panic with ErrTooLarge. func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) { b.lastRead = opInvalid // If buffer is empty, reset to recover space. @@ -188,10 +191,10 @@ return make([]byte, n) } -// WriteTo writes data to w until the buffer is drained or an error -// occurs. The return value n is the number of bytes written; it always -// fits into an int, but it is int64 to match the io.WriterTo interface. -// Any error encountered during the write is also returned. +// WriteTo writes data to w until the buffer is drained or an error occurs. +// The return value n is the number of bytes written; it always fits into an +// int, but it is int64 to match the io.WriterTo interface. Any error +// encountered during the write is also returned. func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) { b.lastRead = opInvalid if b.off < len(b.buf) { @@ -216,10 +219,9 @@ return } -// WriteByte appends the byte c to the buffer. -// The returned error is always nil, but is included -// to match bufio.Writer's WriteByte. -// If the buffer becomes too large, WriteByte will panic with +// WriteByte appends the byte c to the buffer, growing the buffer as needed. +// The returned error is always nil, but is included to match bufio.Writer's +// WriteByte. If the buffer becomes too large, WriteByte will panic with // ErrTooLarge. func (b *Buffer) WriteByte(c byte) error { b.lastRead = opInvalid @@ -228,12 +230,10 @@ return nil } -// WriteRune appends the UTF-8 encoding of Unicode -// code point r to the buffer, returning its length and -// an error, which is always nil but is included -// to match bufio.Writer's WriteRune. -// If the buffer becomes too large, WriteRune will panic with -// ErrTooLarge. +// WriteRune appends the UTF-8 encoding of Unicode code point r to the +// buffer, returning its length and an error, which is always nil but is +// included to match bufio.Writer's WriteRune. The buffer is grown as needed; +// if it becomes too large, WriteRune will panic with ErrTooLarge. func (b *Buffer) WriteRune(r rune) (n int, err error) { if r < utf8.RuneSelf { b.WriteByte(byte(r)) diff -Naur gcc-4.8.1.orig/libgo/go/bytes/buffer_test.go gcc-4.8.1/libgo/go/bytes/buffer_test.go --- gcc-4.8.1.orig/libgo/go/bytes/buffer_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/bytes/buffer_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -475,3 +475,53 @@ t.Errorf("ReadByte = %q; want %q", c, 'm') } } + +// Tests that we occasionally compact. Issue 5154. +func TestBufferGrowth(t *testing.T) { + var b Buffer + buf := make([]byte, 1024) + b.Write(buf[0:1]) + var cap0 int + for i := 0; i < 5<<10; i++ { + b.Write(buf) + b.Read(buf) + if i == 0 { + cap0 = b.Cap() + } + } + cap1 := b.Cap() + // (*Buffer).grow allows for 2x capacity slop before sliding, + // so set our error threshold at 3x. + if cap1 > cap0*3 { + t.Errorf("buffer cap = %d; too big (grew from %d)", cap1, cap0) + } +} + +// From Issue 5154. +func BenchmarkBufferNotEmptyWriteRead(b *testing.B) { + buf := make([]byte, 1024) + for i := 0; i < b.N; i++ { + var b Buffer + b.Write(buf[0:1]) + for i := 0; i < 5<<10; i++ { + b.Write(buf) + b.Read(buf) + } + } +} + +// Check that we don't compact too often. From Issue 5154. +func BenchmarkBufferFullSmallReads(b *testing.B) { + buf := make([]byte, 1024) + for i := 0; i < b.N; i++ { + var b Buffer + b.Write(buf) + for b.Len()+20 < b.Cap() { + b.Write(buf[:10]) + } + for i := 0; i < 5<<10; i++ { + b.Read(buf[:1]) + b.Write(buf[:1]) + } + } +} diff -Naur gcc-4.8.1.orig/libgo/go/bytes/bytes_decl.go gcc-4.8.1/libgo/go/bytes/bytes_decl.go --- gcc-4.8.1.orig/libgo/go/bytes/bytes_decl.go 2010-08-26 18:31:13.000000000 -0500 +++ gcc-4.8.1/libgo/go/bytes/bytes_decl.go 2013-07-16 01:55:04.520470000 -0500 @@ -4,5 +4,13 @@ package bytes +//go:noescape + // IndexByte returns the index of the first instance of c in s, or -1 if c is not present in s. func IndexByte(s []byte, c byte) int // asm_$GOARCH.s + +//go:noescape + +// Equal returns a boolean reporting whether a == b. +// A nil argument is equivalent to an empty slice. +func Equal(a, b []byte) bool // asm_arm.s or ../runtime/asm_{386,amd64}.s diff -Naur gcc-4.8.1.orig/libgo/go/bytes/bytes.go gcc-4.8.1/libgo/go/bytes/bytes.go --- gcc-4.8.1.orig/libgo/go/bytes/bytes.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/bytes/bytes.go 2013-07-16 01:55:04.520470000 -0500 @@ -37,10 +37,6 @@ return 0 } -// Equal returns a boolean reporting whether a == b. -// A nil argument is equivalent to an empty slice. -func Equal(a, b []byte) bool - func equalPortable(a, b []byte) bool { if len(a) != len(b) { return false @@ -465,10 +461,10 @@ return unicode.IsSpace(r) } -// BUG(r): The rule Title uses for word boundaries does not handle Unicode punctuation properly. - // Title returns a copy of s with all Unicode letters that begin words // mapped to their title case. +// +// BUG: The rule Title uses for word boundaries does not handle Unicode punctuation properly. func Title(s []byte) []byte { // Use a closure here to remember state. // Hackish but effective. Depends on Map scanning in order and calling @@ -515,6 +511,24 @@ return TrimRightFunc(TrimLeftFunc(s, f), f) } +// TrimPrefix returns s without the provided leading prefix string. +// If s doesn't start with prefix, s is returned unchanged. +func TrimPrefix(s, prefix []byte) []byte { + if HasPrefix(s, prefix) { + return s[len(prefix):] + } + return s +} + +// TrimSuffix returns s without the provided trailing suffix string. +// If s doesn't end with suffix, s is returned unchanged. +func TrimSuffix(s, suffix []byte) []byte { + if HasSuffix(s, suffix) { + return s[:len(s)-len(suffix)] + } + return s +} + // IndexFunc interprets s as a sequence of UTF-8-encoded Unicode code points. // It returns the byte index in s of the first Unicode // code point satisfying f(c), or -1 if none do. @@ -553,7 +567,10 @@ // inverted. func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int { for i := len(s); i > 0; { - r, size := utf8.DecodeLastRune(s[0:i]) + r, size := rune(s[i-1]), 1 + if r >= utf8.RuneSelf { + r, size = utf8.DecodeLastRune(s[0:i]) + } i -= size if f(r) == truth { return i diff -Naur gcc-4.8.1.orig/libgo/go/bytes/bytes_test.go gcc-4.8.1/libgo/go/bytes/bytes_test.go --- gcc-4.8.1.orig/libgo/go/bytes/bytes_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/bytes/bytes_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -61,6 +61,10 @@ {[]byte("ab"), []byte("x"), -1}, {[]byte("x"), []byte("a"), 1}, {[]byte("b"), []byte("x"), -1}, + // test runtime·memeq's chunked implementation + {[]byte("abcdefgh"), []byte("abcdefgh"), 0}, + {[]byte("abcdefghi"), []byte("abcdefghi"), 0}, + {[]byte("abcdefghi"), []byte("abcdefghj"), -1}, // nil tests {nil, nil, 0}, {[]byte(""), nil, 0}, @@ -86,6 +90,58 @@ } } +func TestEqual(t *testing.T) { + var size = 128 + if testing.Short() { + size = 32 + } + a := make([]byte, size) + b := make([]byte, size) + b_init := make([]byte, size) + // randomish but deterministic data + for i := 0; i < size; i++ { + a[i] = byte(17 * i) + b_init[i] = byte(23*i + 100) + } + + for len := 0; len <= size; len++ { + for x := 0; x <= size-len; x++ { + for y := 0; y <= size-len; y++ { + copy(b, b_init) + copy(b[y:y+len], a[x:x+len]) + if !Equal(a[x:x+len], b[y:y+len]) || !Equal(b[y:y+len], a[x:x+len]) { + t.Errorf("Equal(%d, %d, %d) = false", len, x, y) + } + } + } + } +} + +// make sure Equal returns false for minimally different strings. The data +// is all zeros except for a single one in one location. +func TestNotEqual(t *testing.T) { + var size = 128 + if testing.Short() { + size = 32 + } + a := make([]byte, size) + b := make([]byte, size) + + for len := 0; len <= size; len++ { + for x := 0; x <= size-len; x++ { + for y := 0; y <= size-len; y++ { + for diffpos := x; diffpos < x+len; diffpos++ { + a[diffpos] = 1 + if Equal(a[x:x+len], b[y:y+len]) || Equal(b[y:y+len], a[x:x+len]) { + t.Errorf("NotEqual(%d, %d, %d, %d) = true", len, x, y, diffpos) + } + a[diffpos] = 0 + } + } + } + } +} + var indexTests = []BinOpTest{ {"", "", 0}, {"", "a", -1}, @@ -303,10 +359,30 @@ buf[n-1] = '\x00' } +func BenchmarkEqual0(b *testing.B) { + var buf [4]byte + buf1 := buf[0:0] + buf2 := buf[1:1] + for i := 0; i < b.N; i++ { + eq := Equal(buf1, buf2) + if !eq { + b.Fatal("bad equal") + } + } +} + +func BenchmarkEqual1(b *testing.B) { bmEqual(b, Equal, 1) } +func BenchmarkEqual6(b *testing.B) { bmEqual(b, Equal, 6) } +func BenchmarkEqual9(b *testing.B) { bmEqual(b, Equal, 9) } +func BenchmarkEqual15(b *testing.B) { bmEqual(b, Equal, 15) } +func BenchmarkEqual16(b *testing.B) { bmEqual(b, Equal, 16) } +func BenchmarkEqual20(b *testing.B) { bmEqual(b, Equal, 20) } func BenchmarkEqual32(b *testing.B) { bmEqual(b, Equal, 32) } func BenchmarkEqual4K(b *testing.B) { bmEqual(b, Equal, 4<<10) } func BenchmarkEqual4M(b *testing.B) { bmEqual(b, Equal, 4<<20) } func BenchmarkEqual64M(b *testing.B) { bmEqual(b, Equal, 64<<20) } +func BenchmarkEqualPort1(b *testing.B) { bmEqual(b, EqualPortable, 1) } +func BenchmarkEqualPort6(b *testing.B) { bmEqual(b, EqualPortable, 6) } func BenchmarkEqualPort32(b *testing.B) { bmEqual(b, EqualPortable, 32) } func BenchmarkEqualPort4K(b *testing.B) { bmEqual(b, EqualPortable, 4<<10) } func BenchmarkEqualPortable4M(b *testing.B) { bmEqual(b, EqualPortable, 4<<20) } @@ -794,8 +870,8 @@ } type TrimTest struct { - f string - in, cutset, out string + f string + in, arg, out string } var trimTests = []TrimTest{ @@ -820,12 +896,17 @@ {"TrimRight", "", "123", ""}, {"TrimRight", "", "", ""}, {"TrimRight", "☺\xc0", "☺", "☺\xc0"}, + {"TrimPrefix", "aabb", "a", "abb"}, + {"TrimPrefix", "aabb", "b", "aabb"}, + {"TrimSuffix", "aabb", "a", "aabb"}, + {"TrimSuffix", "aabb", "b", "aab"}, } func TestTrim(t *testing.T) { for _, tc := range trimTests { name := tc.f var f func([]byte, string) []byte + var fb func([]byte, []byte) []byte switch name { case "Trim": f = Trim @@ -833,12 +914,21 @@ f = TrimLeft case "TrimRight": f = TrimRight + case "TrimPrefix": + fb = TrimPrefix + case "TrimSuffix": + fb = TrimSuffix default: t.Errorf("Undefined trim function %s", name) } - actual := string(f([]byte(tc.in), tc.cutset)) + var actual string + if f != nil { + actual = string(f([]byte(tc.in), tc.arg)) + } else { + actual = string(fb([]byte(tc.in), []byte(tc.arg))) + } if actual != tc.out { - t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.cutset, actual, tc.out) + t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out) } } } @@ -1059,3 +1149,10 @@ FieldsFunc(fieldsInput, unicode.IsSpace) } } + +func BenchmarkTrimSpace(b *testing.B) { + s := []byte(" Some text. \n") + for i := 0; i < b.N; i++ { + TrimSpace(s) + } +} diff -Naur gcc-4.8.1.orig/libgo/go/bytes/equal_test.go gcc-4.8.1/libgo/go/bytes/equal_test.go --- gcc-4.8.1.orig/libgo/go/bytes/equal_test.go 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/bytes/equal_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,47 @@ +// Copyright 2013 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 linux + +package bytes_test + +import ( + . "bytes" + "syscall" + "testing" + "unsafe" +) + +// This file tests the situation where memeq is checking +// data very near to a page boundary. We want to make sure +// equal does not read across the boundary and cause a page +// fault where it shouldn't. + +// This test runs only on linux. The code being tested is +// not OS-specific, so it does not need to be tested on all +// operating systems. + +func TestEqualNearPageBoundary(t *testing.T) { + pagesize := syscall.Getpagesize() + b := make([]byte, 4*pagesize) + i := pagesize + for ; uintptr(unsafe.Pointer(&b[i]))%uintptr(pagesize) != 0; i++ { + } + syscall.Mprotect(b[i-pagesize:i], 0) + syscall.Mprotect(b[i+pagesize:i+2*pagesize], 0) + defer syscall.Mprotect(b[i-pagesize:i], syscall.PROT_READ|syscall.PROT_WRITE) + defer syscall.Mprotect(b[i+pagesize:i+2*pagesize], syscall.PROT_READ|syscall.PROT_WRITE) + + // both of these should fault + //pagesize += int(b[i-1]) + //pagesize += int(b[i+pagesize]) + + for j := 0; j < pagesize; j++ { + b[i+j] = 'A' + } + for j := 0; j <= pagesize; j++ { + Equal(b[i:i+j], b[i+pagesize-j:i+pagesize]) + Equal(b[i+pagesize-j:i+pagesize], b[i:i+j]) + } +} diff -Naur gcc-4.8.1.orig/libgo/go/bytes/example_test.go gcc-4.8.1/libgo/go/bytes/example_test.go --- gcc-4.8.1.orig/libgo/go/bytes/example_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/bytes/example_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -66,3 +66,20 @@ // Found it! } } + +func ExampleTrimSuffix() { + var b = []byte("Hello, goodbye, etc!") + b = bytes.TrimSuffix(b, []byte("goodbye, etc!")) + b = bytes.TrimSuffix(b, []byte("gopher")) + b = append(b, bytes.TrimSuffix([]byte("world!"), []byte("x!"))...) + os.Stdout.Write(b) + // Output: Hello, world! +} + +func ExampleTrimPrefix() { + var b = []byte("Goodbye,, world!") + b = bytes.TrimPrefix(b, []byte("Goodbye,")) + b = bytes.TrimPrefix(b, []byte("See ya,")) + fmt.Printf("Hello%s", b) + // Output: Hello, world! +} diff -Naur gcc-4.8.1.orig/libgo/go/bytes/export_test.go gcc-4.8.1/libgo/go/bytes/export_test.go --- gcc-4.8.1.orig/libgo/go/bytes/export_test.go 2012-01-11 19:31:45.000000000 -0600 +++ gcc-4.8.1/libgo/go/bytes/export_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -7,3 +7,7 @@ // Export func for testing var IndexBytePortable = indexBytePortable var EqualPortable = equalPortable + +func (b *Buffer) Cap() int { + return cap(b.buf) +} diff -Naur gcc-4.8.1.orig/libgo/go/compress/bzip2/huffman.go gcc-4.8.1/libgo/go/compress/bzip2/huffman.go --- gcc-4.8.1.orig/libgo/go/compress/bzip2/huffman.go 2011-12-02 20:17:34.000000000 -0600 +++ gcc-4.8.1/libgo/go/compress/bzip2/huffman.go 2013-07-16 01:55:04.520470000 -0500 @@ -54,8 +54,6 @@ nodeIndex = node.right } } - - panic("unreachable") } // newHuffmanTree builds a Huffman tree from a slice containing the code diff -Naur gcc-4.8.1.orig/libgo/go/compress/flate/deflate_test.go gcc-4.8.1/libgo/go/compress/flate/deflate_test.go --- gcc-4.8.1.orig/libgo/go/compress/flate/deflate_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/compress/flate/deflate_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -158,7 +158,6 @@ } <-b.ready } - panic("unreachable") } func (b *syncBuffer) signal() { diff -Naur gcc-4.8.1.orig/libgo/go/compress/flate/inflate.go gcc-4.8.1/libgo/go/compress/flate/inflate.go --- gcc-4.8.1.orig/libgo/go/compress/flate/inflate.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/compress/flate/inflate.go 2013-07-16 01:55:04.520470000 -0500 @@ -263,7 +263,6 @@ } f.step(f) } - panic("unreachable") } func (f *decompressor) Close() error { @@ -495,7 +494,6 @@ return } } - panic("unreached") } // copyHist copies f.copyLen bytes from f.hist (f.copyDist bytes ago) to itself. @@ -642,7 +640,6 @@ return int(chunk >> huffmanValueShift), nil } } - return 0, CorruptInputError(f.roffset) } // Flush any buffered output to the underlying writer. diff -Naur gcc-4.8.1.orig/libgo/go/compress/flate/token.go gcc-4.8.1/libgo/go/compress/flate/token.go --- gcc-4.8.1.orig/libgo/go/compress/flate/token.go 2009-12-21 23:56:33.000000000 -0600 +++ gcc-4.8.1/libgo/go/compress/flate/token.go 2013-07-16 01:55:04.520470000 -0500 @@ -99,5 +99,4 @@ default: return offsetCodes[off>>14] + 28 } - panic("unreachable") } diff -Naur gcc-4.8.1.orig/libgo/go/compress/gzip/gunzip.go gcc-4.8.1/libgo/go/compress/gzip/gunzip.go --- gcc-4.8.1.orig/libgo/go/compress/gzip/gunzip.go 2012-03-02 10:38:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/compress/gzip/gunzip.go 2013-07-16 01:55:04.520470000 -0500 @@ -120,7 +120,6 @@ return string(z.buf[0:i]), nil } } - panic("not reached") } func (z *Reader) read2() (uint32, error) { diff -Naur gcc-4.8.1.orig/libgo/go/compress/gzip/gzip.go gcc-4.8.1/libgo/go/compress/gzip/gzip.go --- gcc-4.8.1.orig/libgo/go/compress/gzip/gzip.go 2012-03-02 10:38:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/compress/gzip/gzip.go 2013-07-16 01:55:04.520470000 -0500 @@ -28,7 +28,7 @@ Header w io.Writer level int - compressor io.WriteCloser + compressor *flate.Writer digest hash.Hash32 size uint32 closed bool @@ -191,6 +191,28 @@ return n, z.err } +// Flush flushes any pending compressed data to the underlying writer. +// +// It is useful mainly in compressed network protocols, to ensure that +// a remote reader has enough data to reconstruct a packet. Flush does +// not return until the data has been written. If the underlying +// writer returns an error, Flush returns that error. +// +// In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH. +func (z *Writer) Flush() error { + if z.err != nil { + return z.err + } + if z.closed { + return nil + } + if z.compressor == nil { + z.Write(nil) + } + z.err = z.compressor.Flush() + return z.err +} + // Close closes the Writer. It does not close the underlying io.Writer. func (z *Writer) Close() error { if z.err != nil { diff -Naur gcc-4.8.1.orig/libgo/go/compress/gzip/gzip_test.go gcc-4.8.1/libgo/go/compress/gzip/gzip_test.go --- gcc-4.8.1.orig/libgo/go/compress/gzip/gzip_test.go 2012-03-02 10:38:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/compress/gzip/gzip_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -157,3 +157,43 @@ } } } + +func TestWriterFlush(t *testing.T) { + buf := new(bytes.Buffer) + + w := NewWriter(buf) + w.Comment = "comment" + w.Extra = []byte("extra") + w.ModTime = time.Unix(1e8, 0) + w.Name = "name" + + n0 := buf.Len() + if n0 != 0 { + t.Fatalf("buffer size = %d before writes; want 0", n0) + } + + if err := w.Flush(); err != nil { + t.Fatal(err) + } + + n1 := buf.Len() + if n1 == 0 { + t.Fatal("no data after first flush") + } + + w.Write([]byte("x")) + + n2 := buf.Len() + if n1 != n2 { + t.Fatalf("after writing a single byte, size changed from %d to %d; want no change", n1, n2) + } + + if err := w.Flush(); err != nil { + t.Fatal(err) + } + + n3 := buf.Len() + if n2 == n3 { + t.Fatal("Flush didn't flush any data") + } +} diff -Naur gcc-4.8.1.orig/libgo/go/compress/lzw/reader.go gcc-4.8.1/libgo/go/compress/lzw/reader.go --- gcc-4.8.1.orig/libgo/go/compress/lzw/reader.go 2011-12-12 17:40:51.000000000 -0600 +++ gcc-4.8.1/libgo/go/compress/lzw/reader.go 2013-07-16 01:55:04.520470000 -0500 @@ -121,7 +121,6 @@ } d.decode() } - panic("unreachable") } // decode decompresses bytes from r and leaves them in d.toRead. @@ -203,7 +202,6 @@ return } } - panic("unreachable") } func (d *decoder) flush() { diff -Naur gcc-4.8.1.orig/libgo/go/container/heap/example_test.go gcc-4.8.1/libgo/go/container/heap/example_test.go --- gcc-4.8.1.orig/libgo/go/container/heap/example_test.go 2012-12-12 17:13:29.000000000 -0600 +++ gcc-4.8.1/libgo/go/container/heap/example_test.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,100 +0,0 @@ -// 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 example demonstrates a priority queue built using the heap interface. -package heap_test - -import ( - "container/heap" - "fmt" -) - -// An Item is something we manage in a priority queue. -type Item struct { - value string // The value of the item; arbitrary. - priority int // The priority of the item in the queue. - // The index is needed by changePriority and is maintained by the heap.Interface methods. - index int // The index of the item in the heap. -} - -// A PriorityQueue implements heap.Interface and holds Items. -type PriorityQueue []*Item - -func (pq PriorityQueue) Len() int { return len(pq) } - -func (pq PriorityQueue) Less(i, j int) bool { - // We want Pop to give us the highest, not lowest, priority so we use greater than here. - return pq[i].priority > pq[j].priority -} - -func (pq PriorityQueue) Swap(i, j int) { - pq[i], pq[j] = pq[j], pq[i] - pq[i].index = i - pq[j].index = j -} - -func (pq *PriorityQueue) Push(x interface{}) { - // Push and Pop use pointer receivers because they modify the slice's length, - // not just its contents. - n := len(*pq) - item := x.(*Item) - item.index = n - *pq = append(*pq, item) -} - -func (pq *PriorityQueue) Pop() interface{} { - a := *pq - n := len(a) - item := a[n-1] - item.index = -1 // for safety - *pq = a[0 : n-1] - return item -} - -// update is not used by the example but shows how to take the top item from -// the queue, update its priority and value, and put it back. -func (pq *PriorityQueue) update(value string, priority int) { - item := heap.Pop(pq).(*Item) - item.value = value - item.priority = priority - heap.Push(pq, item) -} - -// changePriority is not used by the example but shows how to change the -// priority of an arbitrary item. -func (pq *PriorityQueue) changePriority(item *Item, priority int) { - heap.Remove(pq, item.index) - item.priority = priority - heap.Push(pq, item) -} - -// This example pushes 10 items into a PriorityQueue and takes them out in -// order of priority. -func Example() { - const nItem = 10 - // Random priorities for the items (a permutation of 0..9, times 11)). - priorities := [nItem]int{ - 77, 22, 44, 55, 11, 88, 33, 99, 00, 66, - } - values := [nItem]string{ - "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", - } - // Create a priority queue and put some items in it. - pq := make(PriorityQueue, 0, nItem) - for i := 0; i < cap(pq); i++ { - item := &Item{ - value: values[i], - priority: priorities[i], - } - heap.Push(&pq, item) - } - // Take the items out; should arrive in decreasing priority order. - // For example, the highest priority (99) is the seventh item, so output starts with 99:"seven". - for i := 0; i < nItem; i++ { - item := heap.Pop(&pq).(*Item) - fmt.Printf("%.2d:%s ", item.priority, item.value) - } - // Output: - // 99:seven 88:five 77:zero 66:nine 55:three 44:two 33:six 22:one 11:four 00:eight -} diff -Naur gcc-4.8.1.orig/libgo/go/container/heap/heap.go gcc-4.8.1/libgo/go/container/heap/heap.go --- gcc-4.8.1.orig/libgo/go/container/heap/heap.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/container/heap/heap.go 2013-07-16 01:55:04.520470000 -0500 @@ -4,13 +4,13 @@ // Package heap provides heap operations for any type that implements // heap.Interface. A heap is a tree with the property that each node is the -// highest-valued node in its subtree. +// minimum-valued node in its subtree. // // A heap is a common way to implement a priority queue. To build a priority // queue, implement the Heap interface with the (negative) priority as the // ordering for the Less method, so Push adds items while Pop removes the // highest-priority item from the queue. The Examples include such an -// implementation; the file example_test.go has the complete source. +// implementation; the file example_pq_test.go has the complete source. // package heap @@ -90,7 +90,7 @@ func down(h Interface, i, n int) { for { j1 := 2*i + 1 - if j1 >= n { + if j1 >= n || j1 < 0 { // j1 < 0 after int overflow break } j := j1 // left child diff -Naur gcc-4.8.1.orig/libgo/go/container/heap/heap_test.go gcc-4.8.1/libgo/go/container/heap/heap_test.go --- gcc-4.8.1.orig/libgo/go/container/heap/heap_test.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/container/heap/heap_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package heap_test +package heap import ( - . "container/heap" "testing" ) diff -Naur gcc-4.8.1.orig/libgo/go/crypto/cipher/cbc.go gcc-4.8.1/libgo/go/crypto/cipher/cbc.go --- gcc-4.8.1.orig/libgo/go/crypto/cipher/cbc.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/cipher/cbc.go 2013-07-16 01:55:04.520470000 -0500 @@ -42,6 +42,12 @@ func (x *cbcEncrypter) BlockSize() int { return x.blockSize } func (x *cbcEncrypter) CryptBlocks(dst, src []byte) { + if len(src)%x.blockSize != 0 { + panic("crypto/cipher: input not full blocks") + } + if len(dst) < len(src) { + panic("crypto/cipher: output smaller than input") + } for len(src) > 0 { for i := 0; i < x.blockSize; i++ { x.iv[i] ^= src[i] @@ -70,6 +76,12 @@ func (x *cbcDecrypter) BlockSize() int { return x.blockSize } func (x *cbcDecrypter) CryptBlocks(dst, src []byte) { + if len(src)%x.blockSize != 0 { + panic("crypto/cipher: input not full blocks") + } + if len(dst) < len(src) { + panic("crypto/cipher: output smaller than input") + } for len(src) > 0 { x.b.Decrypt(x.tmp, src[:x.blockSize]) for i := 0; i < x.blockSize; i++ { diff -Naur gcc-4.8.1.orig/libgo/go/crypto/cipher/cipher_test.go gcc-4.8.1/libgo/go/crypto/cipher/cipher_test.go --- gcc-4.8.1.orig/libgo/go/crypto/cipher/cipher_test.go 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/cipher/cipher_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,36 @@ +// Copyright 2013 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 cipher_test + +import ( + "crypto/aes" + "crypto/cipher" + "testing" +) + +func TestCryptBlocks(t *testing.T) { + buf := make([]byte, 16) + block, _ := aes.NewCipher(buf) + + mode := cipher.NewCBCDecrypter(block, buf) + mustPanic(t, "crypto/cipher: input not full blocks", func() { mode.CryptBlocks(buf, buf[:3]) }) + mustPanic(t, "crypto/cipher: output smaller than input", func() { mode.CryptBlocks(buf[:3], buf) }) + + mode = cipher.NewCBCEncrypter(block, buf) + mustPanic(t, "crypto/cipher: input not full blocks", func() { mode.CryptBlocks(buf, buf[:3]) }) + mustPanic(t, "crypto/cipher: output smaller than input", func() { mode.CryptBlocks(buf[:3], buf) }) +} + +func mustPanic(t *testing.T, msg string, f func()) { + defer func() { + err := recover() + if err == nil { + t.Errorf("function did not panic, wanted %q", msg) + } else if err != msg { + t.Errorf("got panic %v, wanted %q", err, msg) + } + }() + f() +} diff -Naur gcc-4.8.1.orig/libgo/go/crypto/cipher/example_test.go gcc-4.8.1/libgo/go/crypto/cipher/example_test.go --- gcc-4.8.1.orig/libgo/go/crypto/cipher/example_test.go 2012-12-21 19:15:33.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/cipher/example_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -233,7 +233,7 @@ } defer outFile.Close() - reader := &cipher.StreamReader{stream, inFile} + reader := &cipher.StreamReader{S: stream, R: inFile} // Copy the input file to the output file, decrypting as we go. if _, err := io.Copy(outFile, reader); err != nil { panic(err) @@ -270,7 +270,7 @@ } defer outFile.Close() - writer := &cipher.StreamWriter{stream, outFile, nil} + writer := &cipher.StreamWriter{S: stream, W: outFile} // Copy the input file to the output file, encrypting as we go. if _, err := io.Copy(writer, inFile); err != nil { panic(err) diff -Naur gcc-4.8.1.orig/libgo/go/crypto/dsa/dsa.go gcc-4.8.1/libgo/go/crypto/dsa/dsa.go --- gcc-4.8.1.orig/libgo/go/crypto/dsa/dsa.go 2012-03-02 14:01:37.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/dsa/dsa.go 2013-07-16 01:55:04.520470000 -0500 @@ -144,8 +144,6 @@ params.G = g return } - - panic("unreachable") } // GenerateKey generates a public&private key pair. The Parameters of the diff -Naur gcc-4.8.1.orig/libgo/go/crypto/dsa/dsa_test.go gcc-4.8.1/libgo/go/crypto/dsa/dsa_test.go --- gcc-4.8.1.orig/libgo/go/crypto/dsa/dsa_test.go 2011-12-06 19:11:29.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/dsa/dsa_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -63,8 +63,9 @@ } func TestParameterGeneration(t *testing.T) { - // This test is too slow to run all the time. - return + if testing.Short() { + t.Skip("skipping parameter generation test in short mode") + } testParameterGeneration(t, L1024N160, 1024, 160) testParameterGeneration(t, L2048N224, 2048, 224) diff -Naur gcc-4.8.1.orig/libgo/go/crypto/ecdsa/ecdsa.go gcc-4.8.1/libgo/go/crypto/ecdsa/ecdsa.go --- gcc-4.8.1.orig/libgo/go/crypto/ecdsa/ecdsa.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/crypto/ecdsa/ecdsa.go 2013-07-16 01:55:04.520470000 -0500 @@ -49,7 +49,7 @@ return } -// GenerateKey generates a public&private key pair. +// GenerateKey generates a public and private key pair. func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error) { k, err := randFieldElement(c, rand) if err != nil { diff -Naur gcc-4.8.1.orig/libgo/go/crypto/md5/gen.go gcc-4.8.1/libgo/go/crypto/md5/gen.go --- gcc-4.8.1.orig/libgo/go/crypto/md5/gen.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/md5/gen.go 2013-07-16 01:55:04.520470000 -0500 @@ -161,6 +161,11 @@ } var program = ` +// DO NOT EDIT. +// Generate with: go run gen.go{{if .Full}} -full{{end}} | gofmt >md5block.go + +// +build !amd64 + package md5 import ( @@ -186,6 +191,16 @@ } {{end}} +const x86 = runtime.GOARCH == "amd64" || runtime.GOARCH == "386" + +var littleEndian bool + +func init() { + x := uint32(0x04030201) + y := [4]byte{0x1, 0x2, 0x3, 0x4} + littleEndian = *(*[4]byte)(unsafe.Pointer(&x)) == y +} + func block(dig *digest, p []byte) { a := dig.s[0] b := dig.s[1] @@ -197,13 +212,13 @@ aa, bb, cc, dd := a, b, c, d // This is a constant condition - it is not evaluated on each iteration. - if runtime.GOARCH == "amd64" || runtime.GOARCH == "386" { + if x86 { // MD5 was designed so that x86 processors can just iterate // over the block data directly as uint32s, and we generate // less code and run 1.3x faster if we take advantage of that. // My apologies. X = (*[16]uint32)(unsafe.Pointer(&p[0])) - } else if uintptr(unsafe.Pointer(&p[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { + } else if littleEndian && uintptr(unsafe.Pointer(&p[0]))&(unsafe.Alignof(uint32(0))-1) == 0 { X = (*[16]uint32)(unsafe.Pointer(&p[0])) } else { X = &xbuf diff -Naur gcc-4.8.1.orig/libgo/go/crypto/md5/md5block_decl.go gcc-4.8.1/libgo/go/crypto/md5/md5block_decl.go --- gcc-4.8.1.orig/libgo/go/crypto/md5/md5block_decl.go 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/md5/md5block_decl.go 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,9 @@ +// Copyright 2013 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 amd64 386 + +package md5 + +func block(dig *digest, p []byte) diff -Naur gcc-4.8.1.orig/libgo/go/crypto/md5/md5block.go gcc-4.8.1/libgo/go/crypto/md5/md5block.go --- gcc-4.8.1.orig/libgo/go/crypto/md5/md5block.go 2013-02-07 15:40:10.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/md5/md5block.go 2013-07-16 01:55:04.520470000 -0500 @@ -1,3 +1,8 @@ +// DO NOT EDIT. +// Generate with: go run gen.go -full | gofmt >md5block.go + +// +build !amd64,!386 + package md5 import ( diff -Naur gcc-4.8.1.orig/libgo/go/crypto/md5/md5_test.go gcc-4.8.1/libgo/go/crypto/md5/md5_test.go --- gcc-4.8.1.orig/libgo/go/crypto/md5/md5_test.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/md5/md5_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package md5_test +package md5 import ( - "crypto/md5" "fmt" "io" "testing" @@ -54,7 +53,7 @@ func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i] - c := md5.New() + c := New() buf := make([]byte, len(g.in)+4) for j := 0; j < 3+4; j++ { if j < 2 { @@ -79,14 +78,14 @@ } func ExampleNew() { - h := md5.New() + h := New() io.WriteString(h, "The fog is getting thicker!") io.WriteString(h, "And Leon's getting laaarger!") fmt.Printf("%x", h.Sum(nil)) // Output: e2c569be17396eca2a2e3c11578123ed } -var bench = md5.New() +var bench = New() var buf = make([]byte, 8192+1) var sum = make([]byte, bench.Size()) diff -Naur gcc-4.8.1.orig/libgo/go/crypto/rand/util.go gcc-4.8.1/libgo/go/crypto/rand/util.go --- gcc-4.8.1.orig/libgo/go/crypto/rand/util.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/rand/util.go 2013-07-16 01:55:04.520470000 -0500 @@ -98,12 +98,13 @@ return } } - - return } -// Int returns a uniform random value in [0, max). +// Int returns a uniform random value in [0, max). It panics if max <= 0. func Int(rand io.Reader, max *big.Int) (n *big.Int, err error) { + if max.Sign() <= 0 { + panic("crypto/rand: argument to Int is <= 0") + } k := (max.BitLen() + 7) / 8 // b is the number of bits in the most significant byte of max. @@ -130,6 +131,4 @@ return } } - - return } diff -Naur gcc-4.8.1.orig/libgo/go/crypto/rc4/rc4_asm.go gcc-4.8.1/libgo/go/crypto/rc4/rc4_asm.go --- gcc-4.8.1.orig/libgo/go/crypto/rc4/rc4_asm.go 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/rc4/rc4_asm.go 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,18 @@ +// Copyright 2013 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 amd64 arm 386 + +package rc4 + +func xorKeyStream(dst, src *byte, n int, state *[256]uint32, i, j *uint8) + +// XORKeyStream sets dst to the result of XORing src with the key stream. +// Dst and src may be the same slice but otherwise should not overlap. +func (c *Cipher) XORKeyStream(dst, src []byte) { + if len(src) == 0 { + return + } + xorKeyStream(&dst[0], &src[0], len(src), &c.s, &c.i, &c.j) +} diff -Naur gcc-4.8.1.orig/libgo/go/crypto/rc4/rc4.go gcc-4.8.1/libgo/go/crypto/rc4/rc4.go --- gcc-4.8.1.orig/libgo/go/crypto/rc4/rc4.go 2011-12-02 20:17:34.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/rc4/rc4.go 2013-07-16 01:55:04.520470000 -0500 @@ -13,7 +13,7 @@ // A Cipher is an instance of RC4 using a particular key. type Cipher struct { - s [256]byte + s [256]uint32 i, j uint8 } @@ -32,27 +32,16 @@ } var c Cipher for i := 0; i < 256; i++ { - c.s[i] = uint8(i) + c.s[i] = uint32(i) } var j uint8 = 0 for i := 0; i < 256; i++ { - j += c.s[i] + key[i%k] + j += uint8(c.s[i]) + key[i%k] c.s[i], c.s[j] = c.s[j], c.s[i] } return &c, nil } -// XORKeyStream sets dst to the result of XORing src with the key stream. -// Dst and src may be the same slice but otherwise should not overlap. -func (c *Cipher) XORKeyStream(dst, src []byte) { - for i := range src { - c.i += 1 - c.j += c.s[c.i] - c.s[c.i], c.s[c.j] = c.s[c.j], c.s[c.i] - dst[i] = src[i] ^ c.s[c.s[c.i]+c.s[c.j]] - } -} - // Reset zeros the key data so that it will no longer appear in the // process's memory. func (c *Cipher) Reset() { diff -Naur gcc-4.8.1.orig/libgo/go/crypto/rc4/rc4_ref.go gcc-4.8.1/libgo/go/crypto/rc4/rc4_ref.go --- gcc-4.8.1.orig/libgo/go/crypto/rc4/rc4_ref.go 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/rc4/rc4_ref.go 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,20 @@ +// Copyright 2013 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 !amd64,!arm,!386 + +package rc4 + +// XORKeyStream sets dst to the result of XORing src with the key stream. +// Dst and src may be the same slice but otherwise should not overlap. +func (c *Cipher) XORKeyStream(dst, src []byte) { + i, j := c.i, c.j + for k, v := range src { + i += 1 + j += uint8(c.s[i]) + c.s[i], c.s[j] = c.s[j], c.s[i] + dst[k] = v ^ byte(c.s[byte(c.s[i]+c.s[j])]) + } + c.i, c.j = i, j +} diff -Naur gcc-4.8.1.orig/libgo/go/crypto/rc4/rc4_test.go gcc-4.8.1/libgo/go/crypto/rc4/rc4_test.go --- gcc-4.8.1.orig/libgo/go/crypto/rc4/rc4_test.go 2011-01-21 12:19:03.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/rc4/rc4_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -5,6 +5,8 @@ package rc4 import ( + "bytes" + "fmt" "testing" ) @@ -37,23 +39,124 @@ []byte{0x57, 0x69, 0x6b, 0x69}, []byte{0x60, 0x44, 0xdb, 0x6d, 0x41, 0xb7}, }, + { + []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + []byte{ + 0xde, 0x18, 0x89, 0x41, 0xa3, 0x37, 0x5d, 0x3a, + 0x8a, 0x06, 0x1e, 0x67, 0x57, 0x6e, 0x92, 0x6d, + 0xc7, 0x1a, 0x7f, 0xa3, 0xf0, 0xcc, 0xeb, 0x97, + 0x45, 0x2b, 0x4d, 0x32, 0x27, 0x96, 0x5f, 0x9e, + 0xa8, 0xcc, 0x75, 0x07, 0x6d, 0x9f, 0xb9, 0xc5, + 0x41, 0x7a, 0xa5, 0xcb, 0x30, 0xfc, 0x22, 0x19, + 0x8b, 0x34, 0x98, 0x2d, 0xbb, 0x62, 0x9e, 0xc0, + 0x4b, 0x4f, 0x8b, 0x05, 0xa0, 0x71, 0x08, 0x50, + 0x92, 0xa0, 0xc3, 0x58, 0x4a, 0x48, 0xe4, 0xa3, + 0x0a, 0x39, 0x7b, 0x8a, 0xcd, 0x1d, 0x00, 0x9e, + 0xc8, 0x7d, 0x68, 0x11, 0xf2, 0x2c, 0xf4, 0x9c, + 0xa3, 0xe5, 0x93, 0x54, 0xb9, 0x45, 0x15, 0x35, + 0xa2, 0x18, 0x7a, 0x86, 0x42, 0x6c, 0xca, 0x7d, + 0x5e, 0x82, 0x3e, 0xba, 0x00, 0x44, 0x12, 0x67, + 0x12, 0x57, 0xb8, 0xd8, 0x60, 0xae, 0x4c, 0xbd, + 0x4c, 0x49, 0x06, 0xbb, 0xc5, 0x35, 0xef, 0xe1, + 0x58, 0x7f, 0x08, 0xdb, 0x33, 0x95, 0x5c, 0xdb, + 0xcb, 0xad, 0x9b, 0x10, 0xf5, 0x3f, 0xc4, 0xe5, + 0x2c, 0x59, 0x15, 0x65, 0x51, 0x84, 0x87, 0xfe, + 0x08, 0x4d, 0x0e, 0x3f, 0x03, 0xde, 0xbc, 0xc9, + 0xda, 0x1c, 0xe9, 0x0d, 0x08, 0x5c, 0x2d, 0x8a, + 0x19, 0xd8, 0x37, 0x30, 0x86, 0x16, 0x36, 0x92, + 0x14, 0x2b, 0xd8, 0xfc, 0x5d, 0x7a, 0x73, 0x49, + 0x6a, 0x8e, 0x59, 0xee, 0x7e, 0xcf, 0x6b, 0x94, + 0x06, 0x63, 0xf4, 0xa6, 0xbe, 0xe6, 0x5b, 0xd2, + 0xc8, 0x5c, 0x46, 0x98, 0x6c, 0x1b, 0xef, 0x34, + 0x90, 0xd3, 0x7b, 0x38, 0xda, 0x85, 0xd3, 0x2e, + 0x97, 0x39, 0xcb, 0x23, 0x4a, 0x2b, 0xe7, 0x40, + }, + }, +} + +func testEncrypt(t *testing.T, desc string, c *Cipher, src, expect []byte) { + dst := make([]byte, len(src)) + c.XORKeyStream(dst, src) + for i, v := range dst { + if v != expect[i] { + t.Fatalf("%s: mismatch at byte %d:\nhave %x\nwant %x", desc, i, dst, expect) + } + } } func TestGolden(t *testing.T) { - for i := 0; i < len(golden); i++ { - g := golden[i] - c, err := NewCipher(g.key) - if err != nil { - t.Errorf("Failed to create cipher at golden index %d", i) - return + for gi, g := range golden { + data := make([]byte, len(g.keystream)) + for i := range data { + data[i] = byte(i) } - keystream := make([]byte, len(g.keystream)) - c.XORKeyStream(keystream, keystream) - for j, v := range keystream { - if g.keystream[j] != v { - t.Errorf("Failed at golden index %d", i) - break + + expect := make([]byte, len(g.keystream)) + for i := range expect { + expect[i] = byte(i) ^ g.keystream[i] + } + + for size := 1; size <= len(g.keystream); size++ { + c, err := NewCipher(g.key) + if err != nil { + t.Fatalf("#%d: NewCipher: %v", gi, err) + } + + off := 0 + for off < len(g.keystream) { + n := len(g.keystream) - off + if n > size { + n = size + } + desc := fmt.Sprintf("#%d@[%d:%d]", gi, off, off+n) + testEncrypt(t, desc, c, data[off:off+n], expect[off:off+n]) + off += n } } } } + +func TestBlock(t *testing.T) { + c1a, _ := NewCipher(golden[0].key) + c1b, _ := NewCipher(golden[1].key) + data1 := make([]byte, 1<<20) + for i := range data1 { + c1a.XORKeyStream(data1[i:i+1], data1[i:i+1]) + c1b.XORKeyStream(data1[i:i+1], data1[i:i+1]) + } + + c2a, _ := NewCipher(golden[0].key) + c2b, _ := NewCipher(golden[1].key) + data2 := make([]byte, 1<<20) + c2a.XORKeyStream(data2, data2) + c2b.XORKeyStream(data2, data2) + + if !bytes.Equal(data1, data2) { + t.Fatalf("bad block") + } +} + +func benchmark(b *testing.B, size int64) { + buf := make([]byte, size) + c, err := NewCipher(golden[0].key) + if err != nil { + panic(err) + } + b.SetBytes(size) + + for i := 0; i < b.N; i++ { + c.XORKeyStream(buf, buf) + } +} + +func BenchmarkRC4_128(b *testing.B) { + benchmark(b, 128) +} + +func BenchmarkRC4_1K(b *testing.B) { + benchmark(b, 1024) +} + +func BenchmarkRC4_8K(b *testing.B) { + benchmark(b, 8096) +} diff -Naur gcc-4.8.1.orig/libgo/go/crypto/rsa/rsa.go gcc-4.8.1/libgo/go/crypto/rsa/rsa.go --- gcc-4.8.1.orig/libgo/go/crypto/rsa/rsa.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/rsa/rsa.go 2013-07-16 01:55:04.520470000 -0500 @@ -150,6 +150,20 @@ NextSetOfPrimes: for { todo := bits + // crypto/rand should set the top two bits in each prime. + // Thus each prime has the form + // p_i = 2^bitlen(p_i) × 0.11... (in base 2). + // And the product is: + // P = 2^todo × α + // where α is the product of nprimes numbers of the form 0.11... + // + // If α < 1/2 (which can happen for nprimes > 2), we need to + // shift todo to compensate for lost bits: the mean value of 0.11... + // is 7/8, so todo + shift - nprimes * log2(7/8) ~= bits - 1/2 + // will give good results. + if nprimes >= 7 { + todo += (nprimes - 2) / 5 + } for i := 0; i < nprimes; i++ { primes[i], err = rand.Prime(random, todo/(nprimes-i)) if err != nil { @@ -176,8 +190,9 @@ totient.Mul(totient, pminus1) } if n.BitLen() != bits { - // This should never happen because crypto/rand should - // set the top two bits in each prime. + // This should never happen for nprimes == 2 because + // crypto/rand should set the top two bits in each prime. + // For nprimes > 2 we hope it does not happen often. continue NextSetOfPrimes } @@ -188,7 +203,9 @@ g.GCD(priv.D, y, e, totient) if g.Cmp(bigOne) == 0 { - priv.D.Add(priv.D, totient) + if priv.D.Sign() < 0 { + priv.D.Add(priv.D, totient) + } priv.Primes = primes priv.N = n diff -Naur gcc-4.8.1.orig/libgo/go/crypto/rsa/rsa_test.go gcc-4.8.1/libgo/go/crypto/rsa/rsa_test.go --- gcc-4.8.1.orig/libgo/go/crypto/rsa/rsa_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/rsa/rsa_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -28,11 +28,11 @@ } func Test3PrimeKeyGeneration(t *testing.T) { + size := 768 if testing.Short() { - return + size = 256 } - size := 768 priv, err := GenerateMultiPrimeKey(rand.Reader, 3, size) if err != nil { t.Errorf("failed to generate key") @@ -41,11 +41,11 @@ } func Test4PrimeKeyGeneration(t *testing.T) { + size := 768 if testing.Short() { - return + size = 256 } - size := 768 priv, err := GenerateMultiPrimeKey(rand.Reader, 4, size) if err != nil { t.Errorf("failed to generate key") @@ -53,6 +53,24 @@ testKeyBasics(t, priv) } +func TestNPrimeKeyGeneration(t *testing.T) { + primeSize := 64 + maxN := 24 + if testing.Short() { + primeSize = 16 + maxN = 16 + } + // Test that generation of N-prime keys works for N > 4. + for n := 5; n < maxN; n++ { + priv, err := GenerateMultiPrimeKey(rand.Reader, n, 64+n*primeSize) + if err == nil { + testKeyBasics(t, priv) + } else { + t.Errorf("failed to generate %d-prime key", n) + } + } +} + func TestGnuTLSKey(t *testing.T) { // This is a key generated by `certtool --generate-privkey --bits 128`. // It's such that de ≢ 1 mod φ(n), but is congruent mod the order of @@ -75,6 +93,9 @@ if err := priv.Validate(); err != nil { t.Errorf("Validate() failed: %s", err) } + if priv.D.Cmp(priv.N) > 0 { + t.Errorf("private exponent too large") + } pub := &priv.PublicKey m := big.NewInt(42) diff -Naur gcc-4.8.1.orig/libgo/go/crypto/sha1/sha1block_decl.go gcc-4.8.1/libgo/go/crypto/sha1/sha1block_decl.go --- gcc-4.8.1.orig/libgo/go/crypto/sha1/sha1block_decl.go 1969-12-31 18:00:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/sha1/sha1block_decl.go 2013-07-16 01:55:04.520470000 -0500 @@ -0,0 +1,9 @@ +// Copyright 2013 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 amd64 386 + +package sha1 + +func block(dig *digest, p []byte) diff -Naur gcc-4.8.1.orig/libgo/go/crypto/sha1/sha1block.go gcc-4.8.1/libgo/go/crypto/sha1/sha1block.go --- gcc-4.8.1.orig/libgo/go/crypto/sha1/sha1block.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/sha1/sha1block.go 2013-07-16 01:55:04.520470000 -0500 @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !amd64,!386 + // SHA1 block step. // In its own file so that a faster assembly or C version // can be substituted easily. diff -Naur gcc-4.8.1.orig/libgo/go/crypto/sha1/sha1_test.go gcc-4.8.1/libgo/go/crypto/sha1/sha1_test.go --- gcc-4.8.1.orig/libgo/go/crypto/sha1/sha1_test.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/sha1/sha1_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -4,10 +4,9 @@ // SHA1 hash algorithm. See RFC 3174. -package sha1_test +package sha1 import ( - "crypto/sha1" "fmt" "io" "testing" @@ -55,7 +54,7 @@ func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i] - c := sha1.New() + c := New() for j := 0; j < 3; j++ { if j < 2 { io.WriteString(c, g.in) @@ -74,13 +73,13 @@ } func ExampleNew() { - h := sha1.New() + h := New() io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.") fmt.Printf("% x", h.Sum(nil)) // Output: 59 7f 6a 54 00 10 f9 4c 15 d7 18 06 a9 9a 2c 87 10 e7 47 bd } -var bench = sha1.New() +var bench = New() var buf = make([]byte, 8192) func benchmarkSize(b *testing.B, size int) { diff -Naur gcc-4.8.1.orig/libgo/go/crypto/tls/common.go gcc-4.8.1/libgo/go/crypto/tls/common.go --- gcc-4.8.1.orig/libgo/go/crypto/tls/common.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/tls/common.go 2013-07-16 01:55:04.520470000 -0500 @@ -204,7 +204,24 @@ // connections using that key are compromised. SessionTicketKey [32]byte - serverInitOnce sync.Once + serverInitOnce sync.Once // guards calling (*Config).serverInit +} + +func (c *Config) serverInit() { + if c.SessionTicketsDisabled { + return + } + + // If the key has already been set then we have nothing to do. + for _, b := range c.SessionTicketKey { + if b != 0 { + return + } + } + + if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { + c.SessionTicketsDisabled = true + } } func (c *Config) rand() io.Reader { diff -Naur gcc-4.8.1.orig/libgo/go/crypto/tls/generate_cert.go gcc-4.8.1/libgo/go/crypto/tls/generate_cert.go --- gcc-4.8.1.orig/libgo/go/crypto/tls/generate_cert.go 2012-03-02 10:38:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/tls/generate_cert.go 2013-07-16 01:55:04.520470000 -0500 @@ -16,36 +16,80 @@ "crypto/x509/pkix" "encoding/pem" "flag" + "fmt" "log" "math/big" + "net" "os" + "strings" "time" ) -var hostName *string = flag.String("host", "127.0.0.1", "Hostname to generate a certificate for") +var ( + host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for") + validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") + validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") + isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") + rsaBits = flag.Int("rsa-bits", 1024, "Size of RSA key to generate") +) func main() { flag.Parse() - priv, err := rsa.GenerateKey(rand.Reader, 1024) + if len(*host) == 0 { + log.Fatalf("Missing required --host parameter") + } + + priv, err := rsa.GenerateKey(rand.Reader, *rsaBits) if err != nil { log.Fatalf("failed to generate private key: %s", err) return } - now := time.Now() + var notBefore time.Time + if len(*validFrom) == 0 { + notBefore = time.Now() + } else { + notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) + os.Exit(1) + } + } + + notAfter := notBefore.Add(*validFor) + + // end of ASN.1 time + endOfTime := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC) + if notAfter.After(endOfTime) { + notAfter = endOfTime + } template := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(0), Subject: pkix.Name{ - CommonName: *hostName, Organization: []string{"Acme Co"}, }, - NotBefore: now.Add(-5 * time.Minute).UTC(), - NotAfter: now.AddDate(1, 0, 0).UTC(), // valid for 1 year. + NotBefore: notBefore, + NotAfter: notAfter, + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + hosts := strings.Split(*host, ",") + for _, h := range hosts { + if ip := net.ParseIP(h); ip != nil { + template.IPAddresses = append(template.IPAddresses, ip) + } else { + template.DNSNames = append(template.DNSNames, h) + } + } - SubjectKeyId: []byte{1, 2, 3, 4}, - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + if *isCA { + template.IsCA = true + template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) diff -Naur gcc-4.8.1.orig/libgo/go/crypto/tls/handshake_server.go gcc-4.8.1/libgo/go/crypto/tls/handshake_server.go --- gcc-4.8.1.orig/libgo/go/crypto/tls/handshake_server.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/tls/handshake_server.go 2013-07-16 01:55:04.520470000 -0500 @@ -33,22 +33,7 @@ // If this is the first server handshake, we generate a random key to // encrypt the tickets with. - config.serverInitOnce.Do(func() { - if config.SessionTicketsDisabled { - return - } - - // If the key has already been set then we have nothing to do. - for _, b := range config.SessionTicketKey { - if b != 0 { - return - } - } - - if _, err := io.ReadFull(config.rand(), config.SessionTicketKey[:]); err != nil { - config.SessionTicketsDisabled = true - } - }) + config.serverInitOnce.Do(config.serverInit) hs := serverHandshakeState{ c: c, diff -Naur gcc-4.8.1.orig/libgo/go/crypto/x509/pkcs8.go gcc-4.8.1/libgo/go/crypto/x509/pkcs8.go --- gcc-4.8.1.orig/libgo/go/crypto/x509/pkcs8.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/x509/pkcs8.go 2013-07-16 01:55:04.520470000 -0500 @@ -51,6 +51,4 @@ default: return nil, fmt.Errorf("crypto/x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm) } - - panic("unreachable") } diff -Naur gcc-4.8.1.orig/libgo/go/crypto/x509/verify.go gcc-4.8.1/libgo/go/crypto/x509/verify.go --- gcc-4.8.1.orig/libgo/go/crypto/x509/verify.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/x509/verify.go 2013-07-16 01:55:04.520470000 -0500 @@ -5,6 +5,7 @@ package x509 import ( + "net" "runtime" "strings" "time" @@ -63,14 +64,28 @@ } func (h HostnameError) Error() string { - var valid string c := h.Certificate - if len(c.DNSNames) > 0 { - valid = strings.Join(c.DNSNames, ", ") + + var valid string + if ip := net.ParseIP(h.Host); ip != nil { + // Trying to validate an IP + if len(c.IPAddresses) == 0 { + return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs" + } + for _, san := range c.IPAddresses { + if len(valid) > 0 { + valid += ", " + } + valid += san.String() + } } else { - valid = c.Subject.CommonName + if len(c.DNSNames) > 0 { + valid = strings.Join(c.DNSNames, ", ") + } else { + valid = c.Subject.CommonName + } } - return "certificate is valid for " + valid + ", not " + h.Host + return "x509: certificate is valid for " + valid + ", not " + h.Host } // UnknownAuthorityError results when the certificate issuer is unknown @@ -334,6 +349,22 @@ // VerifyHostname returns nil if c is a valid certificate for the named host. // Otherwise it returns an error describing the mismatch. func (c *Certificate) VerifyHostname(h string) error { + // IP addresses may be written in [ ]. + candidateIP := h + if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' { + candidateIP = h[1 : len(h)-1] + } + if ip := net.ParseIP(candidateIP); ip != nil { + // We only match IP addresses against IP SANs. + // https://tools.ietf.org/html/rfc6125#appendix-B.2 + for _, candidate := range c.IPAddresses { + if ip.Equal(candidate) { + return nil + } + } + return HostnameError{c, candidateIP} + } + lowered := toLowerCaseASCII(h) if len(c.DNSNames) > 0 { @@ -389,6 +420,14 @@ for _, usage := range cert.ExtKeyUsage { if requestedUsage == usage { continue NextRequestedUsage + } else if requestedUsage == ExtKeyUsageServerAuth && + (usage == ExtKeyUsageNetscapeServerGatedCrypto || + usage == ExtKeyUsageMicrosoftServerGatedCrypto) { + // In order to support COMODO + // certificate chains, we have to + // accept Netscape or Microsoft SGC + // usages as equal to ServerAuth. + continue NextRequestedUsage } } diff -Naur gcc-4.8.1.orig/libgo/go/crypto/x509/verify_test.go gcc-4.8.1/libgo/go/crypto/x509/verify_test.go --- gcc-4.8.1.orig/libgo/go/crypto/x509/verify_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/x509/verify_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -158,6 +158,19 @@ {"Ryan Hurst", "GlobalSign PersonalSign 2 CA - G2"}, }, }, + { + leaf: megaLeaf, + intermediates: []string{comodoIntermediate1}, + roots: []string{comodoRoot}, + currentTime: 1360431182, + + // CryptoAPI can find alternative validation paths so we don't + // perform this test with system validation. + systemSkip: true, + expectedChains: [][]string{ + {"mega.co.nz", "EssentialSSL CA", "COMODO Certification Authority"}, + }, + }, } func expectHostnameError(t *testing.T, i int, err error) (ok bool) { @@ -563,3 +576,90 @@ 7y3rH/7TjwDVD7SLu5/SdOfKskuMPTjOEvz3K161mymW06klVhubCIWOro/Gx1Q2 2FQOZ7/2k4uYoOdBTSlb8kTAuzZNgIE0rB2BIYCTz/P6zZIKW0ogbRSH -----END CERTIFICATE-----` + +var megaLeaf = `-----BEGIN CERTIFICATE----- +MIIFOjCCBCKgAwIBAgIQWYE8Dup170kZ+k11Lg51OjANBgkqhkiG9w0BAQUFADBy +MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD +VQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDEYMBYGA1UE +AxMPRXNzZW50aWFsU1NMIENBMB4XDTEyMTIxNDAwMDAwMFoXDTE0MTIxNDIzNTk1 +OVowfzEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRhdGVkMS4wLAYDVQQL +EyVIb3N0ZWQgYnkgSW5zdHJhIENvcnBvcmF0aW9uIFB0eS4gTFREMRUwEwYDVQQL +EwxFc3NlbnRpYWxTU0wxEzARBgNVBAMTCm1lZ2EuY28ubnowggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDcxMCClae8BQIaJHBUIVttlLvhbK4XhXPk3RQ3 +G5XA6tLZMBQ33l3F9knYJ0YErXtr8IdfYoulRQFmKFMJl9GtWyg4cGQi2Rcr5VN5 +S5dA1vu4oyJBxE9fPELcK6Yz1vqaf+n6za+mYTiQYKggVdS8/s8hmNuXP9Zk1pIn ++q0pGsf8NAcSHMJgLqPQrTDw+zae4V03DvcYfNKjuno88d2226ld7MAmQZ7uRNsI +/CnkdelVs+akZsXf0szefSqMJlf08SY32t2jj4Ra7RApVYxOftD9nij/aLfuqOU6 +ow6IgIcIG2ZvXLZwK87c5fxL7UAsTTV+M1sVv8jA33V2oKLhAgMBAAGjggG9MIIB +uTAfBgNVHSMEGDAWgBTay+qtWwhdzP/8JlTOSeVVxjj0+DAdBgNVHQ4EFgQUmP9l +6zhyrZ06Qj4zogt+6LKFk4AwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAw +NAYDVR0lBC0wKwYIKwYBBQUHAwEGCCsGAQUFBwMCBgorBgEEAYI3CgMDBglghkgB +hvhCBAEwTwYDVR0gBEgwRjA6BgsrBgEEAbIxAQICBzArMCkGCCsGAQUFBwIBFh1o +dHRwczovL3NlY3VyZS5jb21vZG8uY29tL0NQUzAIBgZngQwBAgEwOwYDVR0fBDQw +MjAwoC6gLIYqaHR0cDovL2NybC5jb21vZG9jYS5jb20vRXNzZW50aWFsU1NMQ0Eu +Y3JsMG4GCCsGAQUFBwEBBGIwYDA4BggrBgEFBQcwAoYsaHR0cDovL2NydC5jb21v +ZG9jYS5jb20vRXNzZW50aWFsU1NMQ0FfMi5jcnQwJAYIKwYBBQUHMAGGGGh0dHA6 +Ly9vY3NwLmNvbW9kb2NhLmNvbTAlBgNVHREEHjAcggptZWdhLmNvLm56gg53d3cu +bWVnYS5jby5uejANBgkqhkiG9w0BAQUFAAOCAQEAcYhrsPSvDuwihMOh0ZmRpbOE +Gw6LqKgLNTmaYUPQhzi2cyIjhUhNvugXQQlP5f0lp5j8cixmArafg1dTn4kQGgD3 +ivtuhBTgKO1VYB/VRoAt6Lmswg3YqyiS7JiLDZxjoV7KoS5xdiaINfHDUaBBY4ZH +j2BUlPniNBjCqXe/HndUTVUewlxbVps9FyCmH+C4o9DWzdGBzDpCkcmo5nM+cp7q +ZhTIFTvZfo3zGuBoyu8BzuopCJcFRm3cRiXkpI7iOMUIixO1szkJS6WpL1sKdT73 +UXp08U0LBqoqG130FbzEJBBV3ixbvY6BWMHoCWuaoF12KJnC5kHt2RoWAAgMXA== +-----END CERTIFICATE-----` + +var comodoIntermediate1 = `-----BEGIN CERTIFICATE----- +MIIFAzCCA+ugAwIBAgIQGLLLuqME8aAPwfLzJkYqSjANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0xOTEyMzEyMzU5NTlaMHIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVh +dGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9E +TyBDQSBMaW1pdGVkMRgwFgYDVQQDEw9Fc3NlbnRpYWxTU0wgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCt8AiwcsargxIxF3CJhakgEtSYau2A1NHf +5I5ZLdOWIY120j8YC0YZYwvHIPPlC92AGvFaoL0dds23Izp0XmEbdaqb1IX04XiR +0y3hr/yYLgbSeT1awB8hLRyuIVPGOqchfr7tZ291HRqfalsGs2rjsQuqag7nbWzD +ypWMN84hHzWQfdvaGlyoiBSyD8gSIF/F03/o4Tjg27z5H6Gq1huQByH6RSRQXScq +oChBRVt9vKCiL6qbfltTxfEFFld+Edc7tNkBdtzffRDPUanlOPJ7FAB1WfnwWdsX +Pvev5gItpHnBXaIcw5rIp6gLSApqLn8tl2X2xQScRMiZln5+pN0vAgMBAAGjggGD +MIIBfzAfBgNVHSMEGDAWgBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAdBgNVHQ4EFgQU +2svqrVsIXcz//CZUzknlVcY49PgwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQI +MAYBAf8CAQAwIAYDVR0lBBkwFwYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMD4GA1Ud +IAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21v +ZG8uY29tL0NQUzBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9kb2Nh +LmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBsBggrBgEFBQcB +AQRgMF4wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NvbW9k +b1VUTlNHQ0NBLmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2Eu +Y29tMA0GCSqGSIb3DQEBBQUAA4IBAQAtlzR6QDLqcJcvgTtLeRJ3rvuq1xqo2l/z +odueTZbLN3qo6u6bldudu+Ennv1F7Q5Slqz0J790qpL0pcRDAB8OtXj5isWMcL2a +ejGjKdBZa0wztSz4iw+SY1dWrCRnilsvKcKxudokxeRiDn55w/65g+onO7wdQ7Vu +F6r7yJiIatnyfKH2cboZT7g440LX8NqxwCPf3dfxp+0Jj1agq8MLy6SSgIGSH6lv ++Wwz3D5XxqfyH8wqfOQsTEZf6/Nh9yvENZ+NWPU6g0QO2JOsTGvMd/QDzczc4BxL +XSXaPV7Od4rhPsbXlM1wSTz/Dr0ISKvlUhQVnQ6cGodWaK2cCQBk +-----END CERTIFICATE-----` + +var comodoRoot = `-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE-----` diff -Naur gcc-4.8.1.orig/libgo/go/crypto/x509/x509.go gcc-4.8.1/libgo/go/crypto/x509/x509.go --- gcc-4.8.1.orig/libgo/go/crypto/x509/x509.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/x509/x509.go 2013-07-16 01:55:04.520470000 -0500 @@ -19,6 +19,8 @@ "errors" "io" "math/big" + "net" + "strconv" "time" ) @@ -360,16 +362,18 @@ // id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } // id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } var ( - oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0} - oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1} - oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2} - oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3} - oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4} - oidExtKeyUsageIPSECEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5} - oidExtKeyUsageIPSECTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6} - oidExtKeyUsageIPSECUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7} - oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8} - oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9} + oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0} + oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1} + oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2} + oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3} + oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4} + oidExtKeyUsageIPSECEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5} + oidExtKeyUsageIPSECTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6} + oidExtKeyUsageIPSECUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7} + oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8} + oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9} + oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3} + oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1} ) // ExtKeyUsage represents an extended set of actions that are valid for a given key. @@ -387,6 +391,8 @@ ExtKeyUsageIPSECUser ExtKeyUsageTimeStamping ExtKeyUsageOCSPSigning + ExtKeyUsageMicrosoftServerGatedCrypto + ExtKeyUsageNetscapeServerGatedCrypto ) // extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID. @@ -404,6 +410,8 @@ {ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser}, {ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping}, {ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning}, + {ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto}, + {ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto}, } func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) { @@ -458,6 +466,7 @@ // Subject Alternate Name values DNSNames []string EmailAddresses []string + IPAddresses []net.IP // Name constraints PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical. @@ -660,6 +669,13 @@ return nil, err } + if p.N.Sign() <= 0 { + return nil, errors.New("x509: RSA modulus is not a positive number") + } + if p.E <= 0 { + return nil, errors.New("x509: RSA public exponent is not a positive number") + } + pub := &rsa.PublicKey{ E: p.E, N: p.N, @@ -713,7 +729,6 @@ default: return nil, nil } - panic("unreachable") } func parseCertificate(in *certificate) (*Certificate, error) { @@ -828,6 +843,13 @@ case 2: out.DNSNames = append(out.DNSNames, string(v.Bytes)) parsedName = true + case 7: + switch len(v.Bytes) { + case net.IPv4len, net.IPv6len: + out.IPAddresses = append(out.IPAddresses, v.Bytes) + default: + return nil, errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(v.Bytes))) + } } } @@ -1072,11 +1094,22 @@ n++ } - if len(template.DNSNames) > 0 { + if len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 { ret[n].Id = oidExtensionSubjectAltName - rawValues := make([]asn1.RawValue, len(template.DNSNames)) - for i, name := range template.DNSNames { - rawValues[i] = asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(name)} + var rawValues []asn1.RawValue + for _, name := range template.DNSNames { + rawValues = append(rawValues, asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(name)}) + } + for _, email := range template.EmailAddresses { + rawValues = append(rawValues, asn1.RawValue{Tag: 1, Class: 2, Bytes: []byte(email)}) + } + for _, rawIP := range template.IPAddresses { + // If possible, we always want to encode IPv4 addresses in 4 bytes. + ip := rawIP.To4() + if ip == nil { + ip = rawIP + } + rawValues = append(rawValues, asn1.RawValue{Tag: 7, Class: 2, Bytes: ip}) } ret[n].Value, err = asn1.Marshal(rawValues) if err != nil { diff -Naur gcc-4.8.1.orig/libgo/go/crypto/x509/x509_test.go gcc-4.8.1/libgo/go/crypto/x509/x509_test.go --- gcc-4.8.1.orig/libgo/go/crypto/x509/x509_test.go 2012-12-21 19:15:33.000000000 -0600 +++ gcc-4.8.1/libgo/go/crypto/x509/x509_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -19,6 +19,7 @@ "encoding/hex" "encoding/pem" "math/big" + "net" "reflect" "testing" "time" @@ -174,6 +175,49 @@ } } +func TestMatchIP(t *testing.T) { + // Check that pattern matching is working. + c := &Certificate{ + DNSNames: []string{"*.foo.bar.baz"}, + Subject: pkix.Name{ + CommonName: "*.foo.bar.baz", + }, + } + err := c.VerifyHostname("quux.foo.bar.baz") + if err != nil { + t.Fatalf("VerifyHostname(quux.foo.bar.baz): %v", err) + } + + // But check that if we change it to be matching against an IP address, + // it is rejected. + c = &Certificate{ + DNSNames: []string{"*.2.3.4"}, + Subject: pkix.Name{ + CommonName: "*.2.3.4", + }, + } + err = c.VerifyHostname("1.2.3.4") + if err == nil { + t.Fatalf("VerifyHostname(1.2.3.4) should have failed, did not") + } + + c = &Certificate{ + IPAddresses: []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")}, + } + err = c.VerifyHostname("127.0.0.1") + if err != nil { + t.Fatalf("VerifyHostname(127.0.0.1): %v", err) + } + err = c.VerifyHostname("::1") + if err != nil { + t.Fatalf("VerifyHostname(::1): %v", err) + } + err = c.VerifyHostname("[::1]") + if err != nil { + t.Fatalf("VerifyHostname([::1]): %v", err) + } +} + func TestCertificateParse(t *testing.T) { s, _ := hex.DecodeString(certBytes) certs, err := ParseCertificates(s) @@ -284,8 +328,11 @@ UnknownExtKeyUsage: testUnknownExtKeyUsage, BasicConstraintsValid: true, - IsCA: true, - DNSNames: []string{"test.example.com"}, + IsCA: true, + + DNSNames: []string{"test.example.com"}, + EmailAddresses: []string{"gopher@golang.org"}, + IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")}, PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}}, PermittedDNSDomains: []string{".example.com", "example.com"}, @@ -327,6 +374,18 @@ t.Errorf("%s: unknown extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.UnknownExtKeyUsage, testUnknownExtKeyUsage) } + if !reflect.DeepEqual(cert.DNSNames, template.DNSNames) { + t.Errorf("%s: SAN DNS names differ from template. Got %v, want %v", test.name, cert.DNSNames, template.DNSNames) + } + + if !reflect.DeepEqual(cert.EmailAddresses, template.EmailAddresses) { + t.Errorf("%s: SAN emails differ from template. Got %v, want %v", test.name, cert.EmailAddresses, template.EmailAddresses) + } + + if !reflect.DeepEqual(cert.IPAddresses, template.IPAddresses) { + t.Errorf("%s: SAN IPs differ from template. Got %v, want %v", test.name, cert.IPAddresses, template.IPAddresses) + } + if test.checkSig { err = cert.CheckSignatureFrom(cert) if err != nil { diff -Naur gcc-4.8.1.orig/libgo/go/database/sql/convert.go gcc-4.8.1/libgo/go/database/sql/convert.go --- gcc-4.8.1.orig/libgo/go/database/sql/convert.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/database/sql/convert.go 2013-07-16 01:55:04.520470000 -0500 @@ -14,12 +14,18 @@ "strconv" ) +var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error + // driverArgs converts arguments from callers of Stmt.Exec and // Stmt.Query into driver Values. // -// The statement si may be nil, if no statement is available. -func driverArgs(si driver.Stmt, args []interface{}) ([]driver.Value, error) { +// The statement ds may be nil, if no statement is available. +func driverArgs(ds *driverStmt, args []interface{}) ([]driver.Value, error) { dargs := make([]driver.Value, len(args)) + var si driver.Stmt + if ds != nil { + si = ds.si + } cc, ok := si.(driver.ColumnConverter) // Normal path, for a driver.Stmt that is not a ColumnConverter. @@ -58,7 +64,9 @@ // column before going across the network to get the // same error. var err error + ds.Lock() dargs[n], err = cc.ColumnConverter(n).ConvertValue(arg) + ds.Unlock() if err != nil { return nil, fmt.Errorf("sql: converting argument #%d's type: %v", n, err) } @@ -75,34 +83,68 @@ // An error is returned if the copy would result in loss of information. // dest should be a pointer type. func convertAssign(dest, src interface{}) error { - // Common cases, without reflect. Fall through. + // Common cases, without reflect. switch s := src.(type) { case string: switch d := dest.(type) { case *string: + if d == nil { + return errNilPtr + } *d = s return nil case *[]byte: + if d == nil { + return errNilPtr + } *d = []byte(s) return nil } case []byte: switch d := dest.(type) { case *string: + if d == nil { + return errNilPtr + } *d = string(s) return nil case *interface{}: - bcopy := make([]byte, len(s)) - copy(bcopy, s) - *d = bcopy + if d == nil { + return errNilPtr + } + *d = cloneBytes(s) return nil case *[]byte: + if d == nil { + return errNilPtr + } + *d = cloneBytes(s) + return nil + case *RawBytes: + if d == nil { + return errNilPtr + } *d = s return nil } case nil: switch d := dest.(type) { + case *interface{}: + if d == nil { + return errNilPtr + } + *d = nil + return nil case *[]byte: + if d == nil { + return errNilPtr + } + *d = nil + return nil + case *RawBytes: + if d == nil { + return errNilPtr + } *d = nil return nil } @@ -121,6 +163,26 @@ *d = fmt.Sprintf("%v", src) return nil } + case *[]byte: + sv = reflect.ValueOf(src) + switch sv.Kind() { + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64: + *d = []byte(fmt.Sprintf("%v", src)) + return nil + } + case *RawBytes: + sv = reflect.ValueOf(src) + switch sv.Kind() { + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64: + *d = RawBytes(fmt.Sprintf("%v", src)) + return nil + } case *bool: bv, err := driver.Bool.ConvertValue(src) if err == nil { @@ -140,6 +202,9 @@ if dpv.Kind() != reflect.Ptr { return errors.New("destination not a pointer") } + if dpv.IsNil() { + return errNilPtr + } if !sv.IsValid() { sv = reflect.ValueOf(src) @@ -189,6 +254,16 @@ return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest) } +func cloneBytes(b []byte) []byte { + if b == nil { + return nil + } else { + c := make([]byte, len(b)) + copy(c, b) + return c + } +} + func asString(src interface{}) string { switch v := src.(type) { case string: diff -Naur gcc-4.8.1.orig/libgo/go/database/sql/convert_test.go gcc-4.8.1/libgo/go/database/sql/convert_test.go --- gcc-4.8.1.orig/libgo/go/database/sql/convert_test.go 2012-03-02 10:38:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/database/sql/convert_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -22,6 +22,8 @@ wantint int64 wantuint uint64 wantstr string + wantbytes []byte + wantraw RawBytes wantf32 float32 wantf64 float64 wanttime time.Time @@ -35,6 +37,8 @@ // Target variables for scanning into. var ( scanstr string + scanbytes []byte + scanraw RawBytes scanint int scanint8 int8 scanint16 int16 @@ -56,6 +60,7 @@ {s: someTime, d: &scantime, wanttime: someTime}, // To strings + {s: "string", d: &scanstr, wantstr: "string"}, {s: []byte("byteslice"), d: &scanstr, wantstr: "byteslice"}, {s: 123, d: &scanstr, wantstr: "123"}, {s: int8(123), d: &scanstr, wantstr: "123"}, @@ -66,6 +71,31 @@ {s: uint64(123), d: &scanstr, wantstr: "123"}, {s: 1.5, d: &scanstr, wantstr: "1.5"}, + // To []byte + {s: nil, d: &scanbytes, wantbytes: nil}, + {s: "string", d: &scanbytes, wantbytes: []byte("string")}, + {s: []byte("byteslice"), d: &scanbytes, wantbytes: []byte("byteslice")}, + {s: 123, d: &scanbytes, wantbytes: []byte("123")}, + {s: int8(123), d: &scanbytes, wantbytes: []byte("123")}, + {s: int64(123), d: &scanbytes, wantbytes: []byte("123")}, + {s: uint8(123), d: &scanbytes, wantbytes: []byte("123")}, + {s: uint16(123), d: &scanbytes, wantbytes: []byte("123")}, + {s: uint32(123), d: &scanbytes, wantbytes: []byte("123")}, + {s: uint64(123), d: &scanbytes, wantbytes: []byte("123")}, + {s: 1.5, d: &scanbytes, wantbytes: []byte("1.5")}, + + // To RawBytes + {s: nil, d: &scanraw, wantraw: nil}, + {s: []byte("byteslice"), d: &scanraw, wantraw: RawBytes("byteslice")}, + {s: 123, d: &scanraw, wantraw: RawBytes("123")}, + {s: int8(123), d: &scanraw, wantraw: RawBytes("123")}, + {s: int64(123), d: &scanraw, wantraw: RawBytes("123")}, + {s: uint8(123), d: &scanraw, wantraw: RawBytes("123")}, + {s: uint16(123), d: &scanraw, wantraw: RawBytes("123")}, + {s: uint32(123), d: &scanraw, wantraw: RawBytes("123")}, + {s: uint64(123), d: &scanraw, wantraw: RawBytes("123")}, + {s: 1.5, d: &scanraw, wantraw: RawBytes("1.5")}, + // Strings to integers {s: "255", d: &scanuint8, wantuint: 255}, {s: "256", d: &scanuint8, wanterr: `converting string "256" to a uint8: strconv.ParseUint: parsing "256": value out of range`}, @@ -113,6 +143,7 @@ {s: []byte("byteslice"), d: &scaniface, wantiface: []byte("byteslice")}, {s: true, d: &scaniface, wantiface: true}, {s: nil, d: &scaniface}, + {s: []byte(nil), d: &scaniface, wantiface: []byte(nil)}, } func intPtrValue(intptr interface{}) interface{} { @@ -191,7 +222,7 @@ } if srcBytes, ok := ct.s.([]byte); ok { dstBytes := (*ifptr).([]byte) - if &dstBytes[0] == &srcBytes[0] { + if len(srcBytes) > 0 && &dstBytes[0] == &srcBytes[0] { errf("copy into interface{} didn't copy []byte data") } } diff -Naur gcc-4.8.1.orig/libgo/go/database/sql/driver/driver.go gcc-4.8.1/libgo/go/database/sql/driver/driver.go --- gcc-4.8.1.orig/libgo/go/database/sql/driver/driver.go 2012-03-30 16:27:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/database/sql/driver/driver.go 2013-07-16 01:55:04.520470000 -0500 @@ -10,8 +10,8 @@ import "errors" -// A driver Value is a value that drivers must be able to handle. -// A Value is either nil or an instance of one of these types: +// Value is a value that drivers must be able to handle. +// It is either nil or an instance of one of these types: // // int64 // float64 @@ -56,7 +56,7 @@ // 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 +// If a Conn does not implement Execer, the sql package's DB.Exec will // first prepare a query, execute the statement, and then close the // statement. // @@ -65,6 +65,17 @@ Exec(query string, args []Value) (Result, error) } +// Queryer is an optional interface that may be implemented by a Conn. +// +// If a Conn does not implement Queryer, the sql package's DB.Query will +// first prepare a query, execute the statement, and then close the +// statement. +// +// Query may return ErrSkip. +type Queryer interface { + Query(query string, args []Value) (Rows, error) +} + // Conn is a connection to a database. It is not used concurrently // by multiple goroutines. // @@ -104,23 +115,8 @@ type Stmt interface { // Close closes the statement. // - // Closing a statement should not interrupt any outstanding - // query created from that statement. That is, the following - // order of operations is valid: - // - // * create a driver statement - // * call Query on statement, returning Rows - // * close the statement - // * read from Rows - // - // If closing a statement invalidates currently-running - // queries, the final step above will incorrectly fail. - // - // TODO(bradfitz): possibly remove the restriction above, if - // enough driver authors object and find it complicates their - // code too much. The sql package could be smarter about - // refcounting the statement and closing it at the appropriate - // time. + // As of Go 1.1, a Stmt will not be closed if it's in use + // by any queries. Close() error // NumInput returns the number of placeholder parameters. diff -Naur gcc-4.8.1.orig/libgo/go/database/sql/fakedb_test.go gcc-4.8.1/libgo/go/database/sql/fakedb_test.go --- gcc-4.8.1.orig/libgo/go/database/sql/fakedb_test.go 2012-12-21 19:15:33.000000000 -0600 +++ gcc-4.8.1/libgo/go/database/sql/fakedb_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -13,6 +13,7 @@ "strconv" "strings" "sync" + "testing" "time" ) @@ -34,9 +35,10 @@ // When opening a fakeDriver's database, it starts empty with no // tables. All tables and data are stored in memory only. type fakeDriver struct { - mu sync.Mutex - openCount int - dbs map[string]*fakeDB + mu sync.Mutex // guards 3 following fields + openCount int // conn opens + closeCount int // conn closes + dbs map[string]*fakeDB } type fakeDB struct { @@ -229,7 +231,43 @@ return c.currTx, nil } -func (c *fakeConn) Close() error { +var hookPostCloseConn struct { + sync.Mutex + fn func(*fakeConn, error) +} + +func setHookpostCloseConn(fn func(*fakeConn, error)) { + hookPostCloseConn.Lock() + defer hookPostCloseConn.Unlock() + hookPostCloseConn.fn = fn +} + +var testStrictClose *testing.T + +// setStrictFakeConnClose sets the t to Errorf on when fakeConn.Close +// fails to close. If nil, the check is disabled. +func setStrictFakeConnClose(t *testing.T) { + testStrictClose = t +} + +func (c *fakeConn) Close() (err error) { + drv := fdriver.(*fakeDriver) + defer func() { + if err != nil && testStrictClose != nil { + testStrictClose.Errorf("failed to close a test fakeConn: %v", err) + } + hookPostCloseConn.Lock() + fn := hookPostCloseConn.fn + hookPostCloseConn.Unlock() + if fn != nil { + fn(c, err) + } + if err == nil { + drv.mu.Lock() + drv.closeCount++ + drv.mu.Unlock() + } + }() if c.currTx != nil { return errors.New("can't close fakeConn; in a Transaction") } @@ -266,6 +304,18 @@ return nil, driver.ErrSkip } +func (c *fakeConn) Query(query string, args []driver.Value) (driver.Rows, error) { + // This is an optional interface, but it's implemented here + // just to check that all the args are of the proper types. + // ErrSkip is returned so the caller acts as if we didn't + // implement this at all. + err := checkSubsetTypes(args) + if err != nil { + return nil, err + } + return nil, driver.ErrSkip +} + func errf(msg string, args ...interface{}) error { return errors.New("fakedb: " + fmt.Sprintf(msg, args...)) } @@ -412,6 +462,12 @@ } func (s *fakeStmt) Close() error { + if s.c == nil { + panic("nil conn in fakeStmt.Close") + } + if s.c.db == nil { + panic("in fakeStmt.Close, conn's db is nil (already closed)") + } if !s.closed { s.c.incrStat(&s.c.stmtsClosed) s.closed = true @@ -503,6 +559,15 @@ if !ok { return nil, fmt.Errorf("fakedb: table %q doesn't exist", s.table) } + + if s.table == "magicquery" { + if len(s.whereCol) == 2 && s.whereCol[0] == "op" && s.whereCol[1] == "millis" { + if args[0] == "sleep" { + time.Sleep(time.Duration(args[1].(int64)) * time.Millisecond) + } + } + } + t.mu.Lock() defer t.mu.Unlock() diff -Naur gcc-4.8.1.orig/libgo/go/database/sql/sql.go gcc-4.8.1/libgo/go/database/sql/sql.go --- gcc-4.8.1.orig/libgo/go/database/sql/sql.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/database/sql/sql.go 2013-07-16 01:55:04.520470000 -0500 @@ -4,6 +4,9 @@ // Package sql provides a generic interface around SQL (or SQL-like) // databases. +// +// The sql package must be used in conjunction with a database driver. +// See http://golang.org/s/sqldrivers for a list of drivers. package sql import ( @@ -11,6 +14,7 @@ "errors" "fmt" "io" + "runtime" "sync" ) @@ -176,22 +180,197 @@ // 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. +// The sql package creates and frees connections automatically; it +// also maintains a free pool of idle connections. If the database has +// a concept of per-connection state, such state can only be reliably +// observed within a transaction. Once DB.Begin is called, the +// returned Tx is bound to a single connection. Once Commit or +// Rollback is called on the transaction, that transaction's +// connection is returned to DB's idle connection pool. The pool size +// can be controlled with SetMaxIdleConns. type DB struct { driver driver.Driver dsn string - mu sync.Mutex // protects freeConn and closed - freeConn []driver.Conn + mu sync.Mutex // protects following fields + freeConn []*driverConn closed bool + dep map[finalCloser]depSet + lastPut map[*driverConn]string // stacktrace of last conn's put; debug only + maxIdle int // zero means defaultMaxIdleConns; negative means 0 +} + +// driverConn wraps a driver.Conn with a mutex, to +// be held during all calls into the Conn. (including any calls onto +// interfaces returned via that Conn, such as calls on Tx, Stmt, +// Result, Rows) +type driverConn struct { + db *DB + + sync.Mutex // guards following + ci driver.Conn + closed bool + finalClosed bool // ci.Close has been called + openStmt map[driver.Stmt]bool + + // guarded by db.mu + inUse bool + onPut []func() // code (with db.mu held) run when conn is next returned + dbmuClosed bool // same as closed, but guarded by db.mu, for connIfFree +} + +func (dc *driverConn) removeOpenStmt(si driver.Stmt) { + dc.Lock() + defer dc.Unlock() + delete(dc.openStmt, si) +} + +func (dc *driverConn) prepareLocked(query string) (driver.Stmt, error) { + si, err := dc.ci.Prepare(query) + if err == nil { + // Track each driverConn's open statements, so we can close them + // before closing the conn. + // + // TODO(bradfitz): let drivers opt out of caring about + // stmt closes if the conn is about to close anyway? For now + // do the safe thing, in case stmts need to be closed. + // + // TODO(bradfitz): after Go 1.1, closing driver.Stmts + // should be moved to driverStmt, using unique + // *driverStmts everywhere (including from + // *Stmt.connStmt, instead of returning a + // driver.Stmt), using driverStmt as a pointer + // everywhere, and making it a finalCloser. + if dc.openStmt == nil { + dc.openStmt = make(map[driver.Stmt]bool) + } + dc.openStmt[si] = true + } + return si, err +} + +// the dc.db's Mutex is held. +func (dc *driverConn) closeDBLocked() error { + dc.Lock() + if dc.closed { + dc.Unlock() + return errors.New("sql: duplicate driverConn close") + } + dc.closed = true + dc.Unlock() // not defer; removeDep finalClose calls may need to lock + return dc.db.removeDepLocked(dc, dc)() +} + +func (dc *driverConn) Close() error { + dc.Lock() + if dc.closed { + dc.Unlock() + return errors.New("sql: duplicate driverConn close") + } + dc.closed = true + dc.Unlock() // not defer; removeDep finalClose calls may need to lock + + // And now updates that require holding dc.mu.Lock. + dc.db.mu.Lock() + dc.dbmuClosed = true + fn := dc.db.removeDepLocked(dc, dc) + dc.db.mu.Unlock() + return fn() +} + +func (dc *driverConn) finalClose() error { + dc.Lock() + + for si := range dc.openStmt { + si.Close() + } + dc.openStmt = nil + + err := dc.ci.Close() + dc.ci = nil + dc.finalClosed = true + + dc.Unlock() + return err +} + +// driverStmt associates a driver.Stmt with the +// *driverConn from which it came, so the driverConn's lock can be +// held during calls. +type driverStmt struct { + sync.Locker // the *driverConn + si driver.Stmt +} + +func (ds *driverStmt) Close() error { + ds.Lock() + defer ds.Unlock() + return ds.si.Close() +} + +// depSet is a finalCloser's outstanding dependencies +type depSet map[interface{}]bool // set of true bools + +// The finalCloser interface is used by (*DB).addDep and related +// dependency reference counting. +type finalCloser interface { + // finalClose is called when the reference count of an object + // goes to zero. (*DB).mu is not held while calling it. + finalClose() error +} + +// addDep notes that x now depends on dep, and x's finalClose won't be +// called until all of x's dependencies are removed with removeDep. +func (db *DB) addDep(x finalCloser, dep interface{}) { + //println(fmt.Sprintf("addDep(%T %p, %T %p)", x, x, dep, dep)) + db.mu.Lock() + defer db.mu.Unlock() + db.addDepLocked(x, dep) +} + +func (db *DB) addDepLocked(x finalCloser, dep interface{}) { + if db.dep == nil { + db.dep = make(map[finalCloser]depSet) + } + xdep := db.dep[x] + if xdep == nil { + xdep = make(depSet) + db.dep[x] = xdep + } + xdep[dep] = true +} + +// removeDep notes that x no longer depends on dep. +// If x still has dependencies, nil is returned. +// If x no longer has any dependencies, its finalClose method will be +// called and its error value will be returned. +func (db *DB) removeDep(x finalCloser, dep interface{}) error { + db.mu.Lock() + fn := db.removeDepLocked(x, dep) + db.mu.Unlock() + return fn() +} + +func (db *DB) removeDepLocked(x finalCloser, dep interface{}) func() error { + //println(fmt.Sprintf("removeDep(%T %p, %T %p)", x, x, dep, dep)) + done := false + + xdep := db.dep[x] + if xdep != nil { + delete(xdep, dep) + if len(xdep) == 0 { + delete(db.dep, x) + done = true + } + } + + if !done { + return func() error { return nil } + } + return func() error { + //println(fmt.Sprintf("calling final close on %T %v (%#v)", x, x, x)) + return x.finalClose() + } } // Open opens a database specified by its database driver name and a @@ -199,13 +378,38 @@ // database name and connection information. // // Most users will open a database via a driver-specific connection -// helper function that returns a *DB. +// helper function that returns a *DB. No database drivers are included +// in the Go standard library. See http://golang.org/s/sqldrivers for +// a list of third-party drivers. +// +// Open may just validate its arguments without creating a connection +// to the database. To verify that the data source name is valid, call +// Ping. func Open(driverName, dataSourceName string) (*DB, error) { - driver, ok := drivers[driverName] + driveri, ok := drivers[driverName] if !ok { return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName) } - return &DB{driver: driver, dsn: dataSourceName}, nil + db := &DB{ + driver: driveri, + dsn: dataSourceName, + lastPut: make(map[*driverConn]string), + } + return db, nil +} + +// Ping verifies a connection to the database is still alive, +// establishing a connection if necessary. +func (db *DB) Ping() error { + // TODO(bradfitz): give drivers an optional hook to implement + // this in a more efficient or more reliable way, if they + // have one. + dc, err := db.conn() + if err != nil { + return err + } + db.putConn(dc, nil) + return nil } // Close closes the database, releasing any open resources. @@ -213,8 +417,8 @@ db.mu.Lock() defer db.mu.Unlock() var err error - for _, c := range db.freeConn { - err1 := c.Close() + for _, dc := range db.freeConn { + err1 := dc.closeDBLocked() if err1 != nil { err = err1 } @@ -224,15 +428,45 @@ return err } -func (db *DB) maxIdleConns() int { - const defaultMaxIdleConns = 2 - // TODO(bradfitz): ask driver, if supported, for its default preference - // TODO(bradfitz): let users override? - return defaultMaxIdleConns +const defaultMaxIdleConns = 2 + +func (db *DB) maxIdleConnsLocked() int { + n := db.maxIdle + switch { + case n == 0: + // TODO(bradfitz): ask driver, if supported, for its default preference + return defaultMaxIdleConns + case n < 0: + return 0 + default: + return n + } +} + +// SetMaxIdleConns sets the maximum number of connections in the idle +// connection pool. +// +// If n <= 0, no idle connections are retained. +func (db *DB) SetMaxIdleConns(n int) { + db.mu.Lock() + defer db.mu.Unlock() + if n > 0 { + db.maxIdle = n + } else { + // No idle connections. + db.maxIdle = -1 + } + for len(db.freeConn) > 0 && len(db.freeConn) > n { + nfree := len(db.freeConn) + dc := db.freeConn[nfree-1] + db.freeConn[nfree-1] = nil + db.freeConn = db.freeConn[:nfree-1] + go dc.Close() + } } -// conn returns a newly-opened or cached driver.Conn -func (db *DB) conn() (driver.Conn, error) { +// conn returns a newly-opened or cached *driverConn +func (db *DB) conn() (*driverConn, error) { db.mu.Lock() if db.closed { db.mu.Unlock() @@ -241,53 +475,132 @@ if n := len(db.freeConn); n > 0 { conn := db.freeConn[n-1] db.freeConn = db.freeConn[:n-1] + conn.inUse = true db.mu.Unlock() return conn, nil } db.mu.Unlock() - return db.driver.Open(db.dsn) + + ci, err := db.driver.Open(db.dsn) + if err != nil { + return nil, err + } + dc := &driverConn{ + db: db, + ci: ci, + } + db.mu.Lock() + db.addDepLocked(dc, dc) + dc.inUse = true + db.mu.Unlock() + return dc, nil } -func (db *DB) connIfFree(wanted driver.Conn) (conn driver.Conn, ok bool) { +var ( + errConnClosed = errors.New("database/sql: internal sentinel error: conn is closed") + errConnBusy = errors.New("database/sql: internal sentinel error: conn is busy") +) + +// connIfFree returns (wanted, nil) if wanted is still a valid conn and +// isn't in use. +// +// The error is errConnClosed if the connection if the requested connection +// is invalid because it's been closed. +// +// The error is errConnBusy if the connection is in use. +func (db *DB) connIfFree(wanted *driverConn) (*driverConn, error) { db.mu.Lock() defer db.mu.Unlock() + if wanted.inUse { + return nil, errConnBusy + } + if wanted.dbmuClosed { + return nil, errConnClosed + } 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 + wanted.inUse = true + return wanted, nil } - return nil, false + // TODO(bradfitz): shouldn't get here. After Go 1.1, change this to: + // panic("connIfFree call requested a non-closed, non-busy, non-free conn") + // Which passes all the tests, but I'm too paranoid to include this + // late in Go 1.1. + // Instead, treat it like a busy connection: + return nil, errConnBusy } // putConnHook is a hook for testing. -var putConnHook func(*DB, driver.Conn) +var putConnHook func(*DB, *driverConn) + +// noteUnusedDriverStatement notes that si is no longer used and should +// be closed whenever possible (when c is next not in use), unless c is +// already closed. +func (db *DB) noteUnusedDriverStatement(c *driverConn, si driver.Stmt) { + db.mu.Lock() + defer db.mu.Unlock() + if c.inUse { + c.onPut = append(c.onPut, func() { + si.Close() + }) + } else { + c.Lock() + defer c.Unlock() + if !c.finalClosed { + si.Close() + } + } +} + +// debugGetPut determines whether getConn & putConn calls' stack traces +// are returned for more verbose crashes. +const debugGetPut = false // putConn adds a connection to the db's free pool. // err is optionally the last error that occurred on this connection. -func (db *DB) putConn(c driver.Conn, err error) { +func (db *DB) putConn(dc *driverConn, err error) { + db.mu.Lock() + if !dc.inUse { + if debugGetPut { + fmt.Printf("putConn(%v) DUPLICATE was: %s\n\nPREVIOUS was: %s", dc, stack(), db.lastPut[dc]) + } + panic("sql: connection returned that was never out") + } + if debugGetPut { + db.lastPut[dc] = stack() + } + dc.inUse = false + + for _, fn := range dc.onPut { + fn() + } + dc.onPut = nil + if err == driver.ErrBadConn { // Don't reuse bad connections. + db.mu.Unlock() return } - db.mu.Lock() if putConnHook != nil { - putConnHook(db, c) + putConnHook(db, dc) } - if n := len(db.freeConn); !db.closed && n < db.maxIdleConns() { - db.freeConn = append(db.freeConn, c) + if n := len(db.freeConn); !db.closed && n < db.maxIdleConnsLocked() { + db.freeConn = append(db.freeConn, dc) db.mu.Unlock() return } - // TODO: check to see if we need this Conn for any prepared - // statements which are still active? db.mu.Unlock() - c.Close() + + dc.Close() } -// Prepare creates a prepared statement for later execution. +// Prepare creates a prepared statement for later queries or executions. +// Multiple queries or executions may be run concurrently from the +// returned statement. func (db *DB) Prepare(query string) (*Stmt, error) { var stmt *Stmt var err error @@ -300,34 +613,36 @@ return stmt, err } -func (db *DB) prepare(query string) (stmt *Stmt, err error) { +func (db *DB) prepare(query string) (*Stmt, 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 // to a connection, and to execute this prepared statement // we either need to use this connection (if it's free), else // get a new connection + re-prepare + execute on that one. - ci, err := db.conn() + dc, err := db.conn() if err != nil { return nil, err } - defer func() { - db.putConn(ci, err) - }() - - si, err := ci.Prepare(query) + dc.Lock() + si, err := dc.prepareLocked(query) + dc.Unlock() if err != nil { + db.putConn(dc, err) return nil, err } - stmt = &Stmt{ + stmt := &Stmt{ db: db, query: query, - css: []connStmt{{ci, si}}, + css: []connStmt{{dc, si}}, } + db.addDep(stmt, stmt) + db.putConn(dc, nil) return stmt, nil } // Exec executes a query without returning any rows. +// The args are for any placeholder parameters in the query. func (db *DB) Exec(query string, args ...interface{}) (Result, error) { var res Result var err error @@ -341,50 +656,119 @@ } func (db *DB) exec(query string, args []interface{}) (res Result, err error) { - ci, err := db.conn() + dc, err := db.conn() if err != nil { return nil, err } defer func() { - db.putConn(ci, err) + db.putConn(dc, err) }() - if execer, ok := ci.(driver.Execer); ok { + if execer, ok := dc.ci.(driver.Execer); ok { dargs, err := driverArgs(nil, args) if err != nil { return nil, err } + dc.Lock() resi, err := execer.Exec(query, dargs) + dc.Unlock() if err != driver.ErrSkip { if err != nil { return nil, err } - return result{resi}, nil + return driverResult{dc, resi}, nil } } - sti, err := ci.Prepare(query) + dc.Lock() + si, err := dc.ci.Prepare(query) + dc.Unlock() if err != nil { return nil, err } - defer sti.Close() - - return resultFromStatement(sti, args...) + defer withLock(dc, func() { si.Close() }) + return resultFromStatement(driverStmt{dc, si}, args...) } // Query executes a query that returns rows, typically a SELECT. // The args are for any placeholder parameters in the query. func (db *DB) Query(query string, args ...interface{}) (*Rows, error) { - stmt, err := db.Prepare(query) + var rows *Rows + var err error + for i := 0; i < 10; i++ { + rows, err = db.query(query, args) + if err != driver.ErrBadConn { + break + } + } + return rows, err +} + +func (db *DB) query(query string, args []interface{}) (*Rows, error) { + ci, err := db.conn() + if err != nil { + return nil, err + } + + releaseConn := func(err error) { db.putConn(ci, err) } + + return db.queryConn(ci, releaseConn, query, args) +} + +// queryConn executes a query on the given connection. +// The connection gets released by the releaseConn function. +func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, args []interface{}) (*Rows, error) { + if queryer, ok := dc.ci.(driver.Queryer); ok { + dargs, err := driverArgs(nil, args) + if err != nil { + releaseConn(err) + return nil, err + } + dc.Lock() + rowsi, err := queryer.Query(query, dargs) + dc.Unlock() + if err != driver.ErrSkip { + if err != nil { + releaseConn(err) + return nil, err + } + // Note: ownership of dc passes to the *Rows, to be freed + // with releaseConn. + rows := &Rows{ + dc: dc, + releaseConn: releaseConn, + rowsi: rowsi, + } + return rows, nil + } + } + + dc.Lock() + si, err := dc.ci.Prepare(query) + dc.Unlock() if err != nil { + releaseConn(err) return nil, err } - rows, err := stmt.Query(args...) + + ds := driverStmt{dc, si} + rowsi, err := rowsiFromStatement(ds, args...) if err != nil { - stmt.Close() + releaseConn(err) + dc.Lock() + si.Close() + dc.Unlock() return nil, err } - rows.closeStmt = stmt + + // Note: ownership of ci passes to the *Rows, to be freed + // with releaseConn. + rows := &Rows{ + dc: dc, + releaseConn: releaseConn, + rowsi: rowsi, + closeStmt: si, + } return rows, nil } @@ -411,18 +795,20 @@ } func (db *DB) begin() (tx *Tx, err error) { - ci, err := db.conn() + dc, err := db.conn() if err != nil { return nil, err } - txi, err := ci.Begin() + dc.Lock() + txi, err := dc.ci.Begin() + dc.Unlock() if err != nil { - db.putConn(ci, err) + db.putConn(dc, err) return nil, err } return &Tx{ db: db, - ci: ci, + dc: dc, txi: txi, }, nil } @@ -441,15 +827,11 @@ type Tx struct { db *DB - // ci is owned exclusively until Commit or Rollback, at which point + // dc is owned exclusively until Commit or Rollback, at which point // it's returned with putConn. - ci driver.Conn + dc *driverConn txi driver.Tx - // cimu is held while somebody is using ci (between grabConn - // and releaseConn) - cimu sync.Mutex - // done transitions from false to true exactly once, on Commit // or Rollback. once done, all operations fail with // ErrTxDone. @@ -463,21 +845,16 @@ panic("double close") // internal error } tx.done = true - tx.db.putConn(tx.ci, nil) - tx.ci = nil + tx.db.putConn(tx.dc, nil) + tx.dc = nil tx.txi = nil } -func (tx *Tx) grabConn() (driver.Conn, error) { +func (tx *Tx) grabConn() (*driverConn, error) { if tx.done { return nil, ErrTxDone } - tx.cimu.Lock() - return tx.ci, nil -} - -func (tx *Tx) releaseConn() { - tx.cimu.Unlock() + return tx.dc, nil } // Commit commits the transaction. @@ -486,6 +863,8 @@ return ErrTxDone } defer tx.close() + tx.dc.Lock() + defer tx.dc.Unlock() return tx.txi.Commit() } @@ -495,6 +874,8 @@ return ErrTxDone } defer tx.close() + tx.dc.Lock() + defer tx.dc.Unlock() return tx.txi.Rollback() } @@ -518,21 +899,25 @@ // Perhaps just looking at the reference count (by noting // Stmt.Close) would be enough. We might also want a finalizer // on Stmt to drop the reference count. - ci, err := tx.grabConn() + dc, err := tx.grabConn() if err != nil { return nil, err } - defer tx.releaseConn() - si, err := ci.Prepare(query) + dc.Lock() + si, err := dc.ci.Prepare(query) + dc.Unlock() if err != nil { return nil, err } stmt := &Stmt{ - db: tx.db, - tx: tx, - txsi: si, + db: tx.db, + tx: tx, + txsi: &driverStmt{ + Locker: dc, + si: si, + }, query: query, } return stmt, nil @@ -556,16 +941,20 @@ if tx.db != stmt.db { return &Stmt{stickyErr: errors.New("sql: Tx.Stmt: statement from different database used")} } - ci, err := tx.grabConn() + dc, err := tx.grabConn() if err != nil { return &Stmt{stickyErr: err} } - defer tx.releaseConn() - si, err := ci.Prepare(stmt.query) + dc.Lock() + si, err := dc.ci.Prepare(stmt.query) + dc.Unlock() return &Stmt{ - db: tx.db, - tx: tx, - txsi: si, + db: tx.db, + tx: tx, + txsi: &driverStmt{ + Locker: dc, + si: si, + }, query: stmt.query, stickyErr: err, } @@ -574,51 +963,46 @@ // Exec executes a query that doesn't return rows. // For example: an INSERT and UPDATE. func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) { - ci, err := tx.grabConn() + dc, err := tx.grabConn() if err != nil { return nil, err } - defer tx.releaseConn() - if execer, ok := ci.(driver.Execer); ok { + if execer, ok := dc.ci.(driver.Execer); ok { dargs, err := driverArgs(nil, args) if err != nil { return nil, err } + dc.Lock() resi, err := execer.Exec(query, dargs) + dc.Unlock() if err == nil { - return result{resi}, nil + return driverResult{dc, resi}, nil } if err != driver.ErrSkip { return nil, err } } - sti, err := ci.Prepare(query) + dc.Lock() + si, err := dc.ci.Prepare(query) + dc.Unlock() if err != nil { return nil, err } - defer sti.Close() + defer withLock(dc, func() { si.Close() }) - return resultFromStatement(sti, args...) + return resultFromStatement(driverStmt{dc, si}, args...) } // Query executes a query that returns rows, typically a SELECT. func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) { - if tx.done { - return nil, ErrTxDone - } - stmt, err := tx.Prepare(query) - if err != nil { - return nil, err - } - rows, err := stmt.Query(args...) + dc, err := tx.grabConn() if err != nil { - stmt.Close() return nil, err } - rows.closeStmt = stmt - return rows, err + releaseConn := func(error) {} + return tx.db.queryConn(dc, releaseConn, query, args) } // QueryRow executes a query that is expected to return at most one row. @@ -631,7 +1015,7 @@ // connStmt is a prepared statement on a particular connection. type connStmt struct { - ci driver.Conn + dc *driverConn si driver.Stmt } @@ -642,9 +1026,11 @@ query string // that created the Stmt stickyErr error // if non-nil, this error is returned for all operations + closemu sync.RWMutex // held exclusively during close, for read otherwise. + // If in a transaction, else both nil: tx *Tx - txsi driver.Stmt + txsi *driverStmt mu sync.Mutex // protects the rest of the fields closed bool @@ -659,39 +1045,47 @@ // Exec executes a prepared statement with the given arguments and // returns a Result summarizing the effect of the statement. func (s *Stmt) Exec(args ...interface{}) (Result, error) { - _, releaseConn, si, err := s.connStmt() + s.closemu.RLock() + defer s.closemu.RUnlock() + dc, releaseConn, si, err := s.connStmt() if err != nil { return nil, err } defer releaseConn(nil) - return resultFromStatement(si, args...) + return resultFromStatement(driverStmt{dc, si}, args...) } -func resultFromStatement(si driver.Stmt, args ...interface{}) (Result, error) { +func resultFromStatement(ds driverStmt, args ...interface{}) (Result, error) { + ds.Lock() + want := ds.si.NumInput() + ds.Unlock() + // -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 // driver deal with errors. - if want := si.NumInput(); want != -1 && len(args) != want { + if want != -1 && len(args) != want { return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(args)) } - dargs, err := driverArgs(si, args) + dargs, err := driverArgs(&ds, args) if err != nil { return nil, err } - resi, err := si.Exec(dargs) + ds.Lock() + resi, err := ds.si.Exec(dargs) + ds.Unlock() if err != nil { return nil, err } - return result{resi}, nil + return driverResult{ds.Locker, resi}, nil } // 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(error), si driver.Stmt, err error) { +func (s *Stmt) connStmt() (ci *driverConn, releaseConn func(error), si driver.Stmt, err error) { if err = s.stickyErr; err != nil { return } @@ -710,19 +1104,27 @@ if err != nil { return } - releaseConn = func(error) { s.tx.releaseConn() } - return ci, releaseConn, s.txsi, nil + releaseConn = func(error) {} + return ci, releaseConn, s.txsi.si, nil } var cs connStmt match := false - for _, v := range s.css { - // TODO(bradfitz): lazily clean up entries in this - // list with dead conns while enumerating - if _, match = s.db.connIfFree(v.ci); match { + for i := 0; i < len(s.css); i++ { + v := s.css[i] + _, err := s.db.connIfFree(v.dc) + if err == nil { + match = true cs = v break } + if err == errConnClosed { + // Lazily remove dead conn from our freelist. + s.css[i] = s.css[len(s.css)-1] + s.css = s.css[:len(s.css)-1] + i-- + } + } s.mu.Unlock() @@ -730,11 +1132,13 @@ // TODO(bradfitz): or wait for one? make configurable later? if !match { for i := 0; ; i++ { - ci, err := s.db.conn() + dc, err := s.db.conn() if err != nil { return nil, nil, nil, err } - si, err := ci.Prepare(s.query) + dc.Lock() + si, err := dc.prepareLocked(s.query) + dc.Unlock() if err == driver.ErrBadConn && i < 10 { continue } @@ -742,14 +1146,14 @@ return nil, nil, nil, err } s.mu.Lock() - cs = connStmt{ci, si} + cs = connStmt{dc, si} s.css = append(s.css, cs) s.mu.Unlock() break } } - conn := cs.ci + conn := cs.dc releaseConn = func(err error) { s.db.putConn(conn, err) } return conn, releaseConn, cs.si, nil } @@ -757,37 +1161,60 @@ // Query executes a prepared query statement with the given arguments // and returns the query results as a *Rows. func (s *Stmt) Query(args ...interface{}) (*Rows, error) { - ci, releaseConn, si, err := s.connStmt() + s.closemu.RLock() + defer s.closemu.RUnlock() + + dc, releaseConn, si, err := s.connStmt() if err != nil { return nil, err } + ds := driverStmt{dc, si} + rowsi, err := rowsiFromStatement(ds, args...) + if err != nil { + releaseConn(err) + return nil, err + } + + // Note: ownership of ci passes to the *Rows, to be freed + // with releaseConn. + rows := &Rows{ + dc: dc, + rowsi: rowsi, + // releaseConn set below + } + s.db.addDep(s, rows) + rows.releaseConn = func(err error) { + releaseConn(err) + s.db.removeDep(s, rows) + } + return rows, nil +} + +func rowsiFromStatement(ds driverStmt, args ...interface{}) (driver.Rows, error) { + ds.Lock() + want := ds.si.NumInput() + ds.Unlock() + // -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 // driver deal with errors. - if want := si.NumInput(); want != -1 && len(args) != want { - return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", si.NumInput(), len(args)) + if want != -1 && len(args) != want { + return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", want, len(args)) } - dargs, err := driverArgs(si, args) + dargs, err := driverArgs(&ds, args) if err != nil { return nil, err } - rowsi, err := si.Query(dargs) + ds.Lock() + rowsi, err := ds.si.Query(dargs) + ds.Unlock() if err != nil { - releaseConn(err) return nil, err } - // Note: ownership of ci passes to the *Rows, to be freed - // with releaseConn. - rows := &Rows{ - db: s.db, - ci: ci, - releaseConn: releaseConn, - rowsi: rowsi, - } - return rows, nil + return rowsi, nil } // QueryRow executes a prepared query statement with the given arguments. @@ -811,6 +1238,9 @@ // Close closes the statement. func (s *Stmt) Close() error { + s.closemu.Lock() + defer s.closemu.Unlock() + if s.stickyErr != nil { return s.stickyErr } @@ -823,18 +1253,19 @@ if s.tx != nil { s.txsi.Close() - } else { - for _, v := range s.css { - if ci, match := s.db.connIfFree(v.ci); match { - v.si.Close() - s.db.putConn(ci, nil) - } else { - // TODO(bradfitz): care that we can't close - // this statement because the statement's - // connection is in use? - } - } + return nil + } + + return s.db.removeDep(s, s) +} + +func (s *Stmt) finalClose() error { + for _, v := range s.css { + s.db.noteUnusedDriverStatement(v.dc, v.si) + v.dc.removeOpenStmt(v.si) + s.db.removeDep(v.dc, s) } + s.css = nil return nil } @@ -852,15 +1283,14 @@ // err = rows.Err() // get any error encountered during iteration // ... type Rows struct { - db *DB - ci driver.Conn // owned; must call putconn when closed to release + dc *driverConn // owned; must call releaseConn when closed to release releaseConn func(error) rowsi driver.Rows closed bool lastcols []driver.Value lasterr error - closeStmt *Stmt // if non-nil, statement to Close on close + closeStmt driver.Stmt // if non-nil, statement to Close on close } // Next prepares the next result row for reading with the Scan method. @@ -936,24 +1366,6 @@ return fmt.Errorf("sql: Scan error on column index %d: %v", i, err) } } - for _, dp := range dest { - b, ok := dp.(*[]byte) - if !ok { - continue - } - if *b == nil { - // If the []byte is now nil (for a NULL value), - // don't fall through to below which would - // turn it into a non-nil 0-length byte slice - continue - } - if _, ok = dp.(*RawBytes); ok { - continue - } - clone := make([]byte, len(*b)) - copy(clone, *b) - *b = clone - } return nil } @@ -966,10 +1378,10 @@ } rs.closed = true err := rs.rowsi.Close() - rs.releaseConn(err) if rs.closeStmt != nil { rs.closeStmt.Close() } + rs.releaseConn(err) return err } @@ -1026,6 +1438,31 @@ RowsAffected() (int64, error) } -type result struct { - driver.Result +type driverResult struct { + sync.Locker // the *driverConn + resi driver.Result +} + +func (dr driverResult) LastInsertId() (int64, error) { + dr.Lock() + defer dr.Unlock() + return dr.resi.LastInsertId() +} + +func (dr driverResult) RowsAffected() (int64, error) { + dr.Lock() + defer dr.Unlock() + return dr.resi.RowsAffected() +} + +func stack() string { + var buf [2 << 10]byte + return string(buf[:runtime.Stack(buf[:], false)]) +} + +// withLock runs while holding lk. +func withLock(lk sync.Locker, fn func()) { + lk.Lock() + fn() + lk.Unlock() } diff -Naur gcc-4.8.1.orig/libgo/go/database/sql/sql_test.go gcc-4.8.1/libgo/go/database/sql/sql_test.go --- gcc-4.8.1.orig/libgo/go/database/sql/sql_test.go 2012-12-21 19:15:33.000000000 -0600 +++ gcc-4.8.1/libgo/go/database/sql/sql_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -5,11 +5,11 @@ package sql import ( - "database/sql/driver" "fmt" "reflect" "runtime" "strings" + "sync" "testing" "time" ) @@ -17,10 +17,10 @@ func init() { type dbConn struct { db *DB - c driver.Conn + c *driverConn } freedFrom := make(map[dbConn]string) - putConnHook = func(db *DB, c driver.Conn) { + putConnHook = func(db *DB, c *driverConn) { for _, oc := range db.freeConn { if oc == c { // print before panic, as panic may get lost due to conflicting panic @@ -38,7 +38,15 @@ var chrisBirthday = time.Unix(123456789, 0) -func newTestDB(t *testing.T, name string) *DB { +type testOrBench interface { + Fatalf(string, ...interface{}) + Errorf(string, ...interface{}) + Fatal(...interface{}) + Error(...interface{}) + Logf(string, ...interface{}) +} + +func newTestDB(t testOrBench, name string) *DB { db, err := Open("test", fakeDBName) if err != nil { t.Fatalf("Open: %v", err) @@ -52,17 +60,42 @@ exec(t, db, "INSERT|people|name=Bob,age=?,photo=BPHOTO", 2) exec(t, db, "INSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday) } + if name == "magicquery" { + // Magic table name and column, known by fakedb_test.go. + exec(t, db, "CREATE|magicquery|op=string,millis=int32") + exec(t, db, "INSERT|magicquery|op=sleep,millis=10") + } return db } -func exec(t *testing.T, db *DB, query string, args ...interface{}) { +func exec(t testOrBench, db *DB, query string, args ...interface{}) { _, err := db.Exec(query, args...) if err != nil { t.Fatalf("Exec of %q: %v", query, err) } } -func closeDB(t *testing.T, db *DB) { +func closeDB(t testOrBench, db *DB) { + if e := recover(); e != nil { + fmt.Printf("Panic: %v\n", e) + panic(e) + } + defer setHookpostCloseConn(nil) + setHookpostCloseConn(func(_ *fakeConn, err error) { + if err != nil { + t.Errorf("Error closing fakeConn: %v", err) + } + }) + for i, dc := range db.freeConn { + if n := len(dc.openStmt); n > 0 { + // Just a sanity check. This is legal in + // general, but if we make the tests clean up + // their statements first, then we can safely + // verify this is always zero here, and any + // other value is a leak. + t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, len(db.freeConn), n) + } + } err := db.Close() if err != nil { t.Fatalf("error closing DB: %v", err) @@ -75,7 +108,52 @@ if n := len(db.freeConn); n != 1 { t.Fatalf("free conns = %d; want 1", n) } - return db.freeConn[0].(*fakeConn).numPrepare + return db.freeConn[0].ci.(*fakeConn).numPrepare +} + +func (db *DB) numDeps() int { + db.mu.Lock() + defer db.mu.Unlock() + return len(db.dep) +} + +// Dependencies are closed via a goroutine, so this polls waiting for +// numDeps to fall to want, waiting up to d. +func (db *DB) numDepsPollUntil(want int, d time.Duration) int { + deadline := time.Now().Add(d) + for { + n := db.numDeps() + if n <= want || time.Now().After(deadline) { + return n + } + time.Sleep(50 * time.Millisecond) + } +} + +func (db *DB) numFreeConns() int { + db.mu.Lock() + defer db.mu.Unlock() + return len(db.freeConn) +} + +func (db *DB) dumpDeps(t *testing.T) { + for fc := range db.dep { + db.dumpDep(t, 0, fc, map[finalCloser]bool{}) + } +} + +func (db *DB) dumpDep(t *testing.T, depth int, dep finalCloser, seen map[finalCloser]bool) { + seen[dep] = true + indent := strings.Repeat(" ", depth) + ds := db.dep[dep] + for k := range ds { + t.Logf("%s%T (%p) waiting for -> %T (%p)", indent, dep, dep, k, k) + if fc, ok := k.(finalCloser); ok { + if !seen[fc] { + db.dumpDep(t, depth+1, fc, seen) + } + } + } } func TestQuery(t *testing.T) { @@ -114,7 +192,7 @@ // And verify that the final rows.Next() call, which hit EOF, // also closed the rows connection. - if n := len(db.freeConn); n != 1 { + if n := db.numFreeConns(); n != 1 { t.Fatalf("free conns after query hitting EOF = %d; want 1", n) } if prepares := numPrepares(t, db) - prepares0; prepares != 1 { @@ -270,6 +348,35 @@ } +// golang.org/issue/3734 +func TestStatementQueryRowConcurrent(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + stmt, err := db.Prepare("SELECT|people|age|name=?") + if err != nil { + t.Fatalf("Prepare: %v", err) + } + defer stmt.Close() + + const n = 10 + ch := make(chan error, n) + for i := 0; i < n; i++ { + go func() { + var age int + err := stmt.QueryRow("Alice").Scan(&age) + if err == nil && age != 1 { + err = fmt.Errorf("unexpected age %d", age) + } + ch <- err + }() + } + for i := 0; i < n; i++ { + if err := <-ch; err != nil { + t.Error(err) + } + } +} + // just a test of fakedb itself func TestBogusPreboundParameters(t *testing.T) { db := newTestDB(t, "foo") @@ -448,6 +555,30 @@ } } +// From golang.org/issue/3865 +func TestCloseStmtBeforeRows(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + s, err := db.Prepare("SELECT|people|name|") + if err != nil { + t.Fatal(err) + } + + r, err := s.Query() + if err != nil { + s.Close() + t.Fatal(err) + } + + err = s.Close() + if err != nil { + t.Fatal(err) + } + + r.Close() +} + // Tests fix for issue 2788, that we bind nil to a []byte if the // value in the column is sql null func TestNullByteSlice(t *testing.T) { @@ -520,7 +651,7 @@ if len(db.freeConn) != 1 { t.Fatalf("expected 1 free conn") } - fakeConn := db.freeConn[0].(*fakeConn) + fakeConn := db.freeConn[0].ci.(*fakeConn) if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed { t.Errorf("statement close mismatch: made %d, closed %d", made, closed) } @@ -641,7 +772,337 @@ } } -func stack() string { - buf := make([]byte, 1024) - return string(buf[:runtime.Stack(buf, false)]) +// golang.org/issue/4859 +func TestQueryRowNilScanDest(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + var name *string // nil pointer + err := db.QueryRow("SELECT|people|name|").Scan(name) + want := "sql: Scan error on column index 0: destination pointer is nil" + if err == nil || err.Error() != want { + t.Errorf("error = %q; want %q", err.Error(), want) + } +} + +func TestIssue4902(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + driver := db.driver.(*fakeDriver) + opens0 := driver.openCount + + var stmt *Stmt + var err error + for i := 0; i < 10; i++ { + stmt, err = db.Prepare("SELECT|people|name|") + if err != nil { + t.Fatal(err) + } + err = stmt.Close() + if err != nil { + t.Fatal(err) + } + } + + opens := driver.openCount - opens0 + if opens > 1 { + t.Errorf("opens = %d; want <= 1", opens) + t.Logf("db = %#v", db) + t.Logf("driver = %#v", driver) + t.Logf("stmt = %#v", stmt) + } +} + +// Issue 3857 +// This used to deadlock. +func TestSimultaneousQueries(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + tx, err := db.Begin() + if err != nil { + t.Fatal(err) + } + defer tx.Rollback() + + r1, err := tx.Query("SELECT|people|name|") + if err != nil { + t.Fatal(err) + } + defer r1.Close() + + r2, err := tx.Query("SELECT|people|name|") + if err != nil { + t.Fatal(err) + } + defer r2.Close() +} + +func TestMaxIdleConns(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + tx, err := db.Begin() + if err != nil { + t.Fatal(err) + } + tx.Commit() + if got := len(db.freeConn); got != 1 { + t.Errorf("freeConns = %d; want 1", got) + } + + db.SetMaxIdleConns(0) + + if got := len(db.freeConn); got != 0 { + t.Errorf("freeConns after set to zero = %d; want 0", got) + } + + tx, err = db.Begin() + if err != nil { + t.Fatal(err) + } + tx.Commit() + if got := len(db.freeConn); got != 0 { + t.Errorf("freeConns = %d; want 0", got) + } +} + +// golang.org/issue/5323 +func TestStmtCloseDeps(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + defer setHookpostCloseConn(nil) + setHookpostCloseConn(func(_ *fakeConn, err error) { + if err != nil { + t.Errorf("Error closing fakeConn: %v", err) + } + }) + + db := newTestDB(t, "magicquery") + defer closeDB(t, db) + + driver := db.driver.(*fakeDriver) + + driver.mu.Lock() + opens0 := driver.openCount + closes0 := driver.closeCount + driver.mu.Unlock() + openDelta0 := opens0 - closes0 + + stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?") + if err != nil { + t.Fatal(err) + } + + // Start 50 parallel slow queries. + const ( + nquery = 50 + sleepMillis = 25 + nbatch = 2 + ) + var wg sync.WaitGroup + for batch := 0; batch < nbatch; batch++ { + for i := 0; i < nquery; i++ { + wg.Add(1) + go func() { + defer wg.Done() + var op string + if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows { + t.Error(err) + } + }() + } + // Sleep for twice the expected length of time for the + // batch of 50 queries above to finish before starting + // the next round. + time.Sleep(2 * sleepMillis * time.Millisecond) + } + wg.Wait() + + if g, w := db.numFreeConns(), 2; g != w { + t.Errorf("free conns = %d; want %d", g, w) + } + + if n := db.numDepsPollUntil(4, time.Second); n > 4 { + t.Errorf("number of dependencies = %d; expected <= 4", n) + db.dumpDeps(t) + } + + driver.mu.Lock() + opens := driver.openCount - opens0 + closes := driver.closeCount - closes0 + driver.mu.Unlock() + openDelta := (driver.openCount - driver.closeCount) - openDelta0 + + if openDelta > 2 { + t.Logf("open calls = %d", opens) + t.Logf("close calls = %d", closes) + t.Logf("open delta = %d", openDelta) + t.Errorf("db connections opened = %d; want <= 2", openDelta) + db.dumpDeps(t) + } + + if len(stmt.css) > nquery { + t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery) + } + + if err := stmt.Close(); err != nil { + t.Fatal(err) + } + + if g, w := db.numFreeConns(), 2; g != w { + t.Errorf("free conns = %d; want %d", g, w) + } + + if n := db.numDepsPollUntil(2, time.Second); n > 2 { + t.Errorf("number of dependencies = %d; expected <= 2", n) + db.dumpDeps(t) + } + + db.SetMaxIdleConns(0) + + if g, w := db.numFreeConns(), 0; g != w { + t.Errorf("free conns = %d; want %d", g, w) + } + + if n := db.numDepsPollUntil(0, time.Second); n > 0 { + t.Errorf("number of dependencies = %d; expected 0", n) + db.dumpDeps(t) + } +} + +// golang.org/issue/5046 +func TestCloseConnBeforeStmts(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + defer setHookpostCloseConn(nil) + setHookpostCloseConn(func(_ *fakeConn, err error) { + if err != nil { + t.Errorf("Error closing fakeConn: %v; from %s", err, stack()) + db.dumpDeps(t) + t.Errorf("DB = %#v", db) + } + }) + + stmt, err := db.Prepare("SELECT|people|name|") + if err != nil { + t.Fatal(err) + } + + if len(db.freeConn) != 1 { + t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn)) + } + dc := db.freeConn[0] + if dc.closed { + t.Errorf("conn shouldn't be closed") + } + + if n := len(dc.openStmt); n != 1 { + t.Errorf("driverConn num openStmt = %d; want 1", n) + } + err = db.Close() + if err != nil { + t.Errorf("db Close = %v", err) + } + if !dc.closed { + t.Errorf("after db.Close, driverConn should be closed") + } + if n := len(dc.openStmt); n != 0 { + t.Errorf("driverConn num openStmt = %d; want 0", n) + } + + err = stmt.Close() + if err != nil { + t.Errorf("Stmt close = %v", err) + } + + if !dc.closed { + t.Errorf("conn should be closed") + } + if dc.ci != nil { + t.Errorf("after Stmt Close, driverConn's Conn interface should be nil") + } +} + +// golang.org/issue/5283: don't release the Rows' connection in Close +// before calling Stmt.Close. +func TestRowsCloseOrder(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + db.SetMaxIdleConns(0) + setStrictFakeConnClose(t) + defer setStrictFakeConnClose(nil) + + rows, err := db.Query("SELECT|people|age,name|") + if err != nil { + t.Fatal(err) + } + err = rows.Close() + if err != nil { + t.Fatal(err) + } +} + +func manyConcurrentQueries(t testOrBench) { + maxProcs, numReqs := 16, 500 + if testing.Short() { + maxProcs, numReqs = 4, 50 + } + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs)) + + db := newTestDB(t, "people") + defer closeDB(t, db) + + stmt, err := db.Prepare("SELECT|people|name|") + if err != nil { + t.Fatal(err) + } + defer stmt.Close() + + var wg sync.WaitGroup + wg.Add(numReqs) + + reqs := make(chan bool) + defer close(reqs) + + for i := 0; i < maxProcs*2; i++ { + go func() { + for _ = range reqs { + rows, err := stmt.Query() + if err != nil { + t.Errorf("error on query: %v", err) + wg.Done() + continue + } + + var name string + for rows.Next() { + rows.Scan(&name) + } + rows.Close() + + wg.Done() + } + }() + } + + for i := 0; i < numReqs; i++ { + reqs <- true + } + + wg.Wait() +} + +func TestConcurrency(t *testing.T) { + manyConcurrentQueries(t) +} + +func BenchmarkConcurrency(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + manyConcurrentQueries(b) + } } diff -Naur gcc-4.8.1.orig/libgo/go/debug/dwarf/buf.go gcc-4.8.1/libgo/go/debug/dwarf/buf.go --- gcc-4.8.1.orig/libgo/go/debug/dwarf/buf.go 2012-03-09 00:35:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/debug/dwarf/buf.go 2013-07-16 01:55:04.520470000 -0500 @@ -13,17 +13,45 @@ // Data buffer being decoded. type buf struct { - dwarf *Data - u *unit - order binary.ByteOrder - name string - off Offset - data []byte - err error + dwarf *Data + order binary.ByteOrder + format dataFormat + name string + off Offset + data []byte + err error } -func makeBuf(d *Data, u *unit, name string, off Offset, data []byte) buf { - return buf{d, u, d.order, name, off, data, nil} +// Data format, other than byte order. This affects the handling of +// certain field formats. +type dataFormat interface { + // DWARF version number. Zero means unknown. + version() int + + // 64-bit DWARF format? + dwarf64() (dwarf64 bool, isKnown bool) + + // Size of an address, in bytes. Zero means unknown. + addrsize() int +} + +// Some parts of DWARF have no data format, e.g., abbrevs. +type unknownFormat struct{} + +func (u unknownFormat) version() int { + return 0 +} + +func (u unknownFormat) dwarf64() (bool, bool) { + return false, false +} + +func (u unknownFormat) addrsize() int { + return 0 +} + +func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf { + return buf{d, d.order, format, name, off, data, nil} } func (b *buf) uint8() uint8 { @@ -121,17 +149,15 @@ // Address-sized uint. func (b *buf) addr() uint64 { - if b.u != nil { - switch b.u.addrsize { - case 1: - return uint64(b.uint8()) - case 2: - return uint64(b.uint16()) - case 4: - return uint64(b.uint32()) - case 8: - return uint64(b.uint64()) - } + switch b.format.addrsize() { + case 1: + return uint64(b.uint8()) + case 2: + return uint64(b.uint16()) + case 4: + return uint64(b.uint32()) + case 8: + return uint64(b.uint64()) } b.error("unknown address size") return 0 diff -Naur gcc-4.8.1.orig/libgo/go/debug/dwarf/entry.go gcc-4.8.1/libgo/go/debug/dwarf/entry.go --- gcc-4.8.1.orig/libgo/go/debug/dwarf/entry.go 2012-03-09 00:35:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/debug/dwarf/entry.go 2013-07-16 01:55:04.520470000 -0500 @@ -40,7 +40,7 @@ } else { data = data[off:] } - b := makeBuf(d, nil, "abbrev", 0, data) + b := makeBuf(d, unknownFormat{}, "abbrev", 0, data) // Error handling is simplified by the buf getters // returning an endless stream of 0s after an error. @@ -190,13 +190,16 @@ case formFlag: val = b.uint8() == 1 case formFlagPresent: + // The attribute is implicitly indicated as present, and no value is + // encoded in the debugging information entry itself. val = true // lineptr, loclistptr, macptr, rangelistptr case formSecOffset: - if b.u == nil { + is64, known := b.format.dwarf64() + if !known { b.error("unknown size for DW_FORM_sec_offset") - } else if b.u.dwarf64 { + } else if is64 { val = Offset(b.uint64()) } else { val = Offset(b.uint32()) @@ -204,14 +207,20 @@ // reference to other entry case formRefAddr: - if b.u == nil { + vers := b.format.version() + if vers == 0 { b.error("unknown version for DW_FORM_ref_addr") - } else if b.u.version == 2 { + } else if vers == 2 { val = Offset(b.addr()) - } else if b.u.dwarf64 { - val = Offset(b.uint64()) } else { - val = Offset(b.uint32()) + is64, known := b.format.dwarf64() + if !known { + b.error("unknown size for DW_FORM_ref_addr") + } else if is64 { + val = Offset(b.uint64()) + } else { + val = Offset(b.uint32()) + } } case formRef1: val = Offset(b.uint8()) + ubase @@ -234,7 +243,7 @@ if b.err != nil { return nil } - b1 := makeBuf(b.dwarf, b.u, "str", 0, b.dwarf.str) + b1 := makeBuf(b.dwarf, unknownFormat{}, "str", 0, b.dwarf.str) b1.skip(int(off)) val = b1.string() if b1.err != nil { diff -Naur gcc-4.8.1.orig/libgo/go/debug/dwarf/line.go gcc-4.8.1/libgo/go/debug/dwarf/line.go --- gcc-4.8.1.orig/libgo/go/debug/dwarf/line.go 2012-09-06 00:28:02.000000000 -0500 +++ gcc-4.8.1/libgo/go/debug/dwarf/line.go 2013-07-16 01:55:04.520470000 -0500 @@ -112,7 +112,7 @@ func (d *Data) readAddressRanges(off Offset, base uint64, u *unit) error { b := makeBuf(d, u, "ranges", off, d.ranges[off:]) var highest uint64 - switch u.addrsize { + switch u.addrsize() { case 1: highest = 0xff case 2: diff -Naur gcc-4.8.1.orig/libgo/go/debug/dwarf/type.go gcc-4.8.1/libgo/go/debug/dwarf/type.go --- gcc-4.8.1.orig/libgo/go/debug/dwarf/type.go 2012-03-09 00:35:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/debug/dwarf/type.go 2013-07-16 01:55:04.520470000 -0500 @@ -435,7 +435,9 @@ goto Error } if loc, ok := kid.Val(AttrDataMemberLoc).([]byte); ok { - b := makeBuf(d, nil, "location", 0, loc) + // TODO: Should have original compilation + // unit here, not unknownFormat. + b := makeBuf(d, unknownFormat{}, "location", 0, loc) if b.uint8() != opPlusUconst { err = DecodeError{"info", kid.Offset, "unexpected opcode"} goto Error diff -Naur gcc-4.8.1.orig/libgo/go/debug/dwarf/unit.go gcc-4.8.1/libgo/go/debug/dwarf/unit.go --- gcc-4.8.1.orig/libgo/go/debug/dwarf/unit.go 2012-03-09 00:35:00.000000000 -0600 +++ gcc-4.8.1/libgo/go/debug/dwarf/unit.go 2013-07-16 01:55:04.520470000 -0500 @@ -10,17 +10,31 @@ // Each unit has its own abbreviation table and address size. type unit struct { - base Offset // byte offset of header within the aggregate info - off Offset // byte offset of data within the aggregate info - lineoff Offset // byte offset of data within the line info - data []byte - atable abbrevTable - addrsize int - version int - dwarf64 bool // True for 64-bit DWARF format - dir string - pc []addrRange // PC ranges in this compilation unit - lines []mapLineInfo // PC -> line mapping + base Offset // byte offset of header within the aggregate info + off Offset // byte offset of data within the aggregate info + lineoff Offset // byte offset of data within the line info + data []byte + atable abbrevTable + asize int + vers int + is64 bool // True for 64-bit DWARF format + dir string + pc []addrRange // PC ranges in this compilation unit + lines []mapLineInfo // PC -> line mapping +} + +// Implement the dataFormat interface. + +func (u *unit) version() int { + return u.vers +} + +func (u *unit) dwarf64() (bool, bool) { + return u.is64, true +} + +func (u *unit) addrsize() int { + return u.asize } // A range is an address range. @@ -32,12 +46,12 @@ func (d *Data) parseUnits() ([]unit, error) { // Count units. nunit := 0 - b := makeBuf(d, nil, "info", 0, d.info) + b := makeBuf(d, unknownFormat{}, "info", 0, d.info) for len(b.data) > 0 { len := b.uint32() if len == 0xffffffff { len64 := b.uint64() - if len64 != uint64(int(len64)) { + if len64 != uint64(uint32(len64)) { b.error("unit length overflow") break } @@ -51,14 +65,14 @@ } // Again, this time writing them down. - b = makeBuf(d, nil, "info", 0, d.info) + b = makeBuf(d, unknownFormat{}, "info", 0, d.info) units := make([]unit, nunit) for i := range units { u := &units[i] u.base = b.off n := b.uint32() if n == 0xffffffff { - u.dwarf64 = true + u.is64 = true n = uint32(b.uint64()) } vers := b.uint16() @@ -66,6 +80,7 @@ b.error("unsupported DWARF version " + strconv.Itoa(int(vers))) break } + u.vers = int(vers) atable, err := d.parseAbbrev(b.uint32()) if err != nil { if b.err == nil { @@ -73,9 +88,8 @@ } break } - u.version = int(vers) u.atable = atable - u.addrsize = int(b.uint8()) + u.asize = int(b.uint8()) u.off = b.off u.data = b.bytes(int(n - (2 + 4 + 1))) } diff -Naur gcc-4.8.1.orig/libgo/go/debug/elf/file.go gcc-4.8.1/libgo/go/debug/elf/file.go --- gcc-4.8.1.orig/libgo/go/debug/elf/file.go 2012-12-21 19:15:33.000000000 -0600 +++ gcc-4.8.1/libgo/go/debug/elf/file.go 2013-07-16 01:55:04.520470000 -0500 @@ -422,6 +422,10 @@ return nil, nil, errors.New("cannot load string table section") } + // The first entry is all zeros. + var skip [Sym32Size]byte + symtab.Read(skip[:]) + symbols := make([]Symbol, symtab.Len()/Sym32Size) i := 0 @@ -461,6 +465,10 @@ return nil, nil, errors.New("cannot load string table section") } + // The first entry is all zeros. + var skip [Sym64Size]byte + symtab.Read(skip[:]) + symbols := make([]Symbol, symtab.Len()/Sym64Size) i := 0 @@ -533,10 +541,10 @@ symNo := rela.Info >> 32 t := R_X86_64(rela.Info & 0xffff) - if symNo >= uint64(len(symbols)) { + if symNo == 0 || symNo > uint64(len(symbols)) { continue } - sym := &symbols[symNo] + sym := &symbols[symNo-1] if SymType(sym.Info&0xf) != STT_SECTION { // We don't handle non-section relocations for now. continue @@ -597,6 +605,10 @@ } // Symbols returns the symbol table for f. +// +// For compatibility with Go 1.0, Symbols omits the null symbol at index 0. +// After retrieving the symbols as symtab, an externally supplied index x +// corresponds to symtab[x-1], not symtab[x]. func (f *File) Symbols() ([]Symbol, error) { sym, _, err := f.getSymbols(SHT_SYMTAB) return sym, err @@ -706,7 +718,7 @@ // which came from offset i of the symbol table. func (f *File) gnuVersion(i int, sym *ImportedSymbol) { // Each entry is two bytes. - i = i * 2 + i = (i + 1) * 2 if i >= len(f.gnuVersym) { return } diff -Naur gcc-4.8.1.orig/libgo/go/debug/gosym/symtab.go gcc-4.8.1/libgo/go/debug/gosym/symtab.go --- gcc-4.8.1.orig/libgo/go/debug/gosym/symtab.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/debug/gosym/symtab.go 2013-07-16 01:55:04.520470000 -0500 @@ -99,31 +99,116 @@ } type sym struct { - value uint32 - gotype uint32 + value uint64 + gotype uint64 typ byte name []byte } -var littleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00} +var littleEndianSymtab = []byte{0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00} +var bigEndianSymtab = []byte{0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00} + +var oldLittleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00} func walksymtab(data []byte, fn func(sym) error) error { var order binary.ByteOrder = binary.BigEndian - if bytes.HasPrefix(data, littleEndianSymtab) { + newTable := false + switch { + case bytes.HasPrefix(data, oldLittleEndianSymtab): + // Same as Go 1.0, but little endian. + // Format was used during interim development between Go 1.0 and Go 1.1. + // Should not be widespread, but easy to support. data = data[6:] order = binary.LittleEndian + case bytes.HasPrefix(data, bigEndianSymtab): + newTable = true + case bytes.HasPrefix(data, littleEndianSymtab): + newTable = true + order = binary.LittleEndian + } + var ptrsz int + if newTable { + if len(data) < 8 { + return &DecodingError{len(data), "unexpected EOF", nil} + } + ptrsz = int(data[7]) + if ptrsz != 4 && ptrsz != 8 { + return &DecodingError{7, "invalid pointer size", ptrsz} + } + data = data[8:] } var s sym p := data - for len(p) >= 6 { - s.value = order.Uint32(p[0:4]) - typ := p[4] - if typ&0x80 == 0 { - return &DecodingError{len(data) - len(p) + 4, "bad symbol type", typ} - } - typ &^= 0x80 - s.typ = typ - p = p[5:] + for len(p) >= 4 { + var typ byte + if newTable { + // Symbol type, value, Go type. + typ = p[0] & 0x3F + wideValue := p[0]&0x40 != 0 + goType := p[0]&0x80 != 0 + if typ < 26 { + typ += 'A' + } else { + typ += 'a' - 26 + } + s.typ = typ + p = p[1:] + if wideValue { + if len(p) < ptrsz { + return &DecodingError{len(data), "unexpected EOF", nil} + } + // fixed-width value + if ptrsz == 8 { + s.value = order.Uint64(p[0:8]) + p = p[8:] + } else { + s.value = uint64(order.Uint32(p[0:4])) + p = p[4:] + } + } else { + // varint value + s.value = 0 + shift := uint(0) + for len(p) > 0 && p[0]&0x80 != 0 { + s.value |= uint64(p[0]&0x7F) << shift + shift += 7 + p = p[1:] + } + if len(p) == 0 { + return &DecodingError{len(data), "unexpected EOF", nil} + } + s.value |= uint64(p[0]) << shift + p = p[1:] + } + if goType { + if len(p) < ptrsz { + return &DecodingError{len(data), "unexpected EOF", nil} + } + // fixed-width go type + if ptrsz == 8 { + s.gotype = order.Uint64(p[0:8]) + p = p[8:] + } else { + s.gotype = uint64(order.Uint32(p[0:4])) + p = p[4:] + } + } + } else { + // Value, symbol type. + s.value = uint64(order.Uint32(p[0:4])) + if len(p) < 5 { + return &DecodingError{len(data), "unexpected EOF", nil} + } + typ = p[4] + if typ&0x80 == 0 { + return &DecodingError{len(data) - len(p) + 4, "bad symbol type", typ} + } + typ &^= 0x80 + s.typ = typ + p = p[5:] + } + + // Name. var i int var nnul int for i = 0; i < len(p); i++ { @@ -142,13 +227,21 @@ } } } - if i+nnul+4 > len(p) { + if len(p) < i+nnul { return &DecodingError{len(data), "unexpected EOF", nil} } s.name = p[0:i] i += nnul - s.gotype = order.Uint32(p[i : i+4]) - p = p[i+4:] + p = p[i:] + + if !newTable { + if len(p) < 4 { + return &DecodingError{len(data), "unexpected EOF", nil} + } + // Go type. + s.gotype = uint64(order.Uint32(p[:4])) + p = p[4:] + } fn(s) } return nil diff -Naur gcc-4.8.1.orig/libgo/go/debug/macho/file.go gcc-4.8.1/libgo/go/debug/macho/file.go --- gcc-4.8.1.orig/libgo/go/debug/macho/file.go 2012-03-06 19:16:20.000000000 -0600 +++ gcc-4.8.1/libgo/go/debug/macho/file.go 2013-07-16 01:55:04.520470000 -0500 @@ -142,6 +142,8 @@ * Mach-O reader */ +// FormatError is returned by some operations if the data does +// not have the correct format for an object file. type FormatError struct { off int64 msg string diff -Naur gcc-4.8.1.orig/libgo/go/encoding/ascii85/ascii85.go gcc-4.8.1/libgo/go/encoding/ascii85/ascii85.go --- gcc-4.8.1.orig/libgo/go/encoding/ascii85/ascii85.go 2012-05-04 10:01:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/encoding/ascii85/ascii85.go 2013-07-16 01:55:04.520470000 -0500 @@ -296,5 +296,4 @@ nn, d.readErr = d.r.Read(d.buf[d.nbuf:]) d.nbuf += nn } - panic("unreachable") } diff -Naur gcc-4.8.1.orig/libgo/go/encoding/asn1/marshal.go gcc-4.8.1/libgo/go/encoding/asn1/marshal.go --- gcc-4.8.1.orig/libgo/go/encoding/asn1/marshal.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/asn1/marshal.go 2013-07-16 01:55:04.520470000 -0500 @@ -460,7 +460,6 @@ default: return marshalUTF8String(out, v.String()) } - return } return StructuralError{"unknown Go type"} diff -Naur gcc-4.8.1.orig/libgo/go/encoding/base32/base32.go gcc-4.8.1/libgo/go/encoding/base32/base32.go --- gcc-4.8.1.orig/libgo/go/encoding/base32/base32.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/encoding/base32/base32.go 2013-07-16 01:55:04.520470000 -0500 @@ -6,8 +6,10 @@ package base32 import ( + "bytes" "io" "strconv" + "strings" ) /* @@ -48,6 +50,13 @@ // It is typically used in DNS. var HexEncoding = NewEncoding(encodeHex) +var removeNewlinesMapper = func(r rune) rune { + if r == '\r' || r == '\n' { + return -1 + } + return r +} + /* * Encoder */ @@ -228,40 +237,47 @@ // decode is like Decode but returns an additional 'end' value, which // indicates if end-of-message padding was encountered and thus any -// additional data is an error. +// additional data is an error. This method assumes that src has been +// stripped of all supported whitespace ('\r' and '\n'). func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) { - osrc := src + olen := len(src) for len(src) > 0 && !end { // Decode quantum using the base32 alphabet var dbuf [8]byte dlen := 8 - // do the top bytes contain any data? for j := 0; j < 8; { if len(src) == 0 { - return n, false, CorruptInputError(len(osrc) - len(src) - j) + return n, false, CorruptInputError(olen - len(src) - j) } in := src[0] src = src[1:] - if in == '\r' || in == '\n' { - // Ignore this character. - continue - } if in == '=' && j >= 2 && len(src) < 8 { - // We've reached the end and there's - // padding, the rest should be padded - for k := 0; k < 8-j-1; k++ { + // We've reached the end and there's padding + if len(src)+j < 8-1 { + // not enough padding + return n, false, CorruptInputError(olen) + } + for k := 0; k < 8-1-j; k++ { if len(src) > k && src[k] != '=' { - return n, false, CorruptInputError(len(osrc) - len(src) + k - 1) + // incorrect padding + return n, false, CorruptInputError(olen - len(src) + k - 1) } } - dlen = j - end = true + dlen, end = j, true + // 7, 5 and 2 are not valid padding lengths, and so 1, 3 and 6 are not + // valid dlen values. See RFC 4648 Section 6 "Base 32 Encoding" listing + // the five valid padding lengths, and Section 9 "Illustrations and + // Examples" for an illustration for how the the 1st, 3rd and 6th base32 + // src bytes do not yield enough information to decode a dst byte. + if dlen == 1 || dlen == 3 || dlen == 6 { + return n, false, CorruptInputError(olen - len(src) - 1) + } break } dbuf[j] = enc.decodeMap[in] if dbuf[j] == 0xFF { - return n, false, CorruptInputError(len(osrc) - len(src) - 1) + return n, false, CorruptInputError(olen - len(src) - 1) } j++ } @@ -269,16 +285,16 @@ // Pack 8x 5-bit source blocks into 5 byte destination // quantum switch dlen { - case 7, 8: + case 8: dst[4] = dbuf[6]<<5 | dbuf[7] fallthrough - case 6, 5: + case 7: dst[3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3 fallthrough - case 4: + case 5: dst[2] = dbuf[3]<<4 | dbuf[4]>>1 fallthrough - case 3: + case 4: dst[1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4 fallthrough case 2: @@ -288,11 +304,11 @@ switch dlen { case 2: n += 1 - case 3, 4: + case 4: n += 2 case 5: n += 3 - case 6, 7: + case 7: n += 4 case 8: n += 5 @@ -307,12 +323,14 @@ // number of bytes successfully written and CorruptInputError. // New line characters (\r and \n) are ignored. func (enc *Encoding) Decode(dst, src []byte) (n int, err error) { + src = bytes.Map(removeNewlinesMapper, src) n, _, err = enc.decode(dst, src) return } // DecodeString returns the bytes represented by the base32 string s. func (enc *Encoding) DecodeString(s string) ([]byte, error) { + s = strings.Map(removeNewlinesMapper, s) dbuf := make([]byte, enc.DecodedLen(len(s))) n, err := enc.Decode(dbuf, []byte(s)) return dbuf[:n], err @@ -377,9 +395,34 @@ return n, d.err } +type newlineFilteringReader struct { + wrapped io.Reader +} + +func (r *newlineFilteringReader) Read(p []byte) (int, error) { + n, err := r.wrapped.Read(p) + for n > 0 { + offset := 0 + for i, b := range p[0:n] { + if b != '\r' && b != '\n' { + if i != offset { + p[offset] = b + } + offset++ + } + } + if offset > 0 { + return offset, err + } + // Previous buffer entirely whitespace, read again + n, err = r.wrapped.Read(p) + } + return n, err +} + // NewDecoder constructs a new base32 stream decoder. func NewDecoder(enc *Encoding, r io.Reader) io.Reader { - return &decoder{enc: enc, r: r} + return &decoder{enc: enc, r: &newlineFilteringReader{r}} } // DecodedLen returns the maximum length in bytes of the decoded data diff -Naur gcc-4.8.1.orig/libgo/go/encoding/base32/base32_test.go gcc-4.8.1/libgo/go/encoding/base32/base32_test.go --- gcc-4.8.1.orig/libgo/go/encoding/base32/base32_test.go 2012-02-09 02:19:58.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/base32/base32_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -8,6 +8,7 @@ "bytes" "io" "io/ioutil" + "strings" "testing" ) @@ -137,27 +138,48 @@ } func TestDecodeCorrupt(t *testing.T) { - type corrupt struct { - e string - p int - } - examples := []corrupt{ + testCases := []struct { + input string + offset int // -1 means no corruption. + }{ + {"", -1}, {"!!!!", 0}, {"x===", 0}, {"AA=A====", 2}, {"AAA=AAAA", 3}, {"MMMMMMMMM", 8}, {"MMMMMM", 0}, - } - - for _, e := range examples { - dbuf := make([]byte, StdEncoding.DecodedLen(len(e.e))) - _, err := StdEncoding.Decode(dbuf, []byte(e.e)) + {"A=", 1}, + {"AA=", 3}, + {"AA==", 4}, + {"AA===", 5}, + {"AAAA=", 5}, + {"AAAA==", 6}, + {"AAAAA=", 6}, + {"AAAAA==", 7}, + {"A=======", 1}, + {"AA======", -1}, + {"AAA=====", 3}, + {"AAAA====", -1}, + {"AAAAA===", -1}, + {"AAAAAA==", 6}, + {"AAAAAAA=", -1}, + {"AAAAAAAA", -1}, + } + for _, tc := range testCases { + dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input))) + _, err := StdEncoding.Decode(dbuf, []byte(tc.input)) + if tc.offset == -1 { + if err != nil { + t.Error("Decoder wrongly detected coruption in", tc.input) + } + continue + } switch err := err.(type) { case CorruptInputError: - testEqual(t, "Corruption in %q at offset %v, want %v", e.e, int(err), e.p) + testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset) default: - t.Error("Decoder failed to detect corruption in", e) + t.Error("Decoder failed to detect corruption in", tc) } } } @@ -195,9 +217,21 @@ } } +func testStringEncoding(t *testing.T, expected string, examples []string) { + for _, e := range examples { + buf, err := StdEncoding.DecodeString(e) + if err != nil { + t.Errorf("Decode(%q) failed: %v", e, err) + continue + } + if s := string(buf); s != expected { + t.Errorf("Decode(%q) = %q, want %q", e, s, expected) + } + } +} + func TestNewLineCharacters(t *testing.T) { // Each of these should decode to the string "sure", without errors. - const expected = "sure" examples := []string{ "ON2XEZI=", "ON2XEZI=\r", @@ -209,14 +243,44 @@ "ON2XEZ\nI=", "ON2XEZI\n=", } - for _, e := range examples { - buf, err := StdEncoding.DecodeString(e) - if err != nil { - t.Errorf("Decode(%q) failed: %v", e, err) - continue - } - if s := string(buf); s != expected { - t.Errorf("Decode(%q) = %q, want %q", e, s, expected) - } + testStringEncoding(t, "sure", examples) + + // Each of these should decode to the string "foobar", without errors. + examples = []string{ + "MZXW6YTBOI======", + "MZXW6YTBOI=\r\n=====", + } + testStringEncoding(t, "foobar", examples) +} + +func TestDecoderIssue4779(t *testing.T) { + encoded := `JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4 +RAMFSGS4DJONUWG2LOM4QGK3DJOQWCA43FMQQGI3YKMVUXK43NN5SCA5DFNVYG64RANFXGG2LENFSH +K3TUEB2XIIDMMFRG64TFEBSXIIDEN5WG64TFEBWWCZ3OMEQGC3DJOF2WCLRAKV2CAZLONFWQUYLEEB +WWS3TJNUQHMZLONFQW2LBAOF2WS4ZANZXXG5DSOVSCAZLYMVZGG2LUMF2GS33OEB2WY3DBNVRW6IDM +MFRG64TJOMQG42LTNEQHK5AKMFWGS4LVNFYCAZLYEBSWCIDDN5WW233EN4QGG33OONSXC5LBOQXCAR +DVNFZSAYLVORSSA2LSOVZGKIDEN5WG64RANFXAU4TFOBZGK2DFNZSGK4TJOQQGS3RAOZXWY5LQORQX +IZJAOZSWY2LUEBSXG43FEBRWS3DMOVWSAZDPNRXXEZJAMV2SAZTVM5UWC5BANZ2WY3DBBJYGC4TJMF +2HK4ROEBCXQY3FOB2GK5LSEBZWS3TUEBXWGY3BMVRWC5BAMN2XA2LEMF2GC5BANZXW4IDQOJXWSZDF +NZ2CYIDTOVXHIIDJNYFGG5LMOBQSA4LVNEQG6ZTGNFRWSYJAMRSXGZLSOVXHIIDNN5WGY2LUEBQW42 +LNEBUWIIDFON2CA3DBMJXXE5LNFY== +====` + encodedShort := strings.Replace(encoded, "\n", "", -1) + + dec := NewDecoder(StdEncoding, bytes.NewBufferString(encoded)) + res1, err := ioutil.ReadAll(dec) + if err != nil { + t.Errorf("ReadAll failed: %v", err) + } + + dec = NewDecoder(StdEncoding, bytes.NewBufferString(encodedShort)) + var res2 []byte + res2, err = ioutil.ReadAll(dec) + if err != nil { + t.Errorf("ReadAll failed: %v", err) + } + + if !bytes.Equal(res1, res2) { + t.Error("Decoded results not equal") } } diff -Naur gcc-4.8.1.orig/libgo/go/encoding/base64/base64.go gcc-4.8.1/libgo/go/encoding/base64/base64.go --- gcc-4.8.1.orig/libgo/go/encoding/base64/base64.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/encoding/base64/base64.go 2013-07-16 01:55:04.520470000 -0500 @@ -6,8 +6,10 @@ package base64 import ( + "bytes" "io" "strconv" + "strings" ) /* @@ -49,6 +51,13 @@ // It is typically used in URLs and file names. var URLEncoding = NewEncoding(encodeURL) +var removeNewlinesMapper = func(r rune) rune { + if r == '\r' || r == '\n' { + return -1 + } + return r +} + /* * Encoder */ @@ -208,9 +217,10 @@ // decode is like Decode but returns an additional 'end' value, which // indicates if end-of-message padding was encountered and thus any -// additional data is an error. +// additional data is an error. This method assumes that src has been +// stripped of all supported whitespace ('\r' and '\n'). func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) { - osrc := src + olen := len(src) for len(src) > 0 && !end { // Decode quantum using the base64 alphabet var dbuf [4]byte @@ -218,32 +228,26 @@ for j := 0; j < 4; { if len(src) == 0 { - return n, false, CorruptInputError(len(osrc) - len(src) - j) + return n, false, CorruptInputError(olen - len(src) - j) } in := src[0] src = src[1:] - if in == '\r' || in == '\n' { - // Ignore this character. - continue - } if in == '=' && j >= 2 && len(src) < 4 { - // We've reached the end and there's - // padding - if len(src) == 0 && j == 2 { + // We've reached the end and there's padding + if len(src)+j < 4-1 { // not enough padding - return n, false, CorruptInputError(len(osrc)) + return n, false, CorruptInputError(olen) } if len(src) > 0 && src[0] != '=' { // incorrect padding - return n, false, CorruptInputError(len(osrc) - len(src) - 1) + return n, false, CorruptInputError(olen - len(src) - 1) } - dlen = j - end = true + dlen, end = j, true break } dbuf[j] = enc.decodeMap[in] if dbuf[j] == 0xFF { - return n, false, CorruptInputError(len(osrc) - len(src) - 1) + return n, false, CorruptInputError(olen - len(src) - 1) } j++ } @@ -273,12 +277,14 @@ // number of bytes successfully written and CorruptInputError. // New line characters (\r and \n) are ignored. func (enc *Encoding) Decode(dst, src []byte) (n int, err error) { + src = bytes.Map(removeNewlinesMapper, src) n, _, err = enc.decode(dst, src) return } // DecodeString returns the bytes represented by the base64 string s. func (enc *Encoding) DecodeString(s string) ([]byte, error) { + s = strings.Map(removeNewlinesMapper, s) dbuf := make([]byte, enc.DecodedLen(len(s))) n, err := enc.Decode(dbuf, []byte(s)) return dbuf[:n], err @@ -343,9 +349,34 @@ return n, d.err } +type newlineFilteringReader struct { + wrapped io.Reader +} + +func (r *newlineFilteringReader) Read(p []byte) (int, error) { + n, err := r.wrapped.Read(p) + for n > 0 { + offset := 0 + for i, b := range p[0:n] { + if b != '\r' && b != '\n' { + if i != offset { + p[offset] = b + } + offset++ + } + } + if offset > 0 { + return offset, err + } + // Previous buffer entirely whitespace, read again + n, err = r.wrapped.Read(p) + } + return n, err +} + // NewDecoder constructs a new base64 stream decoder. func NewDecoder(enc *Encoding, r io.Reader) io.Reader { - return &decoder{enc: enc, r: r} + return &decoder{enc: enc, r: &newlineFilteringReader{r}} } // DecodedLen returns the maximum length in bytes of the decoded data diff -Naur gcc-4.8.1.orig/libgo/go/encoding/base64/base64_test.go gcc-4.8.1/libgo/go/encoding/base64/base64_test.go --- gcc-4.8.1.orig/libgo/go/encoding/base64/base64_test.go 2012-06-25 11:20:03.000000000 -0500 +++ gcc-4.8.1/libgo/go/encoding/base64/base64_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -9,6 +9,7 @@ "errors" "io" "io/ioutil" + "strings" "testing" "time" ) @@ -142,11 +143,11 @@ } func TestDecodeCorrupt(t *testing.T) { - type corrupt struct { - e string - p int - } - examples := []corrupt{ + testCases := []struct { + input string + offset int // -1 means no corruption. + }{ + {"", -1}, {"!!!!", 0}, {"x===", 1}, {"AA=A", 2}, @@ -154,18 +155,27 @@ {"AAAAA", 4}, {"AAAAAA", 4}, {"A=", 1}, + {"A==", 1}, {"AA=", 3}, + {"AA==", -1}, + {"AAA=", -1}, + {"AAAA", -1}, {"AAAAAA=", 7}, } - - for _, e := range examples { - dbuf := make([]byte, StdEncoding.DecodedLen(len(e.e))) - _, err := StdEncoding.Decode(dbuf, []byte(e.e)) + for _, tc := range testCases { + dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input))) + _, err := StdEncoding.Decode(dbuf, []byte(tc.input)) + if tc.offset == -1 { + if err != nil { + t.Error("Decoder wrongly detected coruption in", tc.input) + } + continue + } switch err := err.(type) { case CorruptInputError: - testEqual(t, "Corruption in %q at offset %v, want %v", e.e, int(err), e.p) + testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset) default: - t.Error("Decoder failed to detect corruption in", e) + t.Error("Decoder failed to detect corruption in", tc) } } } @@ -216,6 +226,8 @@ "c3V\nyZ\rQ==", "c3VyZ\nQ==", "c3VyZQ\n==", + "c3VyZQ=\n=", + "c3VyZQ=\r\n\r\n=", } for _, e := range examples { buf, err := StdEncoding.DecodeString(e) @@ -257,6 +269,7 @@ wantErr := errors.New("my error") next <- nextRead{5, nil} next <- nextRead{10, wantErr} + next <- nextRead{0, wantErr} d := NewDecoder(StdEncoding, &faultInjectReader{ source: "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", // twas brillig... nextc: next, @@ -275,3 +288,40 @@ t.Errorf("timeout; Decoder blocked without returning an error") } } + +func TestDecoderIssue4779(t *testing.T) { + encoded := `CP/EAT8AAAEF +AQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAAB +BAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHx +Y3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm +9jdHV2d3h5ent8fX5/cRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS +0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSFtJXE1OT0 +pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x//aAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkJ+Tj +1kiy1jCJJDnAcCTykpKkuQ6p/jN6FgmxlNduXawwAzaGH+V6jn/R/wCt71zdn+N/qL3kVYFNYB4N +ji6PDVjWpKp9TSXnvTf8bFNjg3qOEa2n6VlLpj/rT/pf567DpX1i6L1hs9Py67X8mqdtg/rUWbbf ++gkp0kkkklKSSSSUpJJJJT//0PVUkkklKVLq3WMDpGI7KzrNjADtYNXvI/Mqr/Pd/q9W3vaxjnvM +NaCXE9gNSvGPrf8AWS3qmba5jjsJhoB0DAf0NDf6sevf+/lf8Hj0JJATfWT6/dV6oXU1uOLQeKKn +EQP+Hubtfe/+R7Mf/g7f5xcocp++Z11JMCJPgFBxOg7/AOuqDx8I/ikpkXkmSdU8mJIJA/O8EMAy +j+mSARB/17pKVXYWHXjsj7yIex0PadzXMO1zT5KHoNA3HT8ietoGhgjsfA+CSnvvqh/jJtqsrwOv +2b6NGNzXfTYexzJ+nU7/ALkf4P8Awv6P9KvTQQ4AgyDqCF85Pho3CTB7eHwXoH+LT65uZbX9X+o2 +bqbPb06551Y4 +` + encodedShort := strings.Replace(encoded, "\n", "", -1) + + dec := NewDecoder(StdEncoding, bytes.NewBufferString(encoded)) + res1, err := ioutil.ReadAll(dec) + if err != nil { + t.Errorf("ReadAll failed: %v", err) + } + + dec = NewDecoder(StdEncoding, bytes.NewBufferString(encodedShort)) + var res2 []byte + res2, err = ioutil.ReadAll(dec) + if err != nil { + t.Errorf("ReadAll failed: %v", err) + } + + if !bytes.Equal(res1, res2) { + t.Error("Decoded results not equal") + } +} diff -Naur gcc-4.8.1.orig/libgo/go/encoding/binary/binary.go gcc-4.8.1/libgo/go/encoding/binary/binary.go --- gcc-4.8.1.orig/libgo/go/encoding/binary/binary.go 2012-12-12 17:13:29.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/binary/binary.go 2013-07-16 01:55:04.520470000 -0500 @@ -167,9 +167,9 @@ default: return errors.New("binary.Read: invalid type " + d.Type().String()) } - size := dataSize(v) - if size < 0 { - return errors.New("binary.Read: invalid type " + v.Type().String()) + size, err := dataSize(v) + if err != nil { + return errors.New("binary.Read: " + err.Error()) } d := &decoder{order: order, buf: make([]byte, size)} if _, err := io.ReadFull(r, d.buf); err != nil { @@ -247,64 +247,68 @@ // Fallback to reflect-based encoding. v := reflect.Indirect(reflect.ValueOf(data)) - size := dataSize(v) - if size < 0 { - return errors.New("binary.Write: invalid type " + v.Type().String()) + size, err := dataSize(v) + if err != nil { + return errors.New("binary.Write: " + err.Error()) } buf := make([]byte, size) e := &encoder{order: order, buf: buf} e.value(v) - _, err := w.Write(buf) + _, err = w.Write(buf) return err } // Size returns how many bytes Write would generate to encode the value v, which // must be a fixed-size value or a slice of fixed-size values, or a pointer to such data. func Size(v interface{}) int { - return dataSize(reflect.Indirect(reflect.ValueOf(v))) + n, err := dataSize(reflect.Indirect(reflect.ValueOf(v))) + if err != nil { + return -1 + } + return n } // dataSize returns the number of bytes the actual data represented by v occupies in memory. // For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice // it returns the length of the slice times the element size and does not count the memory // occupied by the header. -func dataSize(v reflect.Value) int { +func dataSize(v reflect.Value) (int, error) { if v.Kind() == reflect.Slice { - elem := sizeof(v.Type().Elem()) - if elem < 0 { - return -1 + elem, err := sizeof(v.Type().Elem()) + if err != nil { + return 0, err } - return v.Len() * elem + return v.Len() * elem, nil } return sizeof(v.Type()) } -func sizeof(t reflect.Type) int { +func sizeof(t reflect.Type) (int, error) { switch t.Kind() { case reflect.Array: - n := sizeof(t.Elem()) - if n < 0 { - return -1 + n, err := sizeof(t.Elem()) + if err != nil { + return 0, err } - return t.Len() * n + return t.Len() * n, nil case reflect.Struct: sum := 0 for i, n := 0, t.NumField(); i < n; i++ { - s := sizeof(t.Field(i).Type) - if s < 0 { - return -1 + s, err := sizeof(t.Field(i).Type) + if err != nil { + return 0, err } sum += s } - return sum + return sum, nil case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: - return int(t.Size()) + return int(t.Size()), nil } - return -1 + return 0, errors.New("invalid type " + t.String()) } type coder struct { @@ -514,11 +518,12 @@ } func (d *decoder) skip(v reflect.Value) { - d.buf = d.buf[dataSize(v):] + n, _ := dataSize(v) + d.buf = d.buf[n:] } func (e *encoder) skip(v reflect.Value) { - n := dataSize(v) + n, _ := dataSize(v) for i := range e.buf[0:n] { e.buf[i] = 0 } diff -Naur gcc-4.8.1.orig/libgo/go/encoding/binary/binary_test.go gcc-4.8.1/libgo/go/encoding/binary/binary_test.go --- gcc-4.8.1.orig/libgo/go/encoding/binary/binary_test.go 2013-02-10 00:02:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/binary/binary_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -9,6 +9,7 @@ "io" "math" "reflect" + "strings" "testing" ) @@ -149,8 +150,14 @@ tv := reflect.Indirect(reflect.ValueOf(ts)) for i, n := 0, tv.NumField(); i < n; i++ { + typ := tv.Field(i).Type().String() + if typ == "[4]int" { + typ = "int" // the problem is int, not the [4] + } if err := Write(buf, BigEndian, tv.Field(i).Interface()); err == nil { t.Errorf("WriteT.%v: have err == nil, want non-nil", tv.Field(i).Type()) + } else if !strings.Contains(err.Error(), typ) { + t.Errorf("WriteT: have err == %q, want it to mention %s", err, typ) } } } @@ -238,7 +245,7 @@ bsr := &byteSliceReader{} var buf bytes.Buffer Write(&buf, BigEndian, &s) - n := dataSize(reflect.ValueOf(s)) + n, _ := dataSize(reflect.ValueOf(s)) b.SetBytes(int64(n)) t := s b.ResetTimer() diff -Naur gcc-4.8.1.orig/libgo/go/encoding/binary/varint.go gcc-4.8.1/libgo/go/encoding/binary/varint.go --- gcc-4.8.1.orig/libgo/go/encoding/binary/varint.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/binary/varint.go 2013-07-16 01:55:04.520470000 -0500 @@ -120,7 +120,6 @@ x |= uint64(b&0x7f) << s s += 7 } - panic("unreachable") } // ReadVarint reads an encoded signed integer from r and returns it as an int64. diff -Naur gcc-4.8.1.orig/libgo/go/encoding/csv/reader.go gcc-4.8.1/libgo/go/encoding/csv/reader.go --- gcc-4.8.1.orig/libgo/go/encoding/csv/reader.go 2012-03-30 16:27:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/encoding/csv/reader.go 2013-07-16 01:55:04.520470000 -0500 @@ -171,7 +171,6 @@ } records = append(records, record) } - panic("unreachable") } // readRune reads one rune from r, folding \r\n to \n and keeping track @@ -213,7 +212,6 @@ return nil } } - panic("unreachable") } // parseRecord reads and parses a single csv record from r. @@ -250,7 +248,6 @@ return nil, err } } - panic("unreachable") } // parseField parses the next field in the record. The read field is diff -Naur gcc-4.8.1.orig/libgo/go/encoding/gob/codec_test.go gcc-4.8.1/libgo/go/encoding/gob/codec_test.go --- gcc-4.8.1.orig/libgo/go/encoding/gob/codec_test.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/encoding/gob/codec_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -1191,10 +1191,8 @@ if v1 != nil || v2 != nil { t.Errorf("item %d inconsistent nils", i) } - continue - if v1.Square() != v2.Square() { - t.Errorf("item %d inconsistent values: %v %v", i, v1, v2) - } + } else if v1.Square() != v2.Square() { + t.Errorf("item %d inconsistent values: %v %v", i, v1, v2) } } } diff -Naur gcc-4.8.1.orig/libgo/go/encoding/gob/decode.go gcc-4.8.1/libgo/go/encoding/gob/decode.go --- gcc-4.8.1.orig/libgo/go/encoding/gob/decode.go 2012-12-21 19:15:33.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/gob/decode.go 2013-07-16 01:55:04.520470000 -0500 @@ -1066,7 +1066,6 @@ case reflect.Struct: return true } - return true } // typeString returns a human-readable description of the type identified by remoteId. diff -Naur gcc-4.8.1.orig/libgo/go/encoding/gob/gobencdec_test.go gcc-4.8.1/libgo/go/encoding/gob/gobencdec_test.go --- gcc-4.8.1.orig/libgo/go/encoding/gob/gobencdec_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/gob/gobencdec_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -1,4 +1,4 @@ -// Copyright 20011 The Go Authors. All rights reserved. +// 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. @@ -348,7 +348,7 @@ t.Fatal("decode error:", err) } if y.G.s != "XYZ" { - t.Fatalf("expected `XYZ` got %c", y.G.s) + t.Fatalf("expected `XYZ` got %q", y.G.s) } } diff -Naur gcc-4.8.1.orig/libgo/go/encoding/gob/timing_test.go gcc-4.8.1/libgo/go/encoding/gob/timing_test.go --- gcc-4.8.1.orig/libgo/go/encoding/gob/timing_test.go 2012-12-12 17:13:29.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/gob/timing_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -50,49 +50,51 @@ } func TestCountEncodeMallocs(t *testing.T) { - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1)) + if runtime.GOMAXPROCS(0) > 1 { + t.Skip("skipping; GOMAXPROCS>1") + } + + const N = 1000 + var buf bytes.Buffer enc := NewEncoder(&buf) bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")} - memstats := new(runtime.MemStats) - runtime.ReadMemStats(memstats) - mallocs := 0 - memstats.Mallocs - const count = 1000 - for i := 0; i < count; i++ { + + allocs := testing.AllocsPerRun(N, func() { err := enc.Encode(bench) if err != nil { t.Fatal("encode:", err) } - } - runtime.ReadMemStats(memstats) - mallocs += memstats.Mallocs - fmt.Printf("mallocs per encode of type Bench: %d\n", mallocs/count) + }) + fmt.Printf("mallocs per encode of type Bench: %v\n", allocs) } func TestCountDecodeMallocs(t *testing.T) { - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1)) + if runtime.GOMAXPROCS(0) > 1 { + t.Skip("skipping; GOMAXPROCS>1") + } + + const N = 1000 + var buf bytes.Buffer enc := NewEncoder(&buf) bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")} - const count = 1000 - for i := 0; i < count; i++ { + + // Fill the buffer with enough to decode + testing.AllocsPerRun(N, func() { err := enc.Encode(bench) if err != nil { t.Fatal("encode:", err) } - } + }) + dec := NewDecoder(&buf) - memstats := new(runtime.MemStats) - runtime.ReadMemStats(memstats) - mallocs := 0 - memstats.Mallocs - for i := 0; i < count; i++ { + allocs := testing.AllocsPerRun(N, func() { *bench = Bench{} err := dec.Decode(&bench) if err != nil { t.Fatal("decode:", err) } - } - runtime.ReadMemStats(memstats) - mallocs += memstats.Mallocs - fmt.Printf("mallocs per decode of type Bench: %d\n", mallocs/count) + }) + fmt.Printf("mallocs per decode of type Bench: %v\n", allocs) } diff -Naur gcc-4.8.1.orig/libgo/go/encoding/gob/type.go gcc-4.8.1/libgo/go/encoding/gob/type.go --- gcc-4.8.1.orig/libgo/go/encoding/gob/type.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/encoding/gob/type.go 2013-07-16 01:55:04.520470000 -0500 @@ -526,7 +526,6 @@ default: return nil, errors.New("gob NewTypeObject can't handle type: " + rt.String()) } - return nil, nil } // isExported reports whether this is an exported - upper case - name. diff -Naur gcc-4.8.1.orig/libgo/go/encoding/json/decode.go gcc-4.8.1/libgo/go/encoding/json/decode.go --- gcc-4.8.1.orig/libgo/go/encoding/json/decode.go 2013-01-29 19:37:13.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/json/decode.go 2013-07-16 01:55:04.520470000 -0500 @@ -33,6 +33,10 @@ // the value pointed at by the pointer. If the pointer is nil, Unmarshal // allocates a new value for it to point to. // +// To unmarshal JSON into a struct, Unmarshal matches incoming object +// keys to the keys used by Marshal (either the struct field name or its tag), +// preferring an exact match but also accepting a case-insensitive match. +// // To unmarshal JSON into an interface value, Unmarshal unmarshals // the JSON into the concrete value contained in the interface value. // If the interface value is nil, that is, has no concrete value stored in it, @@ -51,17 +55,22 @@ // If no more serious errors are encountered, Unmarshal returns // an UnmarshalTypeError describing the earliest such error. // +// When unmarshaling quoted strings, invalid UTF-8 or +// invalid UTF-16 surrogate pairs are not treated as an error. +// Instead, they are replaced by the Unicode replacement +// character U+FFFD. +// func Unmarshal(data []byte, v interface{}) error { - d := new(decodeState).init(data) - - // Quick check for well-formedness. + // Check for well-formedness. // Avoids filling out half a data structure // before discovering a JSON syntax error. + var d decodeState err := checkValid(data, &d.scan) if err != nil { return err } + d.init(data) return d.unmarshal(v) } @@ -252,6 +261,16 @@ } d.scan.step(&d.scan, '"') d.scan.step(&d.scan, '"') + + n := len(d.scan.parseState) + if n > 0 && d.scan.parseState[n-1] == parseObjectKey { + // d.scan thinks we just read an object key; finish the object + d.scan.step(&d.scan, ':') + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '"') + d.scan.step(&d.scan, '}') + } + return } @@ -730,6 +749,7 @@ switch d.scanWhile(scanSkipSpace) { default: d.error(errPhase) + panic("unreachable") case scanBeginArray: return d.arrayInterface() case scanBeginObject: @@ -737,12 +757,11 @@ case scanBeginLiteral: return d.literalInterface() } - panic("unreachable") } // arrayInterface is like array but returns []interface{}. func (d *decodeState) arrayInterface() []interface{} { - var v []interface{} + var v = make([]interface{}, 0) for { // Look ahead for ] - can only happen on first iteration. op := d.scanWhile(scanSkipSpace) @@ -849,7 +868,6 @@ } return n } - panic("unreachable") } // getu4 decodes \uXXXX from the beginning of s, returning the hex value, diff -Naur gcc-4.8.1.orig/libgo/go/encoding/json/decode_test.go gcc-4.8.1/libgo/go/encoding/json/decode_test.go --- gcc-4.8.1.orig/libgo/go/encoding/json/decode_test.go 2013-01-29 19:37:13.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/json/decode_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -11,6 +11,7 @@ "reflect" "strings" "testing" + "time" ) type T struct { @@ -29,7 +30,7 @@ F3 Number } -// ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshalling with and +// ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and // without UseNumber var ifaceNumAsFloat64 = map[string]interface{}{ "k1": float64(1), @@ -239,6 +240,12 @@ {in: `[1, 2, 3]`, ptr: new([1]int), out: [1]int{1}}, {in: `[1, 2, 3]`, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}}, + // empty array to interface test + {in: `[]`, ptr: new([]interface{}), out: []interface{}{}}, + {in: `null`, ptr: new([]interface{}), out: []interface{}(nil)}, + {in: `{"T":[]}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}}, + {in: `{"T":null}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": interface{}(nil)}}, + // composite tests {in: allValueIndent, ptr: new(All), out: allValue}, {in: allValueCompact, ptr: new(All), out: allValue}, @@ -323,6 +330,43 @@ ptr: new(S10), out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}}, }, + + // invalid UTF-8 is coerced to valid UTF-8. + { + in: "\"hello\xffworld\"", + ptr: new(string), + out: "hello\ufffdworld", + }, + { + in: "\"hello\xc2\xc2world\"", + ptr: new(string), + out: "hello\ufffd\ufffdworld", + }, + { + in: "\"hello\xc2\xffworld\"", + ptr: new(string), + out: "hello\ufffd\ufffdworld", + }, + { + in: "\"hello\\ud800world\"", + ptr: new(string), + out: "hello\ufffdworld", + }, + { + in: "\"hello\\ud800\\ud800world\"", + ptr: new(string), + out: "hello\ufffd\ufffdworld", + }, + { + in: "\"hello\\ud800\\ud800world\"", + ptr: new(string), + out: "hello\ufffd\ufffdworld", + }, + { + in: "\"hello\xed\xa0\x80\xed\xb0\x80world\"", + ptr: new(string), + out: "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld", + }, } func TestMarshal(t *testing.T) { @@ -1107,3 +1151,43 @@ t.Errorf("got %q, want %q", out, want) } } + +// Time3339 is a time.Time which encodes to and from JSON +// as an RFC 3339 time in UTC. +type Time3339 time.Time + +func (t *Time3339) UnmarshalJSON(b []byte) error { + if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { + return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b) + } + tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1])) + if err != nil { + return err + } + *t = Time3339(tm) + return nil +} + +func TestUnmarshalJSONLiteralError(t *testing.T) { + var t3 Time3339 + err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3) + if err == nil { + t.Fatalf("expected error; got time %v", time.Time(t3)) + } + if !strings.Contains(err.Error(), "range") { + t.Errorf("got err = %v; want out of range error", err) + } +} + +// Test that extra object elements in an array do not result in a +// "data changing underfoot" error. +// Issue 3717 +func TestSkipArrayObjects(t *testing.T) { + json := `[{}]` + var dest [0]interface{} + + err := Unmarshal([]byte(json), &dest) + if err != nil { + t.Errorf("got error %q, want nil", err) + } +} diff -Naur gcc-4.8.1.orig/libgo/go/encoding/json/encode.go gcc-4.8.1/libgo/go/encoding/json/encode.go --- gcc-4.8.1.orig/libgo/go/encoding/json/encode.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/json/encode.go 2013-07-16 01:55:04.520470000 -0500 @@ -3,7 +3,8 @@ // license that can be found in the LICENSE file. // Package json implements encoding and decoding of JSON objects as defined in -// RFC 4627. +// RFC 4627. The mapping between JSON objects and Go values is described +// in the documentation for the Marshal and Unmarshal functions. // // See "JSON and Go" for an introduction to this package: // http://golang.org/doc/articles/json_and_go.html @@ -38,8 +39,8 @@ // // Floating point, integer, and Number values encode as JSON numbers. // -// String values encode as JSON strings, with each invalid UTF-8 sequence -// replaced by the encoding of the Unicode replacement character U+FFFD. +// String values encode as JSON strings. InvalidUTF8Error will be returned +// if an invalid UTF-8 sequence is encountered. // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" // to keep some browsers from misinterpreting JSON output as HTML. // @@ -86,9 +87,21 @@ // underscores and slashes. // // Anonymous struct fields are usually marshaled as if their inner exported fields -// were fields in the outer struct, subject to the usual Go visibility rules. +// were fields in the outer struct, subject to the usual Go visibility rules amended +// as described in the next paragraph. // An anonymous struct field with a name given in its JSON tag is treated as -// having that name instead of as anonymous. +// having that name, rather than being anonymous. +// +// The Go visibility rules for struct fields are amended for JSON when +// deciding which field to marshal or unmarshal. If there are +// multiple fields at the same level, and that level is the least +// nested (and would therefore be the nesting level selected by the +// usual Go rules), the following extra rules apply: +// +// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, +// even if there are multiple untagged fields that would otherwise conflict. +// 2) If there is exactly one field (tagged or not according to the first rule), that is selected. +// 3) Otherwise there are multiple fields, and all are ignored; no error occurs. // // Handling of anonymous struct fields is new in Go 1.1. // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of @@ -187,8 +200,10 @@ return "json: unsupported value: " + e.Str } +// An InvalidUTF8Error is returned by Marshal when attempting +// to encode a string value with invalid UTF-8 sequences. type InvalidUTF8Error struct { - S string + S string // the whole string value that caused the error } func (e *InvalidUTF8Error) Error() string { @@ -654,27 +669,78 @@ sort.Sort(byName(fields)) - // Remove fields with annihilating name collisions - // and also fields shadowed by fields with explicit JSON tags. - name := "" + // Delete all fields that are hidden by the Go rules for embedded fields, + // except that fields with JSON tags are promoted. + + // The fields are sorted in primary order of name, secondary order + // of field index length. Loop over names; for each name, delete + // hidden fields by choosing the one dominant field that survives. out := fields[:0] - for _, f := range fields { - if f.name != name { - name = f.name - out = append(out, f) + for advance, i := 0, 0; i < len(fields); i += advance { + // One iteration per name. + // Find the sequence of fields with the name of this first field. + fi := fields[i] + name := fi.name + for advance = 1; i+advance < len(fields); advance++ { + fj := fields[i+advance] + if fj.name != name { + break + } + } + if advance == 1 { // Only one field with this name + out = append(out, fi) continue } - if n := len(out); n > 0 && out[n-1].name == name && (!out[n-1].tag || f.tag) { - out = out[:n-1] + dominant, ok := dominantField(fields[i : i+advance]) + if ok { + out = append(out, dominant) } } - fields = out + fields = out sort.Sort(byIndex(fields)) return fields } +// dominantField looks through the fields, all of which are known to +// have the same name, to find the single field that dominates the +// others using Go's embedding rules, modified by the presence of +// JSON tags. If there are multiple top-level fields, the boolean +// will be false: This condition is an error in Go and we skip all +// the fields. +func dominantField(fields []field) (field, bool) { + // The fields are sorted in increasing index-length order. The winner + // must therefore be one with the shortest index length. Drop all + // longer entries, which is easy: just truncate the slice. + length := len(fields[0].index) + tagged := -1 // Index of first tagged field. + for i, f := range fields { + if len(f.index) > length { + fields = fields[:i] + break + } + if f.tag { + if tagged >= 0 { + // Multiple tagged fields at the same level: conflict. + // Return no field. + return field{}, false + } + tagged = i + } + } + if tagged >= 0 { + return fields[tagged], true + } + // All remaining fields have the same length. If there's more than one, + // we have a conflict (two fields named "X" at the same level) and we + // return no field. + if len(fields) > 1 { + return field{}, false + } + return fields[0], true +} + var fieldCache struct { sync.RWMutex m map[reflect.Type][]field diff -Naur gcc-4.8.1.orig/libgo/go/encoding/json/encode_test.go gcc-4.8.1/libgo/go/encoding/json/encode_test.go --- gcc-4.8.1.orig/libgo/go/encoding/json/encode_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/json/encode_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -206,3 +206,107 @@ t.Errorf("got %q, want %q", got, want) } } + +type BugA struct { + S string +} + +type BugB struct { + BugA + S string +} + +type BugC struct { + S string +} + +// Legal Go: We never use the repeated embedded field (S). +type BugX struct { + A int + BugA + BugB +} + +// Issue 5245. +func TestEmbeddedBug(t *testing.T) { + v := BugB{ + BugA{"A"}, + "B", + } + b, err := Marshal(v) + if err != nil { + t.Fatal("Marshal:", err) + } + want := `{"S":"B"}` + got := string(b) + if got != want { + t.Fatalf("Marshal: got %s want %s", got, want) + } + // Now check that the duplicate field, S, does not appear. + x := BugX{ + A: 23, + } + b, err = Marshal(x) + if err != nil { + t.Fatal("Marshal:", err) + } + want = `{"A":23}` + got = string(b) + if got != want { + t.Fatalf("Marshal: got %s want %s", got, want) + } +} + +type BugD struct { // Same as BugA after tagging. + XXX string `json:"S"` +} + +// BugD's tagged S field should dominate BugA's. +type BugY struct { + BugA + BugD +} + +// Test that a field with a tag dominates untagged fields. +func TestTaggedFieldDominates(t *testing.T) { + v := BugY{ + BugA{"BugA"}, + BugD{"BugD"}, + } + b, err := Marshal(v) + if err != nil { + t.Fatal("Marshal:", err) + } + want := `{"S":"BugD"}` + got := string(b) + if got != want { + t.Fatalf("Marshal: got %s want %s", got, want) + } +} + +// There are no tags here, so S should not appear. +type BugZ struct { + BugA + BugC + BugY // Contains a tagged S field through BugD; should not dominate. +} + +func TestDuplicatedFieldDisappears(t *testing.T) { + v := BugZ{ + BugA{"BugA"}, + BugC{"BugC"}, + BugY{ + BugA{"nested BugA"}, + BugD{"nested BugD"}, + }, + } + b, err := Marshal(v) + if err != nil { + t.Fatal("Marshal:", err) + } + want := `{}` + got := string(b) + if got != want { + t.Fatalf("Marshal: got %s want %s", got, want) + } +} diff -Naur gcc-4.8.1.orig/libgo/go/encoding/json/scanner_test.go gcc-4.8.1/libgo/go/encoding/json/scanner_test.go --- gcc-4.8.1.orig/libgo/go/encoding/json/scanner_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/json/scanner_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -277,9 +277,6 @@ if f > n { f = n } - if n > 0 && f == 0 { - f = 1 - } x := make([]interface{}, f) for i := range x { x[i] = genValue(((i+1)*n)/f - (i*n)/f) diff -Naur gcc-4.8.1.orig/libgo/go/encoding/xml/marshal.go gcc-4.8.1/libgo/go/encoding/xml/marshal.go --- gcc-4.8.1.orig/libgo/go/encoding/xml/marshal.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/xml/marshal.go 2013-07-16 01:55:04.520470000 -0500 @@ -81,8 +81,7 @@ func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { var b bytes.Buffer enc := NewEncoder(&b) - enc.prefix = prefix - enc.indent = indent + enc.Indent(prefix, indent) if err := enc.Encode(v); err != nil { return nil, err } @@ -99,6 +98,14 @@ return &Encoder{printer{Writer: bufio.NewWriter(w)}} } +// Indent sets the encoder to generate XML in which each element +// begins on a new indented line that starts with prefix and is followed by +// one or more copies of indent according to the nesting depth. +func (enc *Encoder) Indent(prefix, indent string) { + enc.prefix = prefix + enc.indent = indent +} + // Encode writes the XML encoding of v to the stream. // // See the documentation for Marshal for details about the conversion @@ -113,10 +120,76 @@ type printer struct { *bufio.Writer + seq int indent string prefix string depth int indentedIn bool + putNewline bool + attrNS map[string]string // map prefix -> name space + attrPrefix map[string]string // map name space -> prefix +} + +// createAttrPrefix finds the name space prefix attribute to use for the given name space, +// defining a new prefix if necessary. It returns the prefix and whether it is new. +func (p *printer) createAttrPrefix(url string) (prefix string, isNew bool) { + if prefix = p.attrPrefix[url]; prefix != "" { + return prefix, false + } + + // The "http://www.w3.org/XML/1998/namespace" name space is predefined as "xml" + // and must be referred to that way. + // (The "http://www.w3.org/2000/xmlns/" name space is also predefined as "xmlns", + // but users should not be trying to use that one directly - that's our job.) + if url == xmlURL { + return "xml", false + } + + // Need to define a new name space. + if p.attrPrefix == nil { + p.attrPrefix = make(map[string]string) + p.attrNS = make(map[string]string) + } + + // Pick a name. We try to use the final element of the path + // but fall back to _. + prefix = strings.TrimRight(url, "/") + if i := strings.LastIndex(prefix, "/"); i >= 0 { + prefix = prefix[i+1:] + } + if prefix == "" || !isName([]byte(prefix)) || strings.Contains(prefix, ":") { + prefix = "_" + } + if strings.HasPrefix(prefix, "xml") { + // xmlanything is reserved. + prefix = "_" + prefix + } + if p.attrNS[prefix] != "" { + // Name is taken. Find a better one. + for p.seq++; ; p.seq++ { + if id := prefix + "_" + strconv.Itoa(p.seq); p.attrNS[id] == "" { + prefix = id + break + } + } + } + + p.attrPrefix[url] = prefix + p.attrNS[prefix] = url + + p.WriteString(`xmlns:`) + p.WriteString(prefix) + p.WriteString(`="`) + EscapeText(p, []byte(url)) + p.WriteString(`" `) + + return prefix, true +} + +// deleteAttrPrefix removes an attribute name space prefix. +func (p *printer) deleteAttrPrefix(prefix string) { + delete(p.attrPrefix, p.attrNS[prefix]) + delete(p.attrNS, prefix) } // marshalValue writes one or more XML elements representing val. @@ -185,7 +258,9 @@ if xmlns != "" { p.WriteString(` xmlns="`) // TODO: EscapeString, to avoid the allocation. - Escape(p, []byte(xmlns)) + if err := EscapeText(p, []byte(xmlns)); err != nil { + return err + } p.WriteByte('"') } @@ -200,6 +275,14 @@ continue } p.WriteByte(' ') + if finfo.xmlns != "" { + prefix, created := p.createAttrPrefix(finfo.xmlns) + if created { + defer p.deleteAttrPrefix(prefix) + } + p.WriteString(prefix) + p.WriteByte(':') + } p.WriteString(finfo.name) p.WriteString(`="`) if err := p.marshalSimple(fv.Type(), fv); err != nil { @@ -244,19 +327,22 @@ p.WriteString(strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits())) case reflect.String: // TODO: Add EscapeString. - Escape(p, []byte(val.String())) + EscapeText(p, []byte(val.String())) case reflect.Bool: p.WriteString(strconv.FormatBool(val.Bool())) case reflect.Array: // will be [...]byte - bytes := make([]byte, val.Len()) - for i := range bytes { - bytes[i] = val.Index(i).Interface().(byte) + var bytes []byte + if val.CanAddr() { + bytes = val.Slice(0, val.Len()).Bytes() + } else { + bytes = make([]byte, val.Len()) + reflect.Copy(reflect.ValueOf(bytes), val) } - Escape(p, bytes) + EscapeText(p, bytes) case reflect.Slice: // will be []byte - Escape(p, val.Bytes()) + EscapeText(p, val.Bytes()) default: return &UnsupportedTypeError{typ} } @@ -273,7 +359,7 @@ s := parentStack{printer: p} for i := range tinfo.fields { finfo := &tinfo.fields[i] - if finfo.flags&(fAttr) != 0 { + if finfo.flags&fAttr != 0 { continue } vf := finfo.value(val) @@ -290,10 +376,14 @@ case reflect.Bool: Escape(p, strconv.AppendBool(scratch[:0], vf.Bool())) case reflect.String: - Escape(p, []byte(vf.String())) + if err := EscapeText(p, []byte(vf.String())); err != nil { + return err + } case reflect.Slice: if elem, ok := vf.Interface().([]byte); ok { - Escape(p, elem) + if err := EscapeText(p, elem); err != nil { + return err + } } case reflect.Struct: if vf.Type() == timeType { @@ -387,7 +477,11 @@ } p.indentedIn = false } - p.WriteByte('\n') + if p.putNewline { + p.WriteByte('\n') + } else { + p.putNewline = true + } if len(p.prefix) > 0 { p.WriteString(p.prefix) } diff -Naur gcc-4.8.1.orig/libgo/go/encoding/xml/marshal_test.go gcc-4.8.1/libgo/go/encoding/xml/marshal_test.go --- gcc-4.8.1.orig/libgo/go/encoding/xml/marshal_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/xml/marshal_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -7,6 +7,7 @@ import ( "bytes" "errors" + "fmt" "io" "reflect" "strconv" @@ -265,6 +266,16 @@ V interface{} } +type MyInt int + +type EmbedInt struct { + MyInt +} + +type Strings struct { + X []string `xml:"A>B,omitempty"` +} + // Unless explicitly stated as such (or *Plain), all of the // tests below are two-way tests. When introducing new tests, // please try to make them two-way as well to ensure that @@ -789,6 +800,17 @@ }, UnmarshalOnly: true, }, + { + ExpectXML: `42`, + Value: &EmbedInt{ + MyInt: 42, + }, + }, + // Test omitempty with parent chain; see golang.org/issue/4168. + { + ExpectXML: ``, + Value: &Strings{}, + }, } func TestMarshal(t *testing.T) { @@ -811,6 +833,10 @@ } } +type AttrParent struct { + X string `xml:"X>Y,attr"` +} + var marshalErrorTests = []struct { Value interface{} Err string @@ -838,12 +864,39 @@ Value: &Domain{Comment: []byte("f--bar")}, Err: `xml: comments must not contain "--"`, }, + // Reject parent chain with attr, never worked; see golang.org/issue/5033. + { + Value: &AttrParent{}, + Err: `xml: X>Y chain not valid with attr flag`, + }, +} + +var marshalIndentTests = []struct { + Value interface{} + Prefix string + Indent string + ExpectXML string +}{ + { + Value: &SecretAgent{ + Handle: "007", + Identity: "James Bond", + Obfuscate: "", + }, + Prefix: "", + Indent: "\t", + ExpectXML: fmt.Sprintf("\n\tJames Bond\n"), + }, } func TestMarshalErrors(t *testing.T) { for idx, test := range marshalErrorTests { - _, err := Marshal(test.Value) - if err == nil || err.Error() != test.Err { + data, err := Marshal(test.Value) + if err == nil { + t.Errorf("#%d: marshal(%#v) = [success] %q, want error %v", idx, test.Value, data, test.Err) + continue + } + if err.Error() != test.Err { t.Errorf("#%d: marshal(%#v) = [error] %v, want %v", idx, test.Value, err, test.Err) } if test.Kind != reflect.Invalid { @@ -884,6 +937,19 @@ } } +func TestMarshalIndent(t *testing.T) { + for i, test := range marshalIndentTests { + data, err := MarshalIndent(test.Value, test.Prefix, test.Indent) + if err != nil { + t.Errorf("#%d: Error: %s", i, err) + continue + } + if got, want := string(data), test.ExpectXML; got != want { + t.Errorf("#%d: MarshalIndent:\nGot:%s\nWant:\n%s", i, got, want) + } + } +} + type limitedBytesWriter struct { w io.Writer remain int // until writes fail @@ -933,6 +999,16 @@ } } +func TestMarshalWriteIOErrors(t *testing.T) { + enc := NewEncoder(errWriter{}) + + expectErr := "unwritable" + err := enc.Encode(&Passenger{}) + if err == nil || err.Error() != expectErr { + t.Errorf("EscapeTest = [error] %v, want %v", err, expectErr) + } +} + func BenchmarkMarshal(b *testing.B) { for i := 0; i < b.N; i++ { Marshal(atomValue) diff -Naur gcc-4.8.1.orig/libgo/go/encoding/xml/read.go gcc-4.8.1/libgo/go/encoding/xml/read.go --- gcc-4.8.1.orig/libgo/go/encoding/xml/read.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/xml/read.go 2013-07-16 01:55:04.520470000 -0500 @@ -263,7 +263,7 @@ strv := finfo.value(sv) // Look for attribute. for _, a := range start.Attr { - if a.Name.Local == finfo.name { + if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) { copyValue(strv, []byte(a.Value)) break } @@ -441,7 +441,7 @@ Loop: for i := range tinfo.fields { finfo := &tinfo.fields[i] - if finfo.flags&fElement == 0 || len(finfo.parents) < len(parents) { + if finfo.flags&fElement == 0 || len(finfo.parents) < len(parents) || finfo.xmlns != "" && finfo.xmlns != start.Name.Space { continue } for j := range parents { @@ -493,7 +493,6 @@ return true, nil } } - panic("unreachable") } // Skip reads tokens until it has consumed the end element @@ -517,5 +516,4 @@ return nil } } - panic("unreachable") } diff -Naur gcc-4.8.1.orig/libgo/go/encoding/xml/read_test.go gcc-4.8.1/libgo/go/encoding/xml/read_test.go --- gcc-4.8.1.orig/libgo/go/encoding/xml/read_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/xml/read_test.go 2013-07-16 01:55:04.520470000 -0500 @@ -6,6 +6,7 @@ import ( "reflect" + "strings" "testing" "time" ) @@ -399,3 +400,224 @@ t.Fatalf("Unmarshal with %s failed:\nhave %#v,\n want %#v", x, p3.Int, 1) } } + +type Tables struct { + HTable string `xml:"http://www.w3.org/TR/html4/ table"` + FTable string `xml:"http://www.w3schools.com/furniture table"` +} + +var tables = []struct { + xml string + tab Tables + ns string +}{ + { + xml: `` + + `hello
` + + `world
` + + `
`, + tab: Tables{"hello", "world"}, + }, + { + xml: `` + + `world
` + + `hello
` + + `
`, + tab: Tables{"hello", "world"}, + }, + { + xml: `` + + `world` + + `hello` + + ``, + tab: Tables{"hello", "world"}, + }, + { + xml: `` + + `bogus
` + + `
`, + tab: Tables{}, + }, + { + xml: `` + + `only
` + + `
`, + tab: Tables{HTable: "only"}, + ns: "http://www.w3.org/TR/html4/", + }, + { + xml: `` + + `only
` + + `
`, + tab: Tables{FTable: "only"}, + ns: "http://www.w3schools.com/furniture", + }, + { + xml: `` + + `only
` + + `
`, + tab: Tables{}, + ns: "something else entirely", + }, +} + +func TestUnmarshalNS(t *testing.T) { + for i, tt := range tables { + var dst Tables + var err error + if tt.ns != "" { + d := NewDecoder(strings.NewReader(tt.xml)) + d.DefaultSpace = tt.ns + err = d.Decode(&dst) + } else { + err = Unmarshal([]byte(tt.xml), &dst) + } + if err != nil { + t.Errorf("#%d: Unmarshal: %v", i, err) + continue + } + want := tt.tab + if dst != want { + t.Errorf("#%d: dst=%+v, want %+v", i, dst, want) + } + } +} + +func TestMarshalNS(t *testing.T) { + dst := Tables{"hello", "world"} + data, err := Marshal(&dst) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + want := `hello
world
` + str := string(data) + if str != want { + t.Errorf("have: %q\nwant: %q\n", str, want) + } +} + +type TableAttrs struct { + TAttr TAttr +} + +type TAttr struct { + HTable string `xml:"http://www.w3.org/TR/html4/ table,attr"` + FTable string `xml:"http://www.w3schools.com/furniture table,attr"` + Lang string `xml:"http://www.w3.org/XML/1998/namespace lang,attr,omitempty"` + Other1 string `xml:"http://golang.org/xml/ other,attr,omitempty"` + Other2 string `xml:"http://golang.org/xmlfoo/ other,attr,omitempty"` + Other3 string `xml:"http://golang.org/json/ other,attr,omitempty"` + Other4 string `xml:"http://golang.org/2/json/ other,attr,omitempty"` +} + +var tableAttrs = []struct { + xml string + tab TableAttrs + ns string +}{ + { + xml: ``, + tab: TableAttrs{TAttr{HTable: "hello", FTable: "world"}}, + }, + { + xml: ``, + tab: TableAttrs{TAttr{HTable: "hello", FTable: "world"}}, + }, + { + xml: ``, + tab: TableAttrs{TAttr{HTable: "hello", FTable: "world"}}, + }, + { + // Default space does not apply to attribute names. + xml: ``, + tab: TableAttrs{TAttr{HTable: "hello", FTable: ""}}, + }, + { + // Default space does not apply to attribute names. + xml: ``, + tab: TableAttrs{TAttr{HTable: "", FTable: "world"}}, + }, + { + xml: ``, + tab: TableAttrs{}, + }, + { + // Default space does not apply to attribute names. + xml: ``, + tab: TableAttrs{TAttr{HTable: "hello", FTable: ""}}, + ns: "http://www.w3schools.com/furniture", + }, + { + // Default space does not apply to attribute names. + xml: ``, + tab: TableAttrs{TAttr{HTable: "", FTable: "world"}}, + ns: "http://www.w3.org/TR/html4/", + }, + { + xml: ``, + tab: TableAttrs{}, + ns: "something else entirely", + }, +} + +func TestUnmarshalNSAttr(t *testing.T) { + for i, tt := range tableAttrs { + var dst TableAttrs + var err error + if tt.ns != "" { + d := NewDecoder(strings.NewReader(tt.xml)) + d.DefaultSpace = tt.ns + err = d.Decode(&dst) + } else { + err = Unmarshal([]byte(tt.xml), &dst) + } + if err != nil { + t.Errorf("#%d: Unmarshal: %v", i, err) + continue + } + want := tt.tab + if dst != want { + t.Errorf("#%d: dst=%+v, want %+v", i, dst, want) + } + } +} + +func TestMarshalNSAttr(t *testing.T) { + src := TableAttrs{TAttr{"hello", "world", "en_US", "other1", "other2", "other3", "other4"}} + data, err := Marshal(&src) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + want := `` + str := string(data) + if str != want { + t.Errorf("Marshal:\nhave: %#q\nwant: %#q\n", str, want) + } + + var dst TableAttrs + if err := Unmarshal(data, &dst); err != nil { + t.Errorf("Unmarshal: %v", err) + } + + if dst != src { + t.Errorf("Unmarshal = %q, want %q", dst, src) + } +} diff -Naur gcc-4.8.1.orig/libgo/go/encoding/xml/typeinfo.go gcc-4.8.1/libgo/go/encoding/xml/typeinfo.go --- gcc-4.8.1.orig/libgo/go/encoding/xml/typeinfo.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/xml/typeinfo.go 2013-07-16 01:55:04.520470000 -0500 @@ -70,20 +70,19 @@ if t.Kind() == reflect.Ptr { t = t.Elem() } - if t.Kind() != reflect.Struct { - continue - } - inner, err := getTypeInfo(t) - if err != nil { - return nil, err - } - for _, finfo := range inner.fields { - finfo.idx = append([]int{i}, finfo.idx...) - if err := addFieldInfo(typ, tinfo, &finfo); err != nil { + if t.Kind() == reflect.Struct { + inner, err := getTypeInfo(t) + if err != nil { return nil, err } + for _, finfo := range inner.fields { + finfo.idx = append([]int{i}, finfo.idx...) + if err := addFieldInfo(typ, tinfo, &finfo); err != nil { + return nil, err + } + } + continue } - continue } finfo, err := structFieldInfo(typ, &f) @@ -193,16 +192,19 @@ } // Prepare field name and parents. - tokens = strings.Split(tag, ">") - if tokens[0] == "" { - tokens[0] = f.Name + parents := strings.Split(tag, ">") + if parents[0] == "" { + parents[0] = f.Name } - if tokens[len(tokens)-1] == "" { + if parents[len(parents)-1] == "" { return nil, fmt.Errorf("xml: trailing '>' in field %s of type %s", f.Name, typ) } - finfo.name = tokens[len(tokens)-1] - if len(tokens) > 1 { - finfo.parents = tokens[:len(tokens)-1] + finfo.name = parents[len(parents)-1] + if len(parents) > 1 { + if (finfo.flags & fElement) == 0 { + return nil, fmt.Errorf("xml: %s chain not valid with %s flag", tag, strings.Join(tokens[1:], ",")) + } + finfo.parents = parents[:len(parents)-1] } // If the field type has an XMLName field, the names must match @@ -268,6 +270,9 @@ if oldf.flags&fMode != newf.flags&fMode { continue } + if oldf.xmlns != "" && newf.xmlns != "" && oldf.xmlns != newf.xmlns { + continue + } minl := min(len(newf.parents), len(oldf.parents)) for p := 0; p < minl; p++ { if oldf.parents[p] != newf.parents[p] { diff -Naur gcc-4.8.1.orig/libgo/go/encoding/xml/xml.go gcc-4.8.1/libgo/go/encoding/xml/xml.go --- gcc-4.8.1.orig/libgo/go/encoding/xml/xml.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/encoding/xml/xml.go 2013-07-16 01:55:04.520470000 -0500 @@ -169,6 +169,11 @@ // the CharsetReader's result values must be non-nil. CharsetReader func(charset string, input io.Reader) (io.Reader, error) + // DefaultSpace sets the default name space used for unadorned tags, + // as if the entire XML stream were wrapped in an element containing + // the attribute xmlns="DefaultSpace". + DefaultSpace string + r io.ByteReader buf bytes.Buffer saved *bytes.Buffer @@ -268,6 +273,8 @@ return } +const xmlURL = "http://www.w3.org/XML/1998/namespace" + // Apply name space translation to name n. // The default name space (for Space=="") // applies only to element names, not to attribute names. @@ -277,11 +284,15 @@ return case n.Space == "" && !isElementName: return + case n.Space == "xml": + n.Space = xmlURL case n.Space == "" && n.Local == "xmlns": return } if v, ok := d.ns[n.Space]; ok { n.Space = v + } else if n.Space == "" { + n.Space = d.DefaultSpace } } @@ -956,7 +967,7 @@ b0, b1 = 0, 0 continue Input } - ent := string(d.buf.Bytes()[before]) + ent := string(d.buf.Bytes()[before:]) if ent[len(ent)-1] != ';' { ent += " (no semicolon)" } @@ -1692,7 +1703,7 @@ var htmlAutoClose = []string{ /* hget http://www.w3.org/TR/html4/loose.dtd | - 9 sed -n 's/", "illegal character code U+FFFE"}, {"\r\n\x07", "illegal character code U+0007"}, {"what's up", "expected attribute name in element"}, + {"&abc\x01;", "invalid character entity &abc (no semicolon)"}, {"&\x01;", "invalid character entity & (no semicolon)"}, - {"&\xef\xbf\xbe;", "invalid character entity & (no semicolon)"}, + {"&\xef\xbf\xbe;", "invalid character entity &\uFFFE;"}, + {"&hello;", "invalid character entity &hello;"}, } func TestDisallowedCharacters(t *testing.T) { @@ -629,7 +625,7 @@ t.Fatalf("input %d d.Token() = _, %v, want _, *SyntaxError", i, err) } if synerr.Msg != tt.err { - t.Fatalf("input %d synerr.Msg wrong: want '%s', got '%s'", i, tt.err, synerr.Msg) + t.Fatalf("input %d synerr.Msg wrong: want %q, got %q", i, tt.err, synerr.Msg) } } } @@ -689,3 +685,32 @@ } } } + +// Writer whose Write method always returns an error. +type errWriter struct{} + +func (errWriter) Write(p []byte) (n int, err error) { return 0, fmt.Errorf("unwritable") } + +func TestEscapeTextIOErrors(t *testing.T) { + expectErr := "unwritable" + err := EscapeText(errWriter{}, []byte{'A'}) + + if err == nil || err.Error() != expectErr { + t.Errorf("have %v, want %v", err, expectErr) + } +} + +func TestEscapeTextInvalidChar(t *testing.T) { + input := []byte("A \x00 terminated string.") + expected := "A \uFFFD terminated string." + + buff := new(bytes.Buffer) + if err := EscapeText(buff, input); err != nil { + t.Fatalf("have %v, want nil", err) + } + text := buff.String() + + if text != expected { + t.Errorf("have %v, want %v", text, expected) + } +} diff -Naur gcc-4.8.1.orig/libgo/go/exp/cookiejar/jar.go gcc-4.8.1/libgo/go/exp/cookiejar/jar.go --- gcc-4.8.1.orig/libgo/go/exp/cookiejar/jar.go 2012-12-12 17:13:29.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/cookiejar/jar.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,89 +0,0 @@ -// 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 cookiejar implements an RFC 6265-compliant http.CookieJar. -// -// TODO: example code to create a memory-backed cookie jar with the default -// public suffix list. -package cookiejar - -import ( - "net/http" - "net/url" -) - -// PublicSuffixList provides the public suffix of a domain. For example: -// - the public suffix of "example.com" is "com", -// - the public suffix of "foo1.foo2.foo3.co.uk" is "co.uk", and -// - the public suffix of "bar.pvt.k12.wy.us" is "pvt.k12.wy.us". -// -// Implementations of PublicSuffixList must be safe for concurrent use by -// multiple goroutines. -// -// An implementation that always returns "" is valid and may be useful for -// testing but it is not secure: it means that the HTTP server for foo.com can -// set a cookie for bar.com. -type PublicSuffixList interface { - // PublicSuffix returns the public suffix of domain. - // - // TODO: specify which of the caller and callee is responsible for IP - // addresses, for leading and trailing dots, for case sensitivity, and - // for IDN/Punycode. - PublicSuffix(domain string) string - - // String returns a description of the source of this public suffix list. - // A Jar will store its PublicSuffixList's description in its storage, - // and update the stored cookies if its list has a different description - // than the stored list. The description will typically contain something - // like a time stamp or version number. - String() string -} - -// Options are the options for creating a new Jar. -type Options struct { - // Storage is the cookie jar storage. It may not be nil. - Storage Storage - - // PublicSuffixList is the public suffix list that determines whether an - // HTTP server can set a cookie for a domain. It may not be nil. - PublicSuffixList PublicSuffixList - - // TODO: ErrorFunc for handling storage errors? -} - -// Jar implements the http.CookieJar interface from the net/http package. -type Jar struct { - storage Storage - psList PublicSuffixList -} - -// New returns a new cookie jar. -func New(o *Options) *Jar { - return &Jar{ - storage: o.Storage, - psList: o.PublicSuffixList, - } -} - -// TODO(nigeltao): how do we reject HttpOnly cookies? Do we post-process the -// return value from Jar.Cookies? -// -// HttpOnly cookies are those for regular HTTP(S) requests but should not be -// visible from JavaScript. The HttpOnly bit mitigates XSS attacks; it's not -// for HTTP vs HTTPS vs FTP transports. - -// Cookies implements the Cookies method of the http.CookieJar interface. -// -// It returns an empty slice if the URL's scheme is not HTTP or HTTPS. -func (j *Jar) Cookies(u *url.URL) []*http.Cookie { - // TODO. - return nil -} - -// SetCookies implements the SetCookies method of the http.CookieJar interface. -// -// It does nothing if the URL's scheme is not HTTP or HTTPS. -func (j *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) { - // TODO. -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/cookiejar/storage.go gcc-4.8.1/libgo/go/exp/cookiejar/storage.go --- gcc-4.8.1.orig/libgo/go/exp/cookiejar/storage.go 2012-12-12 17:13:29.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/cookiejar/storage.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,101 +0,0 @@ -// 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 cookiejar - -import ( - "time" -) - -// Storage is a Jar's storage. It is a multi-map, mapping keys to one or more -// entries. Each entry consists of a subkey, creation time, last access time, -// and some arbitrary data. -// -// The Add and Delete methods have undefined behavior if the key is invalid. -// A valid key must use only bytes in the character class [a-z0-9.-] and -// must have at least one non-. byte. Note that this excludes any key -// containing a capital ASCII letter as well as the empty string. -type Storage interface { - // A client must call Lock before calling other methods and must call - // Unlock when finished. Between the calls to Lock and Unlock, a client - // can assume that other clients are not modifying the Storage. - Lock() - Unlock() - - // Add adds entries to the storage. Each entry's Subkey and Data must - // both be non-empty. - // - // If the Storage already contains an entry with the same key and - // subkey then the new entry is stored with the creation time of the - // old entry, and the old entry is deleted. - // - // Adding entries may cause other entries to be deleted, to maintain an - // implementation-specific storage constraint. - Add(key string, entries ...Entry) error - - // Delete deletes all entries for the given key. - Delete(key string) error - - // Entries calls f for each entry stored for that key. If f returns a - // non-nil error then the iteration stops and Entries returns that - // error. Iteration is not guaranteed to be in any particular order. - // - // If f returns an Update action then that stored entry's LastAccess - // time will be set to the time that f returned. If f returns a Delete - // action then that entry will be deleted from the Storage. - // - // f may call a Storage's Add and Delete methods; those modifications - // will not affect the list of entries visited in this call to Entries. - Entries(key string, f func(entry Entry) (Action, time.Time, error)) error - - // Keys calls f for each key stored. f will not be called on a key with - // zero entries. If f returns a non-nil error then the iteration stops - // and Keys returns that error. Iteration is not guaranteed to be in any - // particular order. - // - // f may call a Storage's Add, Delete and Entries methods; those - // modifications will not affect the list of keys visited in this call - // to Keys. - Keys(f func(key string) error) error -} - -// Entry is an entry in a Storage. -type Entry struct { - Subkey string - Data string - Creation time.Time - LastAccess time.Time -} - -// Action is an action returned by the function passed to Entries. -type Action int - -const ( - // Pass means to take no further action with an Entry. - Pass Action = iota - // Update means to update the LastAccess time of an Entry. - Update - // Delete means to delete an Entry. - Delete -) - -// ValidStorageKey returns whether the given key is valid for a Storage. -func ValidStorageKey(key string) bool { - hasNonDot := false - for i := 0; i < len(key); i++ { - switch c := key[i]; { - case 'a' <= c && c <= 'z': - fallthrough - case '0' <= c && c <= '9': - fallthrough - case c == '-': - hasNonDot = true - case c == '.': - // No-op. - default: - return false - } - } - return hasNonDot -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/cookiejar/storage_test.go gcc-4.8.1/libgo/go/exp/cookiejar/storage_test.go --- gcc-4.8.1.orig/libgo/go/exp/cookiejar/storage_test.go 2012-12-12 17:13:29.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/cookiejar/storage_test.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,48 +0,0 @@ -// 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 cookiejar - -import ( - "testing" -) - -var validStorageKeyTests = map[string]bool{ - "": false, - ".": false, - "..": false, - "/": false, - "EXAMPLE.com": false, - "\n": false, - "\r": false, - "\r\n": false, - "\x00": false, - "back\\slash": false, - "co:lon": false, - "com,ma": false, - "semi;colon": false, - "sl/ash": false, - "sp ace": false, - "under_score": false, - "π": false, - - "-": true, - ".dot": true, - ".dot.": true, - ".metadata": true, - ".x..y..z...": true, - "dot.": true, - "example.com": true, - "foo": true, - "hy-phen": true, - "xn--bcher-kva.ch": true, -} - -func TestValidStorageKey(t *testing.T) { - for key, want := range validStorageKeyTests { - if got := ValidStorageKey(key); got != want { - t.Errorf("%q: got %v, want %v", key, got, want) - } - } -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/ebnf/ebnf.go gcc-4.8.1/libgo/go/exp/ebnf/ebnf.go --- gcc-4.8.1.orig/libgo/go/exp/ebnf/ebnf.go 2011-12-06 19:11:29.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/ebnf/ebnf.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,269 +0,0 @@ -// 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. - -// Package ebnf is a library for EBNF grammars. The input is text ([]byte) -// satisfying the following grammar (represented itself in EBNF): -// -// Production = name "=" [ Expression ] "." . -// Expression = Alternative { "|" Alternative } . -// Alternative = Term { Term } . -// Term = name | token [ "…" token ] | Group | Option | Repetition . -// Group = "(" Expression ")" . -// Option = "[" Expression "]" . -// Repetition = "{" Expression "}" . -// -// A name is a Go identifier, a token is a Go string, and comments -// and white space follow the same rules as for the Go language. -// Production names starting with an uppercase Unicode letter denote -// non-terminal productions (i.e., productions which allow white-space -// and comments between tokens); all other production names denote -// lexical productions. -// -package ebnf - -import ( - "errors" - "fmt" - "text/scanner" - "unicode" - "unicode/utf8" -) - -// ---------------------------------------------------------------------------- -// Error handling - -type errorList []error - -func (list errorList) Err() error { - if len(list) == 0 { - return nil - } - return list -} - -func (list errorList) Error() string { - switch len(list) { - case 0: - return "no errors" - case 1: - return list[0].Error() - } - return fmt.Sprintf("%s (and %d more errors)", list[0], len(list)-1) -} - -func newError(pos scanner.Position, msg string) error { - return errors.New(fmt.Sprintf("%s: %s", pos, msg)) -} - -// ---------------------------------------------------------------------------- -// Internal representation - -type ( - // An Expression node represents a production expression. - Expression interface { - // Pos is the position of the first character of the syntactic construct - Pos() scanner.Position - } - - // An Alternative node represents a non-empty list of alternative expressions. - Alternative []Expression // x | y | z - - // A Sequence node represents a non-empty list of sequential expressions. - Sequence []Expression // x y z - - // A Name node represents a production name. - Name struct { - StringPos scanner.Position - String string - } - - // A Token node represents a literal. - Token struct { - StringPos scanner.Position - String string - } - - // A List node represents a range of characters. - Range struct { - Begin, End *Token // begin ... end - } - - // A Group node represents a grouped expression. - Group struct { - Lparen scanner.Position - Body Expression // (body) - } - - // An Option node represents an optional expression. - Option struct { - Lbrack scanner.Position - Body Expression // [body] - } - - // A Repetition node represents a repeated expression. - Repetition struct { - Lbrace scanner.Position - Body Expression // {body} - } - - // A Production node represents an EBNF production. - Production struct { - Name *Name - Expr Expression - } - - // A Bad node stands for pieces of source code that lead to a parse error. - Bad struct { - TokPos scanner.Position - Error string // parser error message - } - - // A Grammar is a set of EBNF productions. The map - // is indexed by production name. - // - Grammar map[string]*Production -) - -func (x Alternative) Pos() scanner.Position { return x[0].Pos() } // the parser always generates non-empty Alternative -func (x Sequence) Pos() scanner.Position { return x[0].Pos() } // the parser always generates non-empty Sequences -func (x *Name) Pos() scanner.Position { return x.StringPos } -func (x *Token) Pos() scanner.Position { return x.StringPos } -func (x *Range) Pos() scanner.Position { return x.Begin.Pos() } -func (x *Group) Pos() scanner.Position { return x.Lparen } -func (x *Option) Pos() scanner.Position { return x.Lbrack } -func (x *Repetition) Pos() scanner.Position { return x.Lbrace } -func (x *Production) Pos() scanner.Position { return x.Name.Pos() } -func (x *Bad) Pos() scanner.Position { return x.TokPos } - -// ---------------------------------------------------------------------------- -// Grammar verification - -func isLexical(name string) bool { - ch, _ := utf8.DecodeRuneInString(name) - return !unicode.IsUpper(ch) -} - -type verifier struct { - errors errorList - worklist []*Production - reached Grammar // set of productions reached from (and including) the root production - grammar Grammar -} - -func (v *verifier) error(pos scanner.Position, msg string) { - v.errors = append(v.errors, newError(pos, msg)) -} - -func (v *verifier) push(prod *Production) { - name := prod.Name.String - if _, found := v.reached[name]; !found { - v.worklist = append(v.worklist, prod) - v.reached[name] = prod - } -} - -func (v *verifier) verifyChar(x *Token) rune { - s := x.String - if utf8.RuneCountInString(s) != 1 { - v.error(x.Pos(), "single char expected, found "+s) - return 0 - } - ch, _ := utf8.DecodeRuneInString(s) - return ch -} - -func (v *verifier) verifyExpr(expr Expression, lexical bool) { - switch x := expr.(type) { - case nil: - // empty expression - case Alternative: - for _, e := range x { - v.verifyExpr(e, lexical) - } - case Sequence: - for _, e := range x { - v.verifyExpr(e, lexical) - } - case *Name: - // a production with this name must exist; - // add it to the worklist if not yet processed - if prod, found := v.grammar[x.String]; found { - v.push(prod) - } else { - v.error(x.Pos(), "missing production "+x.String) - } - // within a lexical production references - // to non-lexical productions are invalid - if lexical && !isLexical(x.String) { - v.error(x.Pos(), "reference to non-lexical production "+x.String) - } - case *Token: - // nothing to do for now - case *Range: - i := v.verifyChar(x.Begin) - j := v.verifyChar(x.End) - if i >= j { - v.error(x.Pos(), "decreasing character range") - } - case *Group: - v.verifyExpr(x.Body, lexical) - case *Option: - v.verifyExpr(x.Body, lexical) - case *Repetition: - v.verifyExpr(x.Body, lexical) - case *Bad: - v.error(x.Pos(), x.Error) - default: - panic(fmt.Sprintf("internal error: unexpected type %T", expr)) - } -} - -func (v *verifier) verify(grammar Grammar, start string) { - // find root production - root, found := grammar[start] - if !found { - var noPos scanner.Position - v.error(noPos, "no start production "+start) - return - } - - // initialize verifier - v.worklist = v.worklist[0:0] - v.reached = make(Grammar) - v.grammar = grammar - - // work through the worklist - v.push(root) - for { - n := len(v.worklist) - 1 - if n < 0 { - break - } - prod := v.worklist[n] - v.worklist = v.worklist[0:n] - v.verifyExpr(prod.Expr, isLexical(prod.Name.String)) - } - - // check if all productions were reached - if len(v.reached) < len(v.grammar) { - for name, prod := range v.grammar { - if _, found := v.reached[name]; !found { - v.error(prod.Pos(), name+" is unreachable") - } - } - } -} - -// Verify checks that: -// - all productions used are defined -// - all productions defined are used when beginning at start -// - lexical productions refer only to other lexical productions -// -// Position information is interpreted relative to the file set fset. -// -func Verify(grammar Grammar, start string) error { - var v verifier - v.verify(grammar, start) - return v.errors.Err() -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/ebnf/ebnf_test.go gcc-4.8.1/libgo/go/exp/ebnf/ebnf_test.go --- gcc-4.8.1.orig/libgo/go/exp/ebnf/ebnf_test.go 2011-10-26 18:57:58.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/ebnf/ebnf_test.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,71 +0,0 @@ -// 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. - -package ebnf - -import ( - "bytes" - "testing" -) - -var goodGrammars = []string{ - `Program = .`, - - `Program = foo . - foo = "foo" .`, - - `Program = "a" | "b" "c" .`, - - `Program = "a" … "z" .`, - - `Program = Song . - Song = { Note } . - Note = Do | (Re | Mi | Fa | So | La) | Ti . - Do = "c" . - Re = "d" . - Mi = "e" . - Fa = "f" . - So = "g" . - La = "a" . - Ti = ti . - ti = "b" .`, -} - -var badGrammars = []string{ - `Program = | .`, - `Program = | b .`, - `Program = a … b .`, - `Program = "a" … .`, - `Program = … "b" .`, - `Program = () .`, - `Program = [] .`, - `Program = {} .`, -} - -func checkGood(t *testing.T, src string) { - grammar, err := Parse("", bytes.NewBuffer([]byte(src))) - if err != nil { - t.Errorf("Parse(%s) failed: %v", src, err) - return - } - if err = Verify(grammar, "Program"); err != nil { - t.Errorf("Verify(%s) failed: %v", src, err) - } -} - -func checkBad(t *testing.T, src string) { - _, err := Parse("", bytes.NewBuffer([]byte(src))) - if err == nil { - t.Errorf("Parse(%s) should have failed", src) - } -} - -func TestGrammars(t *testing.T) { - for _, src := range goodGrammars { - checkGood(t, src) - } - for _, src := range badGrammars { - checkBad(t, src) - } -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/ebnf/parser.go gcc-4.8.1/libgo/go/exp/ebnf/parser.go --- gcc-4.8.1.orig/libgo/go/exp/ebnf/parser.go 2011-12-06 19:11:29.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/ebnf/parser.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,190 +0,0 @@ -// 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. - -package ebnf - -import ( - "io" - "strconv" - "text/scanner" -) - -type parser struct { - errors errorList - scanner scanner.Scanner - pos scanner.Position // token position - tok rune // one token look-ahead - lit string // token literal -} - -func (p *parser) next() { - p.tok = p.scanner.Scan() - p.pos = p.scanner.Position - p.lit = p.scanner.TokenText() -} - -func (p *parser) error(pos scanner.Position, msg string) { - p.errors = append(p.errors, newError(pos, msg)) -} - -func (p *parser) errorExpected(pos scanner.Position, msg string) { - msg = `expected "` + msg + `"` - if pos.Offset == p.pos.Offset { - // the error happened at the current position; - // make the error message more specific - msg += ", found " + scanner.TokenString(p.tok) - if p.tok < 0 { - msg += " " + p.lit - } - } - p.error(pos, msg) -} - -func (p *parser) expect(tok rune) scanner.Position { - pos := p.pos - if p.tok != tok { - p.errorExpected(pos, scanner.TokenString(tok)) - } - p.next() // make progress in any case - return pos -} - -func (p *parser) parseIdentifier() *Name { - pos := p.pos - name := p.lit - p.expect(scanner.Ident) - return &Name{pos, name} -} - -func (p *parser) parseToken() *Token { - pos := p.pos - value := "" - if p.tok == scanner.String { - value, _ = strconv.Unquote(p.lit) - // Unquote may fail with an error, but only if the scanner found - // an illegal string in the first place. In this case the error - // has already been reported. - p.next() - } else { - p.expect(scanner.String) - } - return &Token{pos, value} -} - -// ParseTerm returns nil if no term was found. -func (p *parser) parseTerm() (x Expression) { - pos := p.pos - - switch p.tok { - case scanner.Ident: - x = p.parseIdentifier() - - case scanner.String: - tok := p.parseToken() - x = tok - const ellipsis = '…' // U+2026, the horizontal ellipsis character - if p.tok == ellipsis { - p.next() - x = &Range{tok, p.parseToken()} - } - - case '(': - p.next() - x = &Group{pos, p.parseExpression()} - p.expect(')') - - case '[': - p.next() - x = &Option{pos, p.parseExpression()} - p.expect(']') - - case '{': - p.next() - x = &Repetition{pos, p.parseExpression()} - p.expect('}') - } - - return x -} - -func (p *parser) parseSequence() Expression { - var list Sequence - - for x := p.parseTerm(); x != nil; x = p.parseTerm() { - list = append(list, x) - } - - // no need for a sequence if list.Len() < 2 - switch len(list) { - case 0: - p.errorExpected(p.pos, "term") - return &Bad{p.pos, "term expected"} - case 1: - return list[0] - } - - return list -} - -func (p *parser) parseExpression() Expression { - var list Alternative - - for { - list = append(list, p.parseSequence()) - if p.tok != '|' { - break - } - p.next() - } - // len(list) > 0 - - // no need for an Alternative node if list.Len() < 2 - if len(list) == 1 { - return list[0] - } - - return list -} - -func (p *parser) parseProduction() *Production { - name := p.parseIdentifier() - p.expect('=') - var expr Expression - if p.tok != '.' { - expr = p.parseExpression() - } - p.expect('.') - return &Production{name, expr} -} - -func (p *parser) parse(filename string, src io.Reader) Grammar { - p.scanner.Init(src) - p.scanner.Filename = filename - p.next() // initializes pos, tok, lit - - grammar := make(Grammar) - for p.tok != scanner.EOF { - prod := p.parseProduction() - name := prod.Name.String - if _, found := grammar[name]; !found { - grammar[name] = prod - } else { - p.error(prod.Pos(), name+" declared already") - } - } - - return grammar -} - -// Parse parses a set of EBNF productions from source src. -// It returns a set of productions. Errors are reported -// for incorrect syntax and if a production is declared -// more than once; the filename is used only for error -// positions. -// -func Parse(filename string, src io.Reader) (Grammar, error) { - var p parser - grammar := p.parse(filename, src) - return grammar, p.errors.Err() -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/ebnflint/doc.go gcc-4.8.1/libgo/go/exp/ebnflint/doc.go --- gcc-4.8.1.orig/libgo/go/exp/ebnflint/doc.go 2012-02-09 02:19:58.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/ebnflint/doc.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,22 +0,0 @@ -// 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. - -/* - -Ebnflint verifies that EBNF productions are consistent and grammatically correct. -It reads them from an HTML document such as the Go specification. - -Grammar productions are grouped in boxes demarcated by the HTML elements -
-	
- - -Usage: - go tool ebnflint [--start production] [file] - -The --start flag specifies the name of the start production for -the grammar; it defaults to "Start". - -*/ -package documentation diff -Naur gcc-4.8.1.orig/libgo/go/exp/ebnflint/ebnflint.go gcc-4.8.1/libgo/go/exp/ebnflint/ebnflint.go --- gcc-4.8.1.orig/libgo/go/exp/ebnflint/ebnflint.go 2012-02-09 02:19:58.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/ebnflint/ebnflint.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,122 +0,0 @@ -// 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. - -package main - -import ( - "bytes" - "exp/ebnf" - "flag" - "fmt" - "go/scanner" - "go/token" - "io" - "io/ioutil" - "os" - "path/filepath" -) - -var fset = token.NewFileSet() -var start = flag.String("start", "Start", "name of start production") - -func usage() { - fmt.Fprintf(os.Stderr, "usage: go tool ebnflint [flags] [filename]\n") - flag.PrintDefaults() - os.Exit(1) -} - -// Markers around EBNF sections in .html files -var ( - open = []byte(`
`)
-	close = []byte(`
`) -) - -func report(err error) { - scanner.PrintError(os.Stderr, err) - os.Exit(1) -} - -func extractEBNF(src []byte) []byte { - var buf bytes.Buffer - - for { - // i = beginning of EBNF text - i := bytes.Index(src, open) - if i < 0 { - break // no EBNF found - we are done - } - i += len(open) - - // write as many newlines as found in the excluded text - // to maintain correct line numbers in error messages - for _, ch := range src[0:i] { - if ch == '\n' { - buf.WriteByte('\n') - } - } - - // j = end of EBNF text (or end of source) - j := bytes.Index(src[i:], close) // close marker - if j < 0 { - j = len(src) - i - } - j += i - - // copy EBNF text - buf.Write(src[i:j]) - - // advance - src = src[j:] - } - - return buf.Bytes() -} - -func main() { - flag.Parse() - - var ( - name string - r io.Reader - ) - switch flag.NArg() { - case 0: - name, r = "", os.Stdin - case 1: - name = flag.Arg(0) - default: - usage() - } - - if err := verify(name, *start, r); err != nil { - report(err) - } -} - -func verify(name, start string, r io.Reader) error { - if r == nil { - f, err := os.Open(name) - if err != nil { - return err - } - defer f.Close() - r = f - } - - src, err := ioutil.ReadAll(r) - if err != nil { - return err - } - - if filepath.Ext(name) == ".html" || bytes.Index(src, open) >= 0 { - src = extractEBNF(src) - } - - grammar, err := ebnf.Parse(name, bytes.NewBuffer(src)) - if err != nil { - return err - } - - return ebnf.Verify(grammar, start) -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/ebnflint/ebnflint_test.go gcc-4.8.1/libgo/go/exp/ebnflint/ebnflint_test.go --- gcc-4.8.1.orig/libgo/go/exp/ebnflint/ebnflint_test.go 2012-02-01 13:26:59.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/ebnflint/ebnflint_test.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,16 +0,0 @@ -// 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 main - -import ( - "runtime" - "testing" -) - -func TestSpec(t *testing.T) { - if err := verify(runtime.GOROOT()+"/doc/go_spec.html", "SourceFile", nil); err != nil { - t.Fatal(err) - } -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/gotype/doc.go gcc-4.8.1/libgo/go/exp/gotype/doc.go --- gcc-4.8.1.orig/libgo/go/exp/gotype/doc.go 2012-03-06 11:57:23.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/gotype/doc.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,63 +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. - -/* -The gotype command does syntactic and semantic analysis of Go files -and packages similar to the analysis performed by the front-end of -a Go compiler. Errors are reported if the analysis fails; otherwise -gotype is quiet (unless -v is set). - -Without a list of paths, gotype processes the standard input, which must -be the source of a single package file. - -Given a list of file names, each file must be a source file belonging to -the same package unless the package name is explicitly specified with the --p flag. - -Given a directory name, gotype collects all .go files in the directory -and processes them as if they were provided as an explicit list of file -names. Each directory is processed independently. Files starting with . -or not ending in .go are ignored. - -Usage: - gotype [flags] [path ...] - -The flags are: - -e - Print all (including spurious) errors. - -p pkgName - Process only those files in package pkgName. - -r - Recursively process subdirectories. - -v - Verbose mode. - -Debugging flags: - -comments - Parse comments (ignored if -ast not set). - -ast - Print AST (disables concurrent parsing). - -trace - Print parse trace (disables concurrent parsing). - - -Examples - -To check the files file.go, old.saved, and .ignored: - - gotype file.go old.saved .ignored - -To check all .go files belonging to package main in the current directory -and recursively in all subdirectories: - - gotype -p main -r . - -To verify the output of a pipe: - - echo "package foo" | gotype - -*/ -package documentation - -// BUG(gri): At the moment, only single-file scope analysis is performed. diff -Naur gcc-4.8.1.orig/libgo/go/exp/gotype/gotype.go gcc-4.8.1/libgo/go/exp/gotype/gotype.go --- gcc-4.8.1.orig/libgo/go/exp/gotype/gotype.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/gotype/gotype.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,184 +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 main - -import ( - "flag" - "fmt" - "go/ast" - "go/parser" - "go/scanner" - "go/token" - "go/types" - "io/ioutil" - "os" - "path/filepath" - "strings" -) - -var ( - // main operation modes - pkgName = flag.String("p", "", "process only those files in package pkgName") - recursive = flag.Bool("r", false, "recursively process subdirectories") - verbose = flag.Bool("v", false, "verbose mode") - allErrors = flag.Bool("e", false, "print all (including spurious) errors") - - // debugging support - parseComments = flag.Bool("comments", false, "parse comments (ignored if -ast not set)") - printTrace = flag.Bool("trace", false, "print parse trace") - printAST = flag.Bool("ast", false, "print AST") -) - -var exitCode = 0 - -func usage() { - fmt.Fprintf(os.Stderr, "usage: gotype [flags] [path ...]\n") - flag.PrintDefaults() - os.Exit(2) -} - -func report(err error) { - scanner.PrintError(os.Stderr, err) - exitCode = 2 -} - -// parse returns the AST for the Go source src. -// The filename is for error reporting only. -// The result is nil if there were errors or if -// the file does not belong to the -p package. -func parse(fset *token.FileSet, filename string, src []byte) *ast.File { - if *verbose { - fmt.Println(filename) - } - - // ignore files with different package name - if *pkgName != "" { - file, err := parser.ParseFile(fset, filename, src, parser.PackageClauseOnly) - if err != nil { - report(err) - return nil - } - if file.Name.Name != *pkgName { - if *verbose { - fmt.Printf("\tignored (package %s)\n", file.Name.Name) - } - return nil - } - } - - // parse entire file - mode := parser.DeclarationErrors - if *allErrors { - mode |= parser.SpuriousErrors - } - if *parseComments && *printAST { - mode |= parser.ParseComments - } - if *printTrace { - mode |= parser.Trace - } - file, err := parser.ParseFile(fset, filename, src, mode) - if err != nil { - report(err) - return nil - } - if *printAST { - ast.Print(fset, file) - } - - return file -} - -func parseStdin(fset *token.FileSet) (files []*ast.File) { - src, err := ioutil.ReadAll(os.Stdin) - if err != nil { - report(err) - return - } - const filename = "" - if file := parse(fset, filename, src); file != nil { - files = []*ast.File{file} - } - return -} - -func parseFiles(fset *token.FileSet, filenames []string) (files []*ast.File) { - for _, filename := range filenames { - src, err := ioutil.ReadFile(filename) - if err != nil { - report(err) - continue - } - if file := parse(fset, filename, src); file != nil { - files = append(files, file) - } - } - return -} - -func isGoFilename(filename string) bool { - // ignore non-Go files - return !strings.HasPrefix(filename, ".") && strings.HasSuffix(filename, ".go") -} - -func processDirectory(dirname string) { - f, err := os.Open(dirname) - if err != nil { - report(err) - return - } - filenames, err := f.Readdirnames(-1) - f.Close() - if err != nil { - report(err) - // continue since filenames may not be empty - } - for i, filename := range filenames { - filenames[i] = filepath.Join(dirname, filename) - } - processFiles(filenames, false) -} - -func processFiles(filenames []string, allFiles bool) { - i := 0 - for _, filename := range filenames { - switch info, err := os.Stat(filename); { - case err != nil: - report(err) - case info.IsDir(): - if allFiles || *recursive { - processDirectory(filename) - } - default: - if allFiles || isGoFilename(info.Name()) { - filenames[i] = filename - i++ - } - } - } - fset := token.NewFileSet() - processPackage(fset, parseFiles(fset, filenames[0:i])) -} - -func processPackage(fset *token.FileSet, files []*ast.File) { - _, err := types.Check(fset, files) - if err != nil { - report(err) - } -} - -func main() { - flag.Usage = usage - flag.Parse() - - if flag.NArg() == 0 { - fset := token.NewFileSet() - processPackage(fset, parseStdin(fset)) - } else { - processFiles(flag.Args(), true) - } - - os.Exit(exitCode) -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/gotype/gotype_test.go gcc-4.8.1/libgo/go/exp/gotype/gotype_test.go --- gcc-4.8.1.orig/libgo/go/exp/gotype/gotype_test.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/gotype/gotype_test.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,215 +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 main - -import ( - "go/build" - "path/filepath" - "runtime" - "strings" - "testing" -) - -func runTest(t *testing.T, path string) { - exitCode = 0 - - *recursive = false - if suffix := ".go"; strings.HasSuffix(path, suffix) { - // single file - path = filepath.Join(runtime.GOROOT(), "src/pkg", path) - path, file := filepath.Split(path) - *pkgName = file[:len(file)-len(suffix)] - processFiles([]string{path}, true) - } else { - // package directory - // TODO(gri) gotype should use the build package instead - ctxt := build.Default - ctxt.CgoEnabled = false - pkg, err := ctxt.Import(path, "", 0) - if err != nil { - t.Errorf("build.Import error for path = %s: %s", path, err) - return - } - // TODO(gri) there ought to be a more direct way using the build package... - files := make([]string, len(pkg.GoFiles)) - for i, file := range pkg.GoFiles { - files[i] = filepath.Join(pkg.Dir, file) - } - *pkgName = pkg.Name - processFiles(files, true) - } - - if exitCode != 0 { - t.Errorf("processing %s failed: exitCode = %d", path, exitCode) - } -} - -var tests = []string{ - // individual files - "exp/gotype/testdata/test1.go", - - // directories - // Note: Packages that don't typecheck yet are commented out. - // Unless there is a comment next to the commented out packages, - // the package doesn't typecheck due to errors in the shift - // expression checker. - "archive/tar", - "archive/zip", - - "bufio", - "bytes", - - // "compress/bzip2", - "compress/flate", - "compress/gzip", - // "compress/lzw", - "compress/zlib", - - "container/heap", - "container/list", - "container/ring", - - "crypto", - "crypto/aes", - "crypto/cipher", - "crypto/des", - "crypto/dsa", - "crypto/ecdsa", - "crypto/elliptic", - "crypto/hmac", - "crypto/md5", - // "crypto/rand", - "crypto/rc4", - // "crypto/rsa", // intermittent failure: /home/gri/go2/src/pkg/crypto/rsa/pkcs1v15.go:21:27: undeclared name: io - "crypto/sha1", - "crypto/sha256", - "crypto/sha512", - "crypto/subtle", - "crypto/tls", - "crypto/x509", - "crypto/x509/pkix", - - "database/sql", - "database/sql/driver", - - // "debug/dwarf", - "debug/elf", - "debug/gosym", - "debug/macho", - "debug/pe", - - "encoding/ascii85", - // "encoding/asn1", - "encoding/base32", - "encoding/base64", - "encoding/binary", - "encoding/csv", - "encoding/gob", - "encoding/hex", - "encoding/json", - "encoding/pem", - "encoding/xml", - - "errors", - "expvar", - "flag", - "fmt", - - "exp/gotype", - - "go/ast", - "go/build", - "go/doc", - "go/format", - "go/parser", - "go/printer", - "go/scanner", - // "go/token", - "go/types", - - "hash/adler32", - "hash/crc32", - "hash/crc64", - "hash/fnv", - - "image", - "image/color", - "image/draw", - "image/gif", - // "image/jpeg", - "image/png", - - "index/suffixarray", - - "io", - "io/ioutil", - - "log", - "log/syslog", - - // "math", - //"math/big", - "math/cmplx", - "math/rand", - - "mime", - "mime/multipart", - - // "net", - "net/http", - "net/http/cgi", - "net/http/fcgi", - "net/http/httptest", - "net/http/httputil", - "net/http/pprof", - "net/mail", - "net/rpc", - "net/rpc/jsonrpc", - "net/smtp", - // "net/textproto", - "net/url", - - "path", - "path/filepath", - - "reflect", - - "regexp", - "regexp/syntax", - - // "runtime", - "runtime/cgo", - "runtime/debug", - "runtime/pprof", - - "sort", - // "strconv", - "strings", - - "sync", - "sync/atomic", - - // "syscall", - - "testing", - "testing/iotest", - "testing/quick", - - // "text/scanner", - "text/tabwriter", - "text/template", - "text/template/parse", - - "time", - "unicode", - "unicode/utf16", - "unicode/utf8", -} - -func Test(t *testing.T) { - for _, test := range tests { - runTest(t, test) - } -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/gotype/testdata/test1.go gcc-4.8.1/libgo/go/exp/gotype/testdata/test1.go --- gcc-4.8.1.orig/libgo/go/exp/gotype/testdata/test1.go 2012-12-12 17:13:29.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/gotype/testdata/test1.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,27 +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 test1 - -func _() { - // the scope of a local type declaration starts immediately after the type name - type T struct{ _ *T } -} - -func _(x interface{}) { - // the variable defined by a TypeSwitchGuard is declared in each TypeCaseClause - switch t := x.(type) { - case int: - _ = t - case float32: - _ = t - default: - _ = t - } - - // the variable defined by a TypeSwitchGuard must not conflict with other - // variables declared in the initial simple statement - switch t := 0; t := x.(type) { - } -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/atom/atom.go gcc-4.8.1/libgo/go/exp/html/atom/atom.go --- gcc-4.8.1.orig/libgo/go/exp/html/atom/atom.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/html/atom/atom.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,81 +0,0 @@ -// 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 atom provides integer codes (also known as atoms) for a fixed set of -// frequently occurring HTML strings: tag names and attribute keys such as "p" -// and "id". -// -// Sharing an atom's name between all elements with the same tag can result in -// fewer string allocations when tokenizing and parsing HTML. Integer -// comparisons are also generally faster than string comparisons. -// -// The value of an atom's particular code is not guaranteed to stay the same -// between versions of this package. Neither is any ordering guaranteed: -// whether atom.H1 < atom.H2 may also change. The codes are not guaranteed to -// be dense. The only guarantees are that e.g. looking up "div" will yield -// atom.Div, calling atom.Div.String will return "div", and atom.Div != 0. -// -// TODO(rsc): When this package moves out of exp we need to freeze atom values -// across releases. -package atom - -// Atom is an integer code for a string. The zero value maps to "". -type Atom uint32 - -// String returns the atom's name. -func (a Atom) String() string { - start := uint32(a >> 8) - n := uint32(a & 0xff) - if start+n > uint32(len(atomText)) { - return "" - } - return atomText[start : start+n] -} - -func (a Atom) string() string { - return atomText[a>>8 : a>>8+a&0xff] -} - -// fnv computes the FNV hash with an arbitrary starting value h. -func fnv(h uint32, s []byte) uint32 { - for i := range s { - h ^= uint32(s[i]) - h *= 16777619 - } - return h -} - -func match(s string, t []byte) bool { - for i, c := range t { - if s[i] != c { - return false - } - } - return true -} - -// Lookup returns the atom whose name is s. It returns zero if there is no -// such atom. The lookup is case sensitive. -func Lookup(s []byte) Atom { - if len(s) == 0 || len(s) > maxAtomLen { - return 0 - } - h := fnv(hash0, s) - if a := table[h&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) { - return a - } - if a := table[(h>>16)&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) { - return a - } - return 0 -} - -// String returns a string whose contents are equal to s. In that sense, it is -// equivalent to string(s) but may be more efficient. -func String(s []byte) string { - if a := Lookup(s); a != 0 { - return a.String() - } - return string(s) -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/atom/atom_test.go gcc-4.8.1/libgo/go/exp/html/atom/atom_test.go --- gcc-4.8.1.orig/libgo/go/exp/html/atom/atom_test.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/html/atom/atom_test.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,109 +0,0 @@ -// 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 atom - -import ( - "sort" - "testing" -) - -func TestKnown(t *testing.T) { - for _, s := range testAtomList { - if atom := Lookup([]byte(s)); atom.String() != s { - t.Errorf("Lookup(%q) = %#x (%q)", s, uint32(atom), atom.String()) - } - } -} - -func TestHits(t *testing.T) { - for _, a := range table { - if a == 0 { - continue - } - got := Lookup([]byte(a.String())) - if got != a { - t.Errorf("Lookup(%q) = %#x, want %#x", a.String(), uint32(got), uint32(a)) - } - } -} - -func TestMisses(t *testing.T) { - testCases := []string{ - "", - "\x00", - "\xff", - "A", - "DIV", - "Div", - "dIV", - "aa", - "a\x00", - "ab", - "abb", - "abbr0", - "abbr ", - " abbr", - " a", - "acceptcharset", - "acceptCharset", - "accept_charset", - "h0", - "h1h2", - "h7", - "onClick", - "λ", - // The following string has the same hash (0xa1d7fab7) as "onmouseover". - "\x00\x00\x00\x00\x00\x50\x18\xae\x38\xd0\xb7", - } - for _, tc := range testCases { - got := Lookup([]byte(tc)) - if got != 0 { - t.Errorf("Lookup(%q): got %d, want 0", tc, got) - } - } -} - -func TestForeignObject(t *testing.T) { - const ( - afo = Foreignobject - afO = ForeignObject - sfo = "foreignobject" - sfO = "foreignObject" - ) - if got := Lookup([]byte(sfo)); got != afo { - t.Errorf("Lookup(%q): got %#v, want %#v", sfo, got, afo) - } - if got := Lookup([]byte(sfO)); got != afO { - t.Errorf("Lookup(%q): got %#v, want %#v", sfO, got, afO) - } - if got := afo.String(); got != sfo { - t.Errorf("Atom(%#v).String(): got %q, want %q", afo, got, sfo) - } - if got := afO.String(); got != sfO { - t.Errorf("Atom(%#v).String(): got %q, want %q", afO, got, sfO) - } -} - -func BenchmarkLookup(b *testing.B) { - sortedTable := make([]string, 0, len(table)) - for _, a := range table { - if a != 0 { - sortedTable = append(sortedTable, a.String()) - } - } - sort.Strings(sortedTable) - - x := make([][]byte, 1000) - for i := range x { - x[i] = []byte(sortedTable[i%len(sortedTable)]) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - for _, s := range x { - Lookup(s) - } - } -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/atom/gen.go gcc-4.8.1/libgo/go/exp/html/atom/gen.go --- gcc-4.8.1.orig/libgo/go/exp/html/atom/gen.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/html/atom/gen.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,636 +0,0 @@ -// 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 - -package main - -// This program generates table.go and table_test.go. -// Invoke as -// -// go run gen.go |gofmt >table.go -// go run gen.go -test |gofmt >table_test.go - -import ( - "flag" - "fmt" - "math/rand" - "os" - "sort" - "strings" -) - -// identifier converts s to a Go exported identifier. -// It converts "div" to "Div" and "accept-charset" to "AcceptCharset". -func identifier(s string) string { - b := make([]byte, 0, len(s)) - cap := true - for _, c := range s { - if c == '-' { - cap = true - continue - } - if cap && 'a' <= c && c <= 'z' { - c -= 'a' - 'A' - } - cap = false - b = append(b, byte(c)) - } - return string(b) -} - -var test = flag.Bool("test", false, "generate table_test.go") - -func main() { - flag.Parse() - - var all []string - all = append(all, elements...) - all = append(all, attributes...) - all = append(all, eventHandlers...) - all = append(all, extra...) - sort.Strings(all) - - if *test { - fmt.Printf("// generated by go run gen.go -test; DO NOT EDIT\n\n") - fmt.Printf("package atom\n\n") - fmt.Printf("var testAtomList = []string{\n") - for _, s := range all { - fmt.Printf("\t%q,\n", s) - } - fmt.Printf("}\n") - return - } - - // uniq - lists have dups - // compute max len too - maxLen := 0 - w := 0 - for _, s := range all { - if w == 0 || all[w-1] != s { - if maxLen < len(s) { - maxLen = len(s) - } - all[w] = s - w++ - } - } - all = all[:w] - - // Find hash that minimizes table size. - var best *table - for i := 0; i < 1000000; i++ { - if best != nil && 1<<(best.k-1) < len(all) { - break - } - h := rand.Uint32() - for k := uint(0); k <= 16; k++ { - if best != nil && k >= best.k { - break - } - var t table - if t.init(h, k, all) { - best = &t - break - } - } - } - if best == nil { - fmt.Fprintf(os.Stderr, "failed to construct string table\n") - os.Exit(1) - } - - // Lay out strings, using overlaps when possible. - layout := append([]string{}, all...) - - // Remove strings that are substrings of other strings - for changed := true; changed; { - changed = false - for i, s := range layout { - if s == "" { - continue - } - for j, t := range layout { - if i != j && t != "" && strings.Contains(s, t) { - changed = true - layout[j] = "" - } - } - } - } - - // Join strings where one suffix matches another prefix. - for { - // Find best i, j, k such that layout[i][len-k:] == layout[j][:k], - // maximizing overlap length k. - besti := -1 - bestj := -1 - bestk := 0 - for i, s := range layout { - if s == "" { - continue - } - for j, t := range layout { - if i == j { - continue - } - for k := bestk + 1; k <= len(s) && k <= len(t); k++ { - if s[len(s)-k:] == t[:k] { - besti = i - bestj = j - bestk = k - } - } - } - } - if bestk > 0 { - layout[besti] += layout[bestj][bestk:] - layout[bestj] = "" - continue - } - break - } - - text := strings.Join(layout, "") - - atom := map[string]uint32{} - for _, s := range all { - off := strings.Index(text, s) - if off < 0 { - panic("lost string " + s) - } - atom[s] = uint32(off<<8 | len(s)) - } - - // Generate the Go code. - fmt.Printf("// generated by go run gen.go; DO NOT EDIT\n\n") - fmt.Printf("package atom\n\nconst (\n") - for _, s := range all { - fmt.Printf("\t%s Atom = %#x\n", identifier(s), atom[s]) - } - fmt.Printf(")\n\n") - - fmt.Printf("const hash0 = %#x\n\n", best.h0) - fmt.Printf("const maxAtomLen = %d\n\n", maxLen) - - fmt.Printf("var table = [1<<%d]Atom{\n", best.k) - for i, s := range best.tab { - if s == "" { - continue - } - fmt.Printf("\t%#x: %#x, // %s\n", i, atom[s], s) - } - fmt.Printf("}\n") - datasize := (1 << best.k) * 4 - - fmt.Printf("const atomText =\n") - textsize := len(text) - for len(text) > 60 { - fmt.Printf("\t%q +\n", text[:60]) - text = text[60:] - } - fmt.Printf("\t%q\n\n", text) - - fmt.Fprintf(os.Stderr, "%d atoms; %d string bytes + %d tables = %d total data\n", len(all), textsize, datasize, textsize+datasize) -} - -type byLen []string - -func (x byLen) Less(i, j int) bool { return len(x[i]) > len(x[j]) } -func (x byLen) Swap(i, j int) { x[i], x[j] = x[j], x[i] } -func (x byLen) Len() int { return len(x) } - -// fnv computes the FNV hash with an arbitrary starting value h. -func fnv(h uint32, s string) uint32 { - for i := 0; i < len(s); i++ { - h ^= uint32(s[i]) - h *= 16777619 - } - return h -} - -// A table represents an attempt at constructing the lookup table. -// The lookup table uses cuckoo hashing, meaning that each string -// can be found in one of two positions. -type table struct { - h0 uint32 - k uint - mask uint32 - tab []string -} - -// hash returns the two hashes for s. -func (t *table) hash(s string) (h1, h2 uint32) { - h := fnv(t.h0, s) - h1 = h & t.mask - h2 = (h >> 16) & t.mask - return -} - -// init initializes the table with the given parameters. -// h0 is the initial hash value, -// k is the number of bits of hash value to use, and -// x is the list of strings to store in the table. -// init returns false if the table cannot be constructed. -func (t *table) init(h0 uint32, k uint, x []string) bool { - t.h0 = h0 - t.k = k - t.tab = make([]string, 1< len(t.tab) { - return false - } - s := t.tab[i] - h1, h2 := t.hash(s) - j := h1 + h2 - i - if t.tab[j] != "" && !t.push(j, depth+1) { - return false - } - t.tab[j] = s - return true -} - -// The lists of element names and attribute keys were taken from -// http://www.whatwg.org/specs/web-apps/current-work/multipage/section-index.html -// as of the "HTML Living Standard - Last Updated 30 May 2012" version. - -var elements = []string{ - "a", - "abbr", - "address", - "area", - "article", - "aside", - "audio", - "b", - "base", - "bdi", - "bdo", - "blockquote", - "body", - "br", - "button", - "canvas", - "caption", - "cite", - "code", - "col", - "colgroup", - "command", - "data", - "datalist", - "dd", - "del", - "details", - "dfn", - "dialog", - "div", - "dl", - "dt", - "em", - "embed", - "fieldset", - "figcaption", - "figure", - "footer", - "form", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "head", - "header", - "hgroup", - "hr", - "html", - "i", - "iframe", - "img", - "input", - "ins", - "kbd", - "keygen", - "label", - "legend", - "li", - "link", - "map", - "mark", - "menu", - "meta", - "meter", - "nav", - "noscript", - "object", - "ol", - "optgroup", - "option", - "output", - "p", - "param", - "pre", - "progress", - "q", - "rp", - "rt", - "ruby", - "s", - "samp", - "script", - "section", - "select", - "small", - "source", - "span", - "strong", - "style", - "sub", - "summary", - "sup", - "table", - "tbody", - "td", - "textarea", - "tfoot", - "th", - "thead", - "time", - "title", - "tr", - "track", - "u", - "ul", - "var", - "video", - "wbr", -} - -var attributes = []string{ - "accept", - "accept-charset", - "accesskey", - "action", - "alt", - "async", - "autocomplete", - "autofocus", - "autoplay", - "border", - "challenge", - "charset", - "checked", - "cite", - "class", - "cols", - "colspan", - "command", - "content", - "contenteditable", - "contextmenu", - "controls", - "coords", - "crossorigin", - "data", - "datetime", - "default", - "defer", - "dir", - "dirname", - "disabled", - "download", - "draggable", - "dropzone", - "enctype", - "for", - "form", - "formaction", - "formenctype", - "formmethod", - "formnovalidate", - "formtarget", - "headers", - "height", - "hidden", - "high", - "href", - "hreflang", - "http-equiv", - "icon", - "id", - "inert", - "ismap", - "itemid", - "itemprop", - "itemref", - "itemscope", - "itemtype", - "keytype", - "kind", - "label", - "lang", - "list", - "loop", - "low", - "manifest", - "max", - "maxlength", - "media", - "mediagroup", - "method", - "min", - "multiple", - "muted", - "name", - "novalidate", - "open", - "optimum", - "pattern", - "ping", - "placeholder", - "poster", - "preload", - "radiogroup", - "readonly", - "rel", - "required", - "reversed", - "rows", - "rowspan", - "sandbox", - "spellcheck", - "scope", - "scoped", - "seamless", - "selected", - "shape", - "size", - "sizes", - "span", - "src", - "srcdoc", - "srclang", - "start", - "step", - "style", - "tabindex", - "target", - "title", - "translate", - "type", - "typemustmatch", - "usemap", - "value", - "width", - "wrap", -} - -var eventHandlers = []string{ - "onabort", - "onafterprint", - "onbeforeprint", - "onbeforeunload", - "onblur", - "oncancel", - "oncanplay", - "oncanplaythrough", - "onchange", - "onclick", - "onclose", - "oncontextmenu", - "oncuechange", - "ondblclick", - "ondrag", - "ondragend", - "ondragenter", - "ondragleave", - "ondragover", - "ondragstart", - "ondrop", - "ondurationchange", - "onemptied", - "onended", - "onerror", - "onfocus", - "onhashchange", - "oninput", - "oninvalid", - "onkeydown", - "onkeypress", - "onkeyup", - "onload", - "onloadeddata", - "onloadedmetadata", - "onloadstart", - "onmessage", - "onmousedown", - "onmousemove", - "onmouseout", - "onmouseover", - "onmouseup", - "onmousewheel", - "onoffline", - "ononline", - "onpagehide", - "onpageshow", - "onpause", - "onplay", - "onplaying", - "onpopstate", - "onprogress", - "onratechange", - "onreset", - "onresize", - "onscroll", - "onseeked", - "onseeking", - "onselect", - "onshow", - "onstalled", - "onstorage", - "onsubmit", - "onsuspend", - "ontimeupdate", - "onunload", - "onvolumechange", - "onwaiting", -} - -// extra are ad-hoc values not covered by any of the lists above. -var extra = []string{ - "align", - "annotation", - "annotation-xml", - "applet", - "basefont", - "bgsound", - "big", - "blink", - "center", - "color", - "desc", - "face", - "font", - "foreignObject", // HTML is case-insensitive, but SVG-embedded-in-HTML is case-sensitive. - "foreignobject", - "frame", - "frameset", - "image", - "isindex", - "listing", - "malignmark", - "marquee", - "math", - "mglyph", - "mi", - "mn", - "mo", - "ms", - "mtext", - "nobr", - "noembed", - "noframes", - "plaintext", - "prompt", - "public", - "spacer", - "strike", - "svg", - "system", - "tt", - "xmp", -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/atom/table.go gcc-4.8.1/libgo/go/exp/html/atom/table.go --- gcc-4.8.1.orig/libgo/go/exp/html/atom/table.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/html/atom/table.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,694 +0,0 @@ -// generated by go run gen.go; DO NOT EDIT - -package atom - -const ( - A Atom = 0x1 - Abbr Atom = 0x4 - Accept Atom = 0x2106 - AcceptCharset Atom = 0x210e - Accesskey Atom = 0x3309 - Action Atom = 0x21b06 - Address Atom = 0x5d507 - Align Atom = 0x1105 - Alt Atom = 0x4503 - Annotation Atom = 0x18d0a - AnnotationXml Atom = 0x18d0e - Applet Atom = 0x2d106 - Area Atom = 0x31804 - Article Atom = 0x39907 - Aside Atom = 0x4f05 - Async Atom = 0x9305 - Audio Atom = 0xaf05 - Autocomplete Atom = 0xd50c - Autofocus Atom = 0xe109 - Autoplay Atom = 0x10c08 - B Atom = 0x101 - Base Atom = 0x11404 - Basefont Atom = 0x11408 - Bdi Atom = 0x1a03 - Bdo Atom = 0x12503 - Bgsound Atom = 0x13807 - Big Atom = 0x14403 - Blink Atom = 0x14705 - Blockquote Atom = 0x14c0a - Body Atom = 0x2f04 - Border Atom = 0x15606 - Br Atom = 0x202 - Button Atom = 0x15c06 - Canvas Atom = 0x4b06 - Caption Atom = 0x1e007 - Center Atom = 0x2df06 - Challenge Atom = 0x23e09 - Charset Atom = 0x2807 - Checked Atom = 0x33f07 - Cite Atom = 0x9704 - Class Atom = 0x3d905 - Code Atom = 0x16f04 - Col Atom = 0x17603 - Colgroup Atom = 0x17608 - Color Atom = 0x18305 - Cols Atom = 0x18804 - Colspan Atom = 0x18807 - Command Atom = 0x19b07 - Content Atom = 0x42c07 - Contenteditable Atom = 0x42c0f - Contextmenu Atom = 0x3480b - Controls Atom = 0x1ae08 - Coords Atom = 0x1ba06 - Crossorigin Atom = 0x1c40b - Data Atom = 0x44304 - Datalist Atom = 0x44308 - Datetime Atom = 0x25b08 - Dd Atom = 0x28802 - Default Atom = 0x5207 - Defer Atom = 0x17105 - Del Atom = 0x4d603 - Desc Atom = 0x4804 - Details Atom = 0x6507 - Dfn Atom = 0x8303 - Dialog Atom = 0x1b06 - Dir Atom = 0x9d03 - Dirname Atom = 0x9d07 - Disabled Atom = 0x10008 - Div Atom = 0x10703 - Dl Atom = 0x13e02 - Download Atom = 0x40908 - Draggable Atom = 0x1a109 - Dropzone Atom = 0x3a208 - Dt Atom = 0x4e402 - Em Atom = 0x7f02 - Embed Atom = 0x7f05 - Enctype Atom = 0x23007 - Face Atom = 0x2dd04 - Fieldset Atom = 0x1d508 - Figcaption Atom = 0x1dd0a - Figure Atom = 0x1f106 - Font Atom = 0x11804 - Footer Atom = 0x5906 - For Atom = 0x1fd03 - ForeignObject Atom = 0x1fd0d - Foreignobject Atom = 0x20a0d - Form Atom = 0x21704 - Formaction Atom = 0x2170a - Formenctype Atom = 0x22c0b - Formmethod Atom = 0x2470a - Formnovalidate Atom = 0x2510e - Formtarget Atom = 0x2660a - Frame Atom = 0x8705 - Frameset Atom = 0x8708 - H1 Atom = 0x13602 - H2 Atom = 0x29602 - H3 Atom = 0x2c502 - H4 Atom = 0x30e02 - H5 Atom = 0x4e602 - H6 Atom = 0x27002 - Head Atom = 0x2fa04 - Header Atom = 0x2fa06 - Headers Atom = 0x2fa07 - Height Atom = 0x27206 - Hgroup Atom = 0x27a06 - Hidden Atom = 0x28606 - High Atom = 0x29304 - Hr Atom = 0x13102 - Href Atom = 0x29804 - Hreflang Atom = 0x29808 - Html Atom = 0x27604 - HttpEquiv Atom = 0x2a00a - I Atom = 0x601 - Icon Atom = 0x42b04 - Id Atom = 0x5102 - Iframe Atom = 0x2b406 - Image Atom = 0x2ba05 - Img Atom = 0x2bf03 - Inert Atom = 0x4c105 - Input Atom = 0x3f605 - Ins Atom = 0x1cd03 - Isindex Atom = 0x2c707 - Ismap Atom = 0x2ce05 - Itemid Atom = 0x9806 - Itemprop Atom = 0x57e08 - Itemref Atom = 0x2d707 - Itemscope Atom = 0x2e509 - Itemtype Atom = 0x2ef08 - Kbd Atom = 0x1903 - Keygen Atom = 0x3906 - Keytype Atom = 0x51207 - Kind Atom = 0xfd04 - Label Atom = 0xba05 - Lang Atom = 0x29c04 - Legend Atom = 0x1a806 - Li Atom = 0x1202 - Link Atom = 0x14804 - List Atom = 0x44704 - Listing Atom = 0x44707 - Loop Atom = 0xbe04 - Low Atom = 0x13f03 - Malignmark Atom = 0x100a - Manifest Atom = 0x5b608 - Map Atom = 0x2d003 - Mark Atom = 0x1604 - Marquee Atom = 0x5f207 - Math Atom = 0x2f704 - Max Atom = 0x30603 - Maxlength Atom = 0x30609 - Media Atom = 0xa205 - Mediagroup Atom = 0xa20a - Menu Atom = 0x34f04 - Meta Atom = 0x45604 - Meter Atom = 0x26105 - Method Atom = 0x24b06 - Mglyph Atom = 0x2c006 - Mi Atom = 0x9b02 - Min Atom = 0x31003 - Mn Atom = 0x25402 - Mo Atom = 0x47a02 - Ms Atom = 0x2e802 - Mtext Atom = 0x31305 - Multiple Atom = 0x32108 - Muted Atom = 0x32905 - Name Atom = 0xa004 - Nav Atom = 0x3e03 - Nobr Atom = 0x7404 - Noembed Atom = 0x7d07 - Noframes Atom = 0x8508 - Noscript Atom = 0x28b08 - Novalidate Atom = 0x2550a - Object Atom = 0x21106 - Ol Atom = 0xcd02 - Onabort Atom = 0x16007 - Onafterprint Atom = 0x1e50c - Onbeforeprint Atom = 0x21f0d - Onbeforeunload Atom = 0x5c90e - Onblur Atom = 0x3e206 - Oncancel Atom = 0xb308 - Oncanplay Atom = 0x12709 - Oncanplaythrough Atom = 0x12710 - Onchange Atom = 0x3b808 - Onclick Atom = 0x2ad07 - Onclose Atom = 0x32e07 - Oncontextmenu Atom = 0x3460d - Oncuechange Atom = 0x3530b - Ondblclick Atom = 0x35e0a - Ondrag Atom = 0x36806 - Ondragend Atom = 0x36809 - Ondragenter Atom = 0x3710b - Ondragleave Atom = 0x37c0b - Ondragover Atom = 0x3870a - Ondragstart Atom = 0x3910b - Ondrop Atom = 0x3a006 - Ondurationchange Atom = 0x3b010 - Onemptied Atom = 0x3a709 - Onended Atom = 0x3c007 - Onerror Atom = 0x3c707 - Onfocus Atom = 0x3ce07 - Onhashchange Atom = 0x3e80c - Oninput Atom = 0x3f407 - Oninvalid Atom = 0x3fb09 - Onkeydown Atom = 0x40409 - Onkeypress Atom = 0x4110a - Onkeyup Atom = 0x42107 - Onload Atom = 0x43b06 - Onloadeddata Atom = 0x43b0c - Onloadedmetadata Atom = 0x44e10 - Onloadstart Atom = 0x4640b - Onmessage Atom = 0x46f09 - Onmousedown Atom = 0x4780b - Onmousemove Atom = 0x4830b - Onmouseout Atom = 0x48e0a - Onmouseover Atom = 0x49b0b - Onmouseup Atom = 0x4a609 - Onmousewheel Atom = 0x4af0c - Onoffline Atom = 0x4bb09 - Ononline Atom = 0x4c608 - Onpagehide Atom = 0x4ce0a - Onpageshow Atom = 0x4d90a - Onpause Atom = 0x4e807 - Onplay Atom = 0x4f206 - Onplaying Atom = 0x4f209 - Onpopstate Atom = 0x4fb0a - Onprogress Atom = 0x5050a - Onratechange Atom = 0x5190c - Onreset Atom = 0x52507 - Onresize Atom = 0x52c08 - Onscroll Atom = 0x53a08 - Onseeked Atom = 0x54208 - Onseeking Atom = 0x54a09 - Onselect Atom = 0x55308 - Onshow Atom = 0x55d06 - Onstalled Atom = 0x56609 - Onstorage Atom = 0x56f09 - Onsubmit Atom = 0x57808 - Onsuspend Atom = 0x58809 - Ontimeupdate Atom = 0x1190c - Onunload Atom = 0x59108 - Onvolumechange Atom = 0x5990e - Onwaiting Atom = 0x5a709 - Open Atom = 0x58404 - Optgroup Atom = 0xc008 - Optimum Atom = 0x5b007 - Option Atom = 0x5c506 - Output Atom = 0x49506 - P Atom = 0xc01 - Param Atom = 0xc05 - Pattern Atom = 0x6e07 - Ping Atom = 0xab04 - Placeholder Atom = 0xc70b - Plaintext Atom = 0xf109 - Poster Atom = 0x17d06 - Pre Atom = 0x27f03 - Preload Atom = 0x27f07 - Progress Atom = 0x50708 - Prompt Atom = 0x5bf06 - Public Atom = 0x42706 - Q Atom = 0x15101 - Radiogroup Atom = 0x30a - Readonly Atom = 0x31908 - Rel Atom = 0x28003 - Required Atom = 0x1f508 - Reversed Atom = 0x5e08 - Rows Atom = 0x7704 - Rowspan Atom = 0x7707 - Rp Atom = 0x1eb02 - Rt Atom = 0x16502 - Ruby Atom = 0xd104 - S Atom = 0x2c01 - Samp Atom = 0x6b04 - Sandbox Atom = 0xe907 - Scope Atom = 0x2e905 - Scoped Atom = 0x2e906 - Script Atom = 0x28d06 - Seamless Atom = 0x33308 - Section Atom = 0x3dd07 - Select Atom = 0x55506 - Selected Atom = 0x55508 - Shape Atom = 0x1b505 - Size Atom = 0x53004 - Sizes Atom = 0x53005 - Small Atom = 0x1bf05 - Source Atom = 0x1cf06 - Spacer Atom = 0x30006 - Span Atom = 0x7a04 - Spellcheck Atom = 0x33a0a - Src Atom = 0x3d403 - Srcdoc Atom = 0x3d406 - Srclang Atom = 0x41a07 - Start Atom = 0x39705 - Step Atom = 0x5bc04 - Strike Atom = 0x50e06 - Strong Atom = 0x53406 - Style Atom = 0x5db05 - Sub Atom = 0x57a03 - Summary Atom = 0x5e007 - Sup Atom = 0x5e703 - Svg Atom = 0x5ea03 - System Atom = 0x5ed06 - Tabindex Atom = 0x45c08 - Table Atom = 0x43605 - Target Atom = 0x26a06 - Tbody Atom = 0x2e05 - Td Atom = 0x4702 - Textarea Atom = 0x31408 - Tfoot Atom = 0x5805 - Th Atom = 0x13002 - Thead Atom = 0x2f905 - Time Atom = 0x11b04 - Title Atom = 0x8e05 - Tr Atom = 0xf902 - Track Atom = 0xf905 - Translate Atom = 0x16609 - Tt Atom = 0x7002 - Type Atom = 0x23304 - Typemustmatch Atom = 0x2330d - U Atom = 0xb01 - Ul Atom = 0x5602 - Usemap Atom = 0x4ec06 - Value Atom = 0x4005 - Var Atom = 0x10903 - Video Atom = 0x2a905 - Wbr Atom = 0x14103 - Width Atom = 0x4e205 - Wrap Atom = 0x56204 - Xmp Atom = 0xef03 -) - -const hash0 = 0xc17da63e - -const maxAtomLen = 16 - -var table = [1 << 9]Atom{ - 0x1: 0x4830b, // onmousemove - 0x2: 0x5a709, // onwaiting - 0x4: 0x5bf06, // prompt - 0x7: 0x5b007, // optimum - 0x8: 0x1604, // mark - 0xa: 0x2d707, // itemref - 0xb: 0x4d90a, // onpageshow - 0xc: 0x55506, // select - 0xd: 0x1a109, // draggable - 0xe: 0x3e03, // nav - 0xf: 0x19b07, // command - 0x11: 0xb01, // u - 0x14: 0x2fa07, // headers - 0x15: 0x44308, // datalist - 0x17: 0x6b04, // samp - 0x1a: 0x40409, // onkeydown - 0x1b: 0x53a08, // onscroll - 0x1c: 0x17603, // col - 0x20: 0x57e08, // itemprop - 0x21: 0x2a00a, // http-equiv - 0x22: 0x5e703, // sup - 0x24: 0x1f508, // required - 0x2b: 0x27f07, // preload - 0x2c: 0x21f0d, // onbeforeprint - 0x2d: 0x3710b, // ondragenter - 0x2e: 0x4e402, // dt - 0x2f: 0x57808, // onsubmit - 0x30: 0x13102, // hr - 0x31: 0x3460d, // oncontextmenu - 0x33: 0x2ba05, // image - 0x34: 0x4e807, // onpause - 0x35: 0x27a06, // hgroup - 0x36: 0xab04, // ping - 0x37: 0x55308, // onselect - 0x3a: 0x10703, // div - 0x40: 0x9b02, // mi - 0x41: 0x33308, // seamless - 0x42: 0x2807, // charset - 0x43: 0x5102, // id - 0x44: 0x4fb0a, // onpopstate - 0x45: 0x4d603, // del - 0x46: 0x5f207, // marquee - 0x47: 0x3309, // accesskey - 0x49: 0x5906, // footer - 0x4a: 0x2d106, // applet - 0x4b: 0x2ce05, // ismap - 0x51: 0x34f04, // menu - 0x52: 0x2f04, // body - 0x55: 0x8708, // frameset - 0x56: 0x52507, // onreset - 0x57: 0x14705, // blink - 0x58: 0x8e05, // title - 0x59: 0x39907, // article - 0x5b: 0x13002, // th - 0x5d: 0x15101, // q - 0x5e: 0x58404, // open - 0x5f: 0x31804, // area - 0x61: 0x43b06, // onload - 0x62: 0x3f605, // input - 0x63: 0x11404, // base - 0x64: 0x18807, // colspan - 0x65: 0x51207, // keytype - 0x66: 0x13e02, // dl - 0x68: 0x1d508, // fieldset - 0x6a: 0x31003, // min - 0x6b: 0x10903, // var - 0x6f: 0x2fa06, // header - 0x70: 0x16502, // rt - 0x71: 0x17608, // colgroup - 0x72: 0x25402, // mn - 0x74: 0x16007, // onabort - 0x75: 0x3906, // keygen - 0x76: 0x4bb09, // onoffline - 0x77: 0x23e09, // challenge - 0x78: 0x2d003, // map - 0x7a: 0x30e02, // h4 - 0x7b: 0x3c707, // onerror - 0x7c: 0x30609, // maxlength - 0x7d: 0x31305, // mtext - 0x7e: 0x5805, // tfoot - 0x7f: 0x11804, // font - 0x80: 0x100a, // malignmark - 0x81: 0x45604, // meta - 0x82: 0x9305, // async - 0x83: 0x2c502, // h3 - 0x84: 0x28802, // dd - 0x85: 0x29804, // href - 0x86: 0xa20a, // mediagroup - 0x87: 0x1ba06, // coords - 0x88: 0x41a07, // srclang - 0x89: 0x35e0a, // ondblclick - 0x8a: 0x4005, // value - 0x8c: 0xb308, // oncancel - 0x8e: 0x33a0a, // spellcheck - 0x8f: 0x8705, // frame - 0x91: 0x14403, // big - 0x94: 0x21b06, // action - 0x95: 0x9d03, // dir - 0x97: 0x31908, // readonly - 0x99: 0x43605, // table - 0x9a: 0x5e007, // summary - 0x9b: 0x14103, // wbr - 0x9c: 0x30a, // radiogroup - 0x9d: 0xa004, // name - 0x9f: 0x5ed06, // system - 0xa1: 0x18305, // color - 0xa2: 0x4b06, // canvas - 0xa3: 0x27604, // html - 0xa5: 0x54a09, // onseeking - 0xac: 0x1b505, // shape - 0xad: 0x28003, // rel - 0xae: 0x12710, // oncanplaythrough - 0xaf: 0x3870a, // ondragover - 0xb1: 0x1fd0d, // foreignObject - 0xb3: 0x7704, // rows - 0xb6: 0x44707, // listing - 0xb7: 0x49506, // output - 0xb9: 0x3480b, // contextmenu - 0xbb: 0x13f03, // low - 0xbc: 0x1eb02, // rp - 0xbd: 0x58809, // onsuspend - 0xbe: 0x15c06, // button - 0xbf: 0x4804, // desc - 0xc1: 0x3dd07, // section - 0xc2: 0x5050a, // onprogress - 0xc3: 0x56f09, // onstorage - 0xc4: 0x2f704, // math - 0xc5: 0x4f206, // onplay - 0xc7: 0x5602, // ul - 0xc8: 0x6e07, // pattern - 0xc9: 0x4af0c, // onmousewheel - 0xca: 0x36809, // ondragend - 0xcb: 0xd104, // ruby - 0xcc: 0xc01, // p - 0xcd: 0x32e07, // onclose - 0xce: 0x26105, // meter - 0xcf: 0x13807, // bgsound - 0xd2: 0x27206, // height - 0xd4: 0x101, // b - 0xd5: 0x2ef08, // itemtype - 0xd8: 0x1e007, // caption - 0xd9: 0x10008, // disabled - 0xdc: 0x5ea03, // svg - 0xdd: 0x1bf05, // small - 0xde: 0x44304, // data - 0xe0: 0x4c608, // ononline - 0xe1: 0x2c006, // mglyph - 0xe3: 0x7f05, // embed - 0xe4: 0xf902, // tr - 0xe5: 0x4640b, // onloadstart - 0xe7: 0x3b010, // ondurationchange - 0xed: 0x12503, // bdo - 0xee: 0x4702, // td - 0xef: 0x4f05, // aside - 0xf0: 0x29602, // h2 - 0xf1: 0x50708, // progress - 0xf2: 0x14c0a, // blockquote - 0xf4: 0xba05, // label - 0xf5: 0x601, // i - 0xf7: 0x7707, // rowspan - 0xfb: 0x4f209, // onplaying - 0xfd: 0x2bf03, // img - 0xfe: 0xc008, // optgroup - 0xff: 0x42c07, // content - 0x101: 0x5190c, // onratechange - 0x103: 0x3e80c, // onhashchange - 0x104: 0x6507, // details - 0x106: 0x40908, // download - 0x109: 0xe907, // sandbox - 0x10b: 0x42c0f, // contenteditable - 0x10d: 0x37c0b, // ondragleave - 0x10e: 0x2106, // accept - 0x10f: 0x55508, // selected - 0x112: 0x2170a, // formaction - 0x113: 0x2df06, // center - 0x115: 0x44e10, // onloadedmetadata - 0x116: 0x14804, // link - 0x117: 0x11b04, // time - 0x118: 0x1c40b, // crossorigin - 0x119: 0x3ce07, // onfocus - 0x11a: 0x56204, // wrap - 0x11b: 0x42b04, // icon - 0x11d: 0x2a905, // video - 0x11e: 0x3d905, // class - 0x121: 0x5990e, // onvolumechange - 0x122: 0x3e206, // onblur - 0x123: 0x2e509, // itemscope - 0x124: 0x5db05, // style - 0x127: 0x42706, // public - 0x129: 0x2510e, // formnovalidate - 0x12a: 0x55d06, // onshow - 0x12c: 0x16609, // translate - 0x12d: 0x9704, // cite - 0x12e: 0x2e802, // ms - 0x12f: 0x1190c, // ontimeupdate - 0x130: 0xfd04, // kind - 0x131: 0x2660a, // formtarget - 0x135: 0x3c007, // onended - 0x136: 0x28606, // hidden - 0x137: 0x2c01, // s - 0x139: 0x2470a, // formmethod - 0x13a: 0x44704, // list - 0x13c: 0x27002, // h6 - 0x13d: 0xcd02, // ol - 0x13e: 0x3530b, // oncuechange - 0x13f: 0x20a0d, // foreignobject - 0x143: 0x5c90e, // onbeforeunload - 0x145: 0x3a709, // onemptied - 0x146: 0x17105, // defer - 0x147: 0xef03, // xmp - 0x148: 0xaf05, // audio - 0x149: 0x1903, // kbd - 0x14c: 0x46f09, // onmessage - 0x14d: 0x5c506, // option - 0x14e: 0x4503, // alt - 0x14f: 0x33f07, // checked - 0x150: 0x10c08, // autoplay - 0x152: 0x202, // br - 0x153: 0x2550a, // novalidate - 0x156: 0x7d07, // noembed - 0x159: 0x2ad07, // onclick - 0x15a: 0x4780b, // onmousedown - 0x15b: 0x3b808, // onchange - 0x15e: 0x3fb09, // oninvalid - 0x15f: 0x2e906, // scoped - 0x160: 0x1ae08, // controls - 0x161: 0x32905, // muted - 0x163: 0x4ec06, // usemap - 0x164: 0x1dd0a, // figcaption - 0x165: 0x36806, // ondrag - 0x166: 0x29304, // high - 0x168: 0x3d403, // src - 0x169: 0x17d06, // poster - 0x16b: 0x18d0e, // annotation-xml - 0x16c: 0x5bc04, // step - 0x16d: 0x4, // abbr - 0x16e: 0x1b06, // dialog - 0x170: 0x1202, // li - 0x172: 0x47a02, // mo - 0x175: 0x1fd03, // for - 0x176: 0x1cd03, // ins - 0x178: 0x53004, // size - 0x17a: 0x5207, // default - 0x17b: 0x1a03, // bdi - 0x17c: 0x4ce0a, // onpagehide - 0x17d: 0x9d07, // dirname - 0x17e: 0x23304, // type - 0x17f: 0x21704, // form - 0x180: 0x4c105, // inert - 0x181: 0x12709, // oncanplay - 0x182: 0x8303, // dfn - 0x183: 0x45c08, // tabindex - 0x186: 0x7f02, // em - 0x187: 0x29c04, // lang - 0x189: 0x3a208, // dropzone - 0x18a: 0x4110a, // onkeypress - 0x18b: 0x25b08, // datetime - 0x18c: 0x18804, // cols - 0x18d: 0x1, // a - 0x18e: 0x43b0c, // onloadeddata - 0x191: 0x15606, // border - 0x192: 0x2e05, // tbody - 0x193: 0x24b06, // method - 0x195: 0xbe04, // loop - 0x196: 0x2b406, // iframe - 0x198: 0x2fa04, // head - 0x19e: 0x5b608, // manifest - 0x19f: 0xe109, // autofocus - 0x1a0: 0x16f04, // code - 0x1a1: 0x53406, // strong - 0x1a2: 0x32108, // multiple - 0x1a3: 0xc05, // param - 0x1a6: 0x23007, // enctype - 0x1a7: 0x2dd04, // face - 0x1a8: 0xf109, // plaintext - 0x1a9: 0x13602, // h1 - 0x1aa: 0x56609, // onstalled - 0x1ad: 0x28d06, // script - 0x1ae: 0x30006, // spacer - 0x1af: 0x52c08, // onresize - 0x1b0: 0x49b0b, // onmouseover - 0x1b1: 0x59108, // onunload - 0x1b2: 0x54208, // onseeked - 0x1b4: 0x2330d, // typemustmatch - 0x1b5: 0x1f106, // figure - 0x1b6: 0x48e0a, // onmouseout - 0x1b7: 0x27f03, // pre - 0x1b8: 0x4e205, // width - 0x1bb: 0x7404, // nobr - 0x1be: 0x7002, // tt - 0x1bf: 0x1105, // align - 0x1c0: 0x3f407, // oninput - 0x1c3: 0x42107, // onkeyup - 0x1c6: 0x1e50c, // onafterprint - 0x1c7: 0x210e, // accept-charset - 0x1c8: 0x9806, // itemid - 0x1cb: 0x50e06, // strike - 0x1cc: 0x57a03, // sub - 0x1cd: 0xf905, // track - 0x1ce: 0x39705, // start - 0x1d0: 0x11408, // basefont - 0x1d6: 0x1cf06, // source - 0x1d7: 0x1a806, // legend - 0x1d8: 0x2f905, // thead - 0x1da: 0x2e905, // scope - 0x1dd: 0x21106, // object - 0x1de: 0xa205, // media - 0x1df: 0x18d0a, // annotation - 0x1e0: 0x22c0b, // formenctype - 0x1e2: 0x28b08, // noscript - 0x1e4: 0x53005, // sizes - 0x1e5: 0xd50c, // autocomplete - 0x1e6: 0x7a04, // span - 0x1e7: 0x8508, // noframes - 0x1e8: 0x26a06, // target - 0x1e9: 0x3a006, // ondrop - 0x1ea: 0x3d406, // srcdoc - 0x1ec: 0x5e08, // reversed - 0x1f0: 0x2c707, // isindex - 0x1f3: 0x29808, // hreflang - 0x1f5: 0x4e602, // h5 - 0x1f6: 0x5d507, // address - 0x1fa: 0x30603, // max - 0x1fb: 0xc70b, // placeholder - 0x1fc: 0x31408, // textarea - 0x1fe: 0x4a609, // onmouseup - 0x1ff: 0x3910b, // ondragstart -} - -const atomText = "abbradiogrouparamalignmarkbdialogaccept-charsetbodyaccesskey" + - "genavaluealtdescanvasidefaultfootereversedetailsampatternobr" + - "owspanoembedfnoframesetitleasyncitemidirnamediagroupingaudio" + - "ncancelabelooptgrouplaceholderubyautocompleteautofocusandbox" + - "mplaintextrackindisabledivarautoplaybasefontimeupdatebdoncan" + - "playthrough1bgsoundlowbrbigblinkblockquoteborderbuttonabortr" + - "anslatecodefercolgroupostercolorcolspannotation-xmlcommandra" + - "ggablegendcontrolshapecoordsmallcrossoriginsourcefieldsetfig" + - "captionafterprintfigurequiredforeignObjectforeignobjectforma" + - "ctionbeforeprintformenctypemustmatchallengeformmethodformnov" + - "alidatetimeterformtargeth6heightmlhgroupreloadhiddenoscripth" + - "igh2hreflanghttp-equivideonclickiframeimageimglyph3isindexis" + - "mappletitemrefacenteritemscopeditemtypematheaderspacermaxlen" + - "gth4minmtextareadonlymultiplemutedoncloseamlesspellcheckedon" + - "contextmenuoncuechangeondblclickondragendondragenterondragle" + - "aveondragoverondragstarticleondropzonemptiedondurationchange" + - "onendedonerroronfocusrcdoclassectionbluronhashchangeoninputo" + - "ninvalidonkeydownloadonkeypressrclangonkeyupublicontentedita" + - "bleonloadeddatalistingonloadedmetadatabindexonloadstartonmes" + - "sageonmousedownonmousemoveonmouseoutputonmouseoveronmouseupo" + - "nmousewheelonofflinertononlineonpagehidelonpageshowidth5onpa" + - "usemaponplayingonpopstateonprogresstrikeytypeonratechangeonr" + - "esetonresizestrongonscrollonseekedonseekingonselectedonshowr" + - "aponstalledonstorageonsubmitempropenonsuspendonunloadonvolum" + - "echangeonwaitingoptimumanifestepromptoptionbeforeunloaddress" + - "tylesummarysupsvgsystemarquee" diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/atom/table_test.go gcc-4.8.1/libgo/go/exp/html/atom/table_test.go --- gcc-4.8.1.orig/libgo/go/exp/html/atom/table_test.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/html/atom/table_test.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,341 +0,0 @@ -// generated by go run gen.go -test; DO NOT EDIT - -package atom - -var testAtomList = []string{ - "a", - "abbr", - "accept", - "accept-charset", - "accesskey", - "action", - "address", - "align", - "alt", - "annotation", - "annotation-xml", - "applet", - "area", - "article", - "aside", - "async", - "audio", - "autocomplete", - "autofocus", - "autoplay", - "b", - "base", - "basefont", - "bdi", - "bdo", - "bgsound", - "big", - "blink", - "blockquote", - "body", - "border", - "br", - "button", - "canvas", - "caption", - "center", - "challenge", - "charset", - "checked", - "cite", - "cite", - "class", - "code", - "col", - "colgroup", - "color", - "cols", - "colspan", - "command", - "command", - "content", - "contenteditable", - "contextmenu", - "controls", - "coords", - "crossorigin", - "data", - "data", - "datalist", - "datetime", - "dd", - "default", - "defer", - "del", - "desc", - "details", - "dfn", - "dialog", - "dir", - "dirname", - "disabled", - "div", - "dl", - "download", - "draggable", - "dropzone", - "dt", - "em", - "embed", - "enctype", - "face", - "fieldset", - "figcaption", - "figure", - "font", - "footer", - "for", - "foreignObject", - "foreignobject", - "form", - "form", - "formaction", - "formenctype", - "formmethod", - "formnovalidate", - "formtarget", - "frame", - "frameset", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "head", - "header", - "headers", - "height", - "hgroup", - "hidden", - "high", - "hr", - "href", - "hreflang", - "html", - "http-equiv", - "i", - "icon", - "id", - "iframe", - "image", - "img", - "inert", - "input", - "ins", - "isindex", - "ismap", - "itemid", - "itemprop", - "itemref", - "itemscope", - "itemtype", - "kbd", - "keygen", - "keytype", - "kind", - "label", - "label", - "lang", - "legend", - "li", - "link", - "list", - "listing", - "loop", - "low", - "malignmark", - "manifest", - "map", - "mark", - "marquee", - "math", - "max", - "maxlength", - "media", - "mediagroup", - "menu", - "meta", - "meter", - "method", - "mglyph", - "mi", - "min", - "mn", - "mo", - "ms", - "mtext", - "multiple", - "muted", - "name", - "nav", - "nobr", - "noembed", - "noframes", - "noscript", - "novalidate", - "object", - "ol", - "onabort", - "onafterprint", - "onbeforeprint", - "onbeforeunload", - "onblur", - "oncancel", - "oncanplay", - "oncanplaythrough", - "onchange", - "onclick", - "onclose", - "oncontextmenu", - "oncuechange", - "ondblclick", - "ondrag", - "ondragend", - "ondragenter", - "ondragleave", - "ondragover", - "ondragstart", - "ondrop", - "ondurationchange", - "onemptied", - "onended", - "onerror", - "onfocus", - "onhashchange", - "oninput", - "oninvalid", - "onkeydown", - "onkeypress", - "onkeyup", - "onload", - "onloadeddata", - "onloadedmetadata", - "onloadstart", - "onmessage", - "onmousedown", - "onmousemove", - "onmouseout", - "onmouseover", - "onmouseup", - "onmousewheel", - "onoffline", - "ononline", - "onpagehide", - "onpageshow", - "onpause", - "onplay", - "onplaying", - "onpopstate", - "onprogress", - "onratechange", - "onreset", - "onresize", - "onscroll", - "onseeked", - "onseeking", - "onselect", - "onshow", - "onstalled", - "onstorage", - "onsubmit", - "onsuspend", - "ontimeupdate", - "onunload", - "onvolumechange", - "onwaiting", - "open", - "optgroup", - "optimum", - "option", - "output", - "p", - "param", - "pattern", - "ping", - "placeholder", - "plaintext", - "poster", - "pre", - "preload", - "progress", - "prompt", - "public", - "q", - "radiogroup", - "readonly", - "rel", - "required", - "reversed", - "rows", - "rowspan", - "rp", - "rt", - "ruby", - "s", - "samp", - "sandbox", - "scope", - "scoped", - "script", - "seamless", - "section", - "select", - "selected", - "shape", - "size", - "sizes", - "small", - "source", - "spacer", - "span", - "span", - "spellcheck", - "src", - "srcdoc", - "srclang", - "start", - "step", - "strike", - "strong", - "style", - "style", - "sub", - "summary", - "sup", - "svg", - "system", - "tabindex", - "table", - "target", - "tbody", - "td", - "textarea", - "tfoot", - "th", - "thead", - "time", - "title", - "title", - "tr", - "track", - "translate", - "tt", - "type", - "typemustmatch", - "u", - "ul", - "usemap", - "value", - "var", - "video", - "wbr", - "width", - "wrap", - "xmp", -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/const.go gcc-4.8.1/libgo/go/exp/html/const.go --- gcc-4.8.1.orig/libgo/go/exp/html/const.go 2012-02-01 13:26:59.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/html/const.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,100 +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 html - -// Section 12.2.3.2 of the HTML5 specification says "The following elements -// have varying levels of special parsing rules". -// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-stack-of-open-elements -var isSpecialElementMap = map[string]bool{ - "address": true, - "applet": true, - "area": true, - "article": true, - "aside": true, - "base": true, - "basefont": true, - "bgsound": true, - "blockquote": true, - "body": true, - "br": true, - "button": true, - "caption": true, - "center": true, - "col": true, - "colgroup": true, - "command": true, - "dd": true, - "details": true, - "dir": true, - "div": true, - "dl": true, - "dt": true, - "embed": true, - "fieldset": true, - "figcaption": true, - "figure": true, - "footer": true, - "form": true, - "frame": true, - "frameset": true, - "h1": true, - "h2": true, - "h3": true, - "h4": true, - "h5": true, - "h6": true, - "head": true, - "header": true, - "hgroup": true, - "hr": true, - "html": true, - "iframe": true, - "img": true, - "input": true, - "isindex": true, - "li": true, - "link": true, - "listing": true, - "marquee": true, - "menu": true, - "meta": true, - "nav": true, - "noembed": true, - "noframes": true, - "noscript": true, - "object": true, - "ol": true, - "p": true, - "param": true, - "plaintext": true, - "pre": true, - "script": true, - "section": true, - "select": true, - "style": true, - "summary": true, - "table": true, - "tbody": true, - "td": true, - "textarea": true, - "tfoot": true, - "th": true, - "thead": true, - "title": true, - "tr": true, - "ul": true, - "wbr": true, - "xmp": true, -} - -func isSpecialElement(element *Node) bool { - switch element.Namespace { - case "", "html": - return isSpecialElementMap[element.Data] - case "svg": - return element.Data == "foreignObject" - } - return false -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/doc.go gcc-4.8.1/libgo/go/exp/html/doc.go --- gcc-4.8.1.orig/libgo/go/exp/html/doc.go 2013-01-29 14:52:43.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/html/doc.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,106 +0,0 @@ -// Copyright 2010 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 html implements an HTML5-compliant tokenizer and parser. - -Tokenization is done by creating a Tokenizer for an io.Reader r. It is the -caller's responsibility to ensure that r provides UTF-8 encoded HTML. - - z := html.NewTokenizer(r) - -Given a Tokenizer z, the HTML is tokenized by repeatedly calling z.Next(), -which parses the next token and returns its type, or an error: - - for { - tt := z.Next() - if tt == html.ErrorToken { - // ... - return ... - } - // Process the current token. - } - -There are two APIs for retrieving the current token. The high-level API is to -call Token; the low-level API is to call Text or TagName / TagAttr. Both APIs -allow optionally calling Raw after Next but before Token, Text, TagName, or -TagAttr. In EBNF notation, the valid call sequence per token is: - - Next {Raw} [ Token | Text | TagName {TagAttr} ] - -Token returns an independent data structure that completely describes a token. -Entities (such as "<") are unescaped, tag names and attribute keys are -lower-cased, and attributes are collected into a []Attribute. For example: - - for { - if z.Next() == html.ErrorToken { - // Returning io.EOF indicates success. - return z.Err() - } - emitToken(z.Token()) - } - -The low-level API performs fewer allocations and copies, but the contents of -the []byte values returned by Text, TagName and TagAttr may change on the next -call to Next. For example, to extract an HTML page's anchor text: - - depth := 0 - for { - tt := z.Next() - switch tt { - case ErrorToken: - return z.Err() - case TextToken: - if depth > 0 { - // emitBytes should copy the []byte it receives, - // if it doesn't process it immediately. - emitBytes(z.Text()) - } - case StartTagToken, EndTagToken: - tn, _ := z.TagName() - if len(tn) == 1 && tn[0] == 'a' { - if tt == StartTagToken { - depth++ - } else { - depth-- - } - } - } - } - -Parsing is done by calling Parse with an io.Reader, which returns the root of -the parse tree (the document element) as a *Node. It is the caller's -responsibility to ensure that the Reader provides UTF-8 encoded HTML. For -example, to process each anchor node in depth-first order: - - doc, err := html.Parse(r) - if err != nil { - // ... - } - var f func(*html.Node) - f = func(n *html.Node) { - if n.Type == html.ElementNode && n.Data == "a" { - // Do something with n... - } - for c := n.FirstChild; c != nil; c = c.NextSibling { - f(c) - } - } - f(doc) - -The relevant specifications include: -http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html and -http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html -*/ -package html - -// The tokenization algorithm implemented by this package is not a line-by-line -// transliteration of the relatively verbose state-machine in the WHATWG -// specification. A more direct approach is used instead, where the program -// counter implies the state, such as whether it is tokenizing a tag or a text -// node. Specification compliance is verified by checking expected and actual -// outputs over a test suite rather than aiming for algorithmic fidelity. - -// TODO(nigeltao): Does a DOM API belong in this package or a separate one? -// TODO(nigeltao): How does parsing interact with a JavaScript engine? diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/doctype.go gcc-4.8.1/libgo/go/exp/html/doctype.go --- gcc-4.8.1.orig/libgo/go/exp/html/doctype.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/html/doctype.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,156 +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 html - -import ( - "strings" -) - -// parseDoctype parses the data from a DoctypeToken into a name, -// public identifier, and system identifier. It returns a Node whose Type -// is DoctypeNode, whose Data is the name, and which has attributes -// named "system" and "public" for the two identifiers if they were present. -// quirks is whether the document should be parsed in "quirks mode". -func parseDoctype(s string) (n *Node, quirks bool) { - n = &Node{Type: DoctypeNode} - - // Find the name. - space := strings.IndexAny(s, whitespace) - if space == -1 { - space = len(s) - } - n.Data = s[:space] - // The comparison to "html" is case-sensitive. - if n.Data != "html" { - quirks = true - } - n.Data = strings.ToLower(n.Data) - s = strings.TrimLeft(s[space:], whitespace) - - if len(s) < 6 { - // It can't start with "PUBLIC" or "SYSTEM". - // Ignore the rest of the string. - return n, quirks || s != "" - } - - key := strings.ToLower(s[:6]) - s = s[6:] - for key == "public" || key == "system" { - s = strings.TrimLeft(s, whitespace) - if s == "" { - break - } - quote := s[0] - if quote != '"' && quote != '\'' { - break - } - s = s[1:] - q := strings.IndexRune(s, rune(quote)) - var id string - if q == -1 { - id = s - s = "" - } else { - id = s[:q] - s = s[q+1:] - } - n.Attr = append(n.Attr, Attribute{Key: key, Val: id}) - if key == "public" { - key = "system" - } else { - key = "" - } - } - - if key != "" || s != "" { - quirks = true - } else if len(n.Attr) > 0 { - if n.Attr[0].Key == "public" { - public := strings.ToLower(n.Attr[0].Val) - switch public { - case "-//w3o//dtd w3 html strict 3.0//en//", "-/w3d/dtd html 4.0 transitional/en", "html": - quirks = true - default: - for _, q := range quirkyIDs { - if strings.HasPrefix(public, q) { - quirks = true - break - } - } - } - // The following two public IDs only cause quirks mode if there is no system ID. - if len(n.Attr) == 1 && (strings.HasPrefix(public, "-//w3c//dtd html 4.01 frameset//") || - strings.HasPrefix(public, "-//w3c//dtd html 4.01 transitional//")) { - quirks = true - } - } - if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" && - strings.ToLower(lastAttr.Val) == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" { - quirks = true - } - } - - return n, quirks -} - -// quirkyIDs is a list of public doctype identifiers that cause a document -// to be interpreted in quirks mode. The identifiers should be in lower case. -var quirkyIDs = []string{ - "+//silmaril//dtd html pro v0r11 19970101//", - "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", - "-//as//dtd html 3.0 aswedit + extensions//", - "-//ietf//dtd html 2.0 level 1//", - "-//ietf//dtd html 2.0 level 2//", - "-//ietf//dtd html 2.0 strict level 1//", - "-//ietf//dtd html 2.0 strict level 2//", - "-//ietf//dtd html 2.0 strict//", - "-//ietf//dtd html 2.0//", - "-//ietf//dtd html 2.1e//", - "-//ietf//dtd html 3.0//", - "-//ietf//dtd html 3.2 final//", - "-//ietf//dtd html 3.2//", - "-//ietf//dtd html 3//", - "-//ietf//dtd html level 0//", - "-//ietf//dtd html level 1//", - "-//ietf//dtd html level 2//", - "-//ietf//dtd html level 3//", - "-//ietf//dtd html strict level 0//", - "-//ietf//dtd html strict level 1//", - "-//ietf//dtd html strict level 2//", - "-//ietf//dtd html strict level 3//", - "-//ietf//dtd html strict//", - "-//ietf//dtd html//", - "-//metrius//dtd metrius presentational//", - "-//microsoft//dtd internet explorer 2.0 html strict//", - "-//microsoft//dtd internet explorer 2.0 html//", - "-//microsoft//dtd internet explorer 2.0 tables//", - "-//microsoft//dtd internet explorer 3.0 html strict//", - "-//microsoft//dtd internet explorer 3.0 html//", - "-//microsoft//dtd internet explorer 3.0 tables//", - "-//netscape comm. corp.//dtd html//", - "-//netscape comm. corp.//dtd strict html//", - "-//o'reilly and associates//dtd html 2.0//", - "-//o'reilly and associates//dtd html extended 1.0//", - "-//o'reilly and associates//dtd html extended relaxed 1.0//", - "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", - "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", - "-//spyglass//dtd html 2.0 extended//", - "-//sq//dtd html 2.0 hotmetal + extensions//", - "-//sun microsystems corp.//dtd hotjava html//", - "-//sun microsystems corp.//dtd hotjava strict html//", - "-//w3c//dtd html 3 1995-03-24//", - "-//w3c//dtd html 3.2 draft//", - "-//w3c//dtd html 3.2 final//", - "-//w3c//dtd html 3.2//", - "-//w3c//dtd html 3.2s draft//", - "-//w3c//dtd html 4.0 frameset//", - "-//w3c//dtd html 4.0 transitional//", - "-//w3c//dtd html experimental 19960712//", - "-//w3c//dtd html experimental 970421//", - "-//w3c//dtd w3 html//", - "-//w3o//dtd w3 html 3.0//", - "-//webtechs//dtd mozilla html 2.0//", - "-//webtechs//dtd mozilla html//", -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/entity.go gcc-4.8.1/libgo/go/exp/html/entity.go --- gcc-4.8.1.orig/libgo/go/exp/html/entity.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/html/entity.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,2253 +0,0 @@ -// Copyright 2010 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 html - -// All entities that do not end with ';' are 6 or fewer bytes long. -const longestEntityWithoutSemicolon = 6 - -// entity is a map from HTML entity names to their values. The semicolon matters: -// http://www.whatwg.org/specs/web-apps/current-work/multipage/named-character-references.html -// lists both "amp" and "amp;" as two separate entries. -// -// Note that the HTML5 list is larger than the HTML4 list at -// http://www.w3.org/TR/html4/sgml/entities.html -var entity = map[string]rune{ - "AElig;": '\U000000C6', - "AMP;": '\U00000026', - "Aacute;": '\U000000C1', - "Abreve;": '\U00000102', - "Acirc;": '\U000000C2', - "Acy;": '\U00000410', - "Afr;": '\U0001D504', - "Agrave;": '\U000000C0', - "Alpha;": '\U00000391', - "Amacr;": '\U00000100', - "And;": '\U00002A53', - "Aogon;": '\U00000104', - "Aopf;": '\U0001D538', - "ApplyFunction;": '\U00002061', - "Aring;": '\U000000C5', - "Ascr;": '\U0001D49C', - "Assign;": '\U00002254', - "Atilde;": '\U000000C3', - "Auml;": '\U000000C4', - "Backslash;": '\U00002216', - "Barv;": '\U00002AE7', - "Barwed;": '\U00002306', - "Bcy;": '\U00000411', - "Because;": '\U00002235', - "Bernoullis;": '\U0000212C', - "Beta;": '\U00000392', - "Bfr;": '\U0001D505', - "Bopf;": '\U0001D539', - "Breve;": '\U000002D8', - "Bscr;": '\U0000212C', - "Bumpeq;": '\U0000224E', - "CHcy;": '\U00000427', - "COPY;": '\U000000A9', - "Cacute;": '\U00000106', - "Cap;": '\U000022D2', - "CapitalDifferentialD;": '\U00002145', - "Cayleys;": '\U0000212D', - "Ccaron;": '\U0000010C', - "Ccedil;": '\U000000C7', - "Ccirc;": '\U00000108', - "Cconint;": '\U00002230', - "Cdot;": '\U0000010A', - "Cedilla;": '\U000000B8', - "CenterDot;": '\U000000B7', - "Cfr;": '\U0000212D', - "Chi;": '\U000003A7', - "CircleDot;": '\U00002299', - "CircleMinus;": '\U00002296', - "CirclePlus;": '\U00002295', - "CircleTimes;": '\U00002297', - "ClockwiseContourIntegral;": '\U00002232', - "CloseCurlyDoubleQuote;": '\U0000201D', - "CloseCurlyQuote;": '\U00002019', - "Colon;": '\U00002237', - "Colone;": '\U00002A74', - "Congruent;": '\U00002261', - "Conint;": '\U0000222F', - "ContourIntegral;": '\U0000222E', - "Copf;": '\U00002102', - "Coproduct;": '\U00002210', - "CounterClockwiseContourIntegral;": '\U00002233', - "Cross;": '\U00002A2F', - "Cscr;": '\U0001D49E', - "Cup;": '\U000022D3', - "CupCap;": '\U0000224D', - "DD;": '\U00002145', - "DDotrahd;": '\U00002911', - "DJcy;": '\U00000402', - "DScy;": '\U00000405', - "DZcy;": '\U0000040F', - "Dagger;": '\U00002021', - "Darr;": '\U000021A1', - "Dashv;": '\U00002AE4', - "Dcaron;": '\U0000010E', - "Dcy;": '\U00000414', - "Del;": '\U00002207', - "Delta;": '\U00000394', - "Dfr;": '\U0001D507', - "DiacriticalAcute;": '\U000000B4', - "DiacriticalDot;": '\U000002D9', - "DiacriticalDoubleAcute;": '\U000002DD', - "DiacriticalGrave;": '\U00000060', - "DiacriticalTilde;": '\U000002DC', - "Diamond;": '\U000022C4', - "DifferentialD;": '\U00002146', - "Dopf;": '\U0001D53B', - "Dot;": '\U000000A8', - "DotDot;": '\U000020DC', - "DotEqual;": '\U00002250', - "DoubleContourIntegral;": '\U0000222F', - "DoubleDot;": '\U000000A8', - "DoubleDownArrow;": '\U000021D3', - "DoubleLeftArrow;": '\U000021D0', - "DoubleLeftRightArrow;": '\U000021D4', - "DoubleLeftTee;": '\U00002AE4', - "DoubleLongLeftArrow;": '\U000027F8', - "DoubleLongLeftRightArrow;": '\U000027FA', - "DoubleLongRightArrow;": '\U000027F9', - "DoubleRightArrow;": '\U000021D2', - "DoubleRightTee;": '\U000022A8', - "DoubleUpArrow;": '\U000021D1', - "DoubleUpDownArrow;": '\U000021D5', - "DoubleVerticalBar;": '\U00002225', - "DownArrow;": '\U00002193', - "DownArrowBar;": '\U00002913', - "DownArrowUpArrow;": '\U000021F5', - "DownBreve;": '\U00000311', - "DownLeftRightVector;": '\U00002950', - "DownLeftTeeVector;": '\U0000295E', - "DownLeftVector;": '\U000021BD', - "DownLeftVectorBar;": '\U00002956', - "DownRightTeeVector;": '\U0000295F', - "DownRightVector;": '\U000021C1', - "DownRightVectorBar;": '\U00002957', - "DownTee;": '\U000022A4', - "DownTeeArrow;": '\U000021A7', - "Downarrow;": '\U000021D3', - "Dscr;": '\U0001D49F', - "Dstrok;": '\U00000110', - "ENG;": '\U0000014A', - "ETH;": '\U000000D0', - "Eacute;": '\U000000C9', - "Ecaron;": '\U0000011A', - "Ecirc;": '\U000000CA', - "Ecy;": '\U0000042D', - "Edot;": '\U00000116', - "Efr;": '\U0001D508', - "Egrave;": '\U000000C8', - "Element;": '\U00002208', - "Emacr;": '\U00000112', - "EmptySmallSquare;": '\U000025FB', - "EmptyVerySmallSquare;": '\U000025AB', - "Eogon;": '\U00000118', - "Eopf;": '\U0001D53C', - "Epsilon;": '\U00000395', - "Equal;": '\U00002A75', - "EqualTilde;": '\U00002242', - "Equilibrium;": '\U000021CC', - "Escr;": '\U00002130', - "Esim;": '\U00002A73', - "Eta;": '\U00000397', - "Euml;": '\U000000CB', - "Exists;": '\U00002203', - "ExponentialE;": '\U00002147', - "Fcy;": '\U00000424', - "Ffr;": '\U0001D509', - "FilledSmallSquare;": '\U000025FC', - "FilledVerySmallSquare;": '\U000025AA', - "Fopf;": '\U0001D53D', - "ForAll;": '\U00002200', - "Fouriertrf;": '\U00002131', - "Fscr;": '\U00002131', - "GJcy;": '\U00000403', - "GT;": '\U0000003E', - "Gamma;": '\U00000393', - "Gammad;": '\U000003DC', - "Gbreve;": '\U0000011E', - "Gcedil;": '\U00000122', - "Gcirc;": '\U0000011C', - "Gcy;": '\U00000413', - "Gdot;": '\U00000120', - "Gfr;": '\U0001D50A', - "Gg;": '\U000022D9', - "Gopf;": '\U0001D53E', - "GreaterEqual;": '\U00002265', - "GreaterEqualLess;": '\U000022DB', - "GreaterFullEqual;": '\U00002267', - "GreaterGreater;": '\U00002AA2', - "GreaterLess;": '\U00002277', - "GreaterSlantEqual;": '\U00002A7E', - "GreaterTilde;": '\U00002273', - "Gscr;": '\U0001D4A2', - "Gt;": '\U0000226B', - "HARDcy;": '\U0000042A', - "Hacek;": '\U000002C7', - "Hat;": '\U0000005E', - "Hcirc;": '\U00000124', - "Hfr;": '\U0000210C', - "HilbertSpace;": '\U0000210B', - "Hopf;": '\U0000210D', - "HorizontalLine;": '\U00002500', - "Hscr;": '\U0000210B', - "Hstrok;": '\U00000126', - "HumpDownHump;": '\U0000224E', - "HumpEqual;": '\U0000224F', - "IEcy;": '\U00000415', - "IJlig;": '\U00000132', - "IOcy;": '\U00000401', - "Iacute;": '\U000000CD', - "Icirc;": '\U000000CE', - "Icy;": '\U00000418', - "Idot;": '\U00000130', - "Ifr;": '\U00002111', - "Igrave;": '\U000000CC', - "Im;": '\U00002111', - "Imacr;": '\U0000012A', - "ImaginaryI;": '\U00002148', - "Implies;": '\U000021D2', - "Int;": '\U0000222C', - "Integral;": '\U0000222B', - "Intersection;": '\U000022C2', - "InvisibleComma;": '\U00002063', - "InvisibleTimes;": '\U00002062', - "Iogon;": '\U0000012E', - "Iopf;": '\U0001D540', - "Iota;": '\U00000399', - "Iscr;": '\U00002110', - "Itilde;": '\U00000128', - "Iukcy;": '\U00000406', - "Iuml;": '\U000000CF', - "Jcirc;": '\U00000134', - "Jcy;": '\U00000419', - "Jfr;": '\U0001D50D', - "Jopf;": '\U0001D541', - "Jscr;": '\U0001D4A5', - "Jsercy;": '\U00000408', - "Jukcy;": '\U00000404', - "KHcy;": '\U00000425', - "KJcy;": '\U0000040C', - "Kappa;": '\U0000039A', - "Kcedil;": '\U00000136', - "Kcy;": '\U0000041A', - "Kfr;": '\U0001D50E', - "Kopf;": '\U0001D542', - "Kscr;": '\U0001D4A6', - "LJcy;": '\U00000409', - "LT;": '\U0000003C', - "Lacute;": '\U00000139', - "Lambda;": '\U0000039B', - "Lang;": '\U000027EA', - "Laplacetrf;": '\U00002112', - "Larr;": '\U0000219E', - "Lcaron;": '\U0000013D', - "Lcedil;": '\U0000013B', - "Lcy;": '\U0000041B', - "LeftAngleBracket;": '\U000027E8', - "LeftArrow;": '\U00002190', - "LeftArrowBar;": '\U000021E4', - "LeftArrowRightArrow;": '\U000021C6', - "LeftCeiling;": '\U00002308', - "LeftDoubleBracket;": '\U000027E6', - "LeftDownTeeVector;": '\U00002961', - "LeftDownVector;": '\U000021C3', - "LeftDownVectorBar;": '\U00002959', - "LeftFloor;": '\U0000230A', - "LeftRightArrow;": '\U00002194', - "LeftRightVector;": '\U0000294E', - "LeftTee;": '\U000022A3', - "LeftTeeArrow;": '\U000021A4', - "LeftTeeVector;": '\U0000295A', - "LeftTriangle;": '\U000022B2', - "LeftTriangleBar;": '\U000029CF', - "LeftTriangleEqual;": '\U000022B4', - "LeftUpDownVector;": '\U00002951', - "LeftUpTeeVector;": '\U00002960', - "LeftUpVector;": '\U000021BF', - "LeftUpVectorBar;": '\U00002958', - "LeftVector;": '\U000021BC', - "LeftVectorBar;": '\U00002952', - "Leftarrow;": '\U000021D0', - "Leftrightarrow;": '\U000021D4', - "LessEqualGreater;": '\U000022DA', - "LessFullEqual;": '\U00002266', - "LessGreater;": '\U00002276', - "LessLess;": '\U00002AA1', - "LessSlantEqual;": '\U00002A7D', - "LessTilde;": '\U00002272', - "Lfr;": '\U0001D50F', - "Ll;": '\U000022D8', - "Lleftarrow;": '\U000021DA', - "Lmidot;": '\U0000013F', - "LongLeftArrow;": '\U000027F5', - "LongLeftRightArrow;": '\U000027F7', - "LongRightArrow;": '\U000027F6', - "Longleftarrow;": '\U000027F8', - "Longleftrightarrow;": '\U000027FA', - "Longrightarrow;": '\U000027F9', - "Lopf;": '\U0001D543', - "LowerLeftArrow;": '\U00002199', - "LowerRightArrow;": '\U00002198', - "Lscr;": '\U00002112', - "Lsh;": '\U000021B0', - "Lstrok;": '\U00000141', - "Lt;": '\U0000226A', - "Map;": '\U00002905', - "Mcy;": '\U0000041C', - "MediumSpace;": '\U0000205F', - "Mellintrf;": '\U00002133', - "Mfr;": '\U0001D510', - "MinusPlus;": '\U00002213', - "Mopf;": '\U0001D544', - "Mscr;": '\U00002133', - "Mu;": '\U0000039C', - "NJcy;": '\U0000040A', - "Nacute;": '\U00000143', - "Ncaron;": '\U00000147', - "Ncedil;": '\U00000145', - "Ncy;": '\U0000041D', - "NegativeMediumSpace;": '\U0000200B', - "NegativeThickSpace;": '\U0000200B', - "NegativeThinSpace;": '\U0000200B', - "NegativeVeryThinSpace;": '\U0000200B', - "NestedGreaterGreater;": '\U0000226B', - "NestedLessLess;": '\U0000226A', - "NewLine;": '\U0000000A', - "Nfr;": '\U0001D511', - "NoBreak;": '\U00002060', - "NonBreakingSpace;": '\U000000A0', - "Nopf;": '\U00002115', - "Not;": '\U00002AEC', - "NotCongruent;": '\U00002262', - "NotCupCap;": '\U0000226D', - "NotDoubleVerticalBar;": '\U00002226', - "NotElement;": '\U00002209', - "NotEqual;": '\U00002260', - "NotExists;": '\U00002204', - "NotGreater;": '\U0000226F', - "NotGreaterEqual;": '\U00002271', - "NotGreaterLess;": '\U00002279', - "NotGreaterTilde;": '\U00002275', - "NotLeftTriangle;": '\U000022EA', - "NotLeftTriangleEqual;": '\U000022EC', - "NotLess;": '\U0000226E', - "NotLessEqual;": '\U00002270', - "NotLessGreater;": '\U00002278', - "NotLessTilde;": '\U00002274', - "NotPrecedes;": '\U00002280', - "NotPrecedesSlantEqual;": '\U000022E0', - "NotReverseElement;": '\U0000220C', - "NotRightTriangle;": '\U000022EB', - "NotRightTriangleEqual;": '\U000022ED', - "NotSquareSubsetEqual;": '\U000022E2', - "NotSquareSupersetEqual;": '\U000022E3', - "NotSubsetEqual;": '\U00002288', - "NotSucceeds;": '\U00002281', - "NotSucceedsSlantEqual;": '\U000022E1', - "NotSupersetEqual;": '\U00002289', - "NotTilde;": '\U00002241', - "NotTildeEqual;": '\U00002244', - "NotTildeFullEqual;": '\U00002247', - "NotTildeTilde;": '\U00002249', - "NotVerticalBar;": '\U00002224', - "Nscr;": '\U0001D4A9', - "Ntilde;": '\U000000D1', - "Nu;": '\U0000039D', - "OElig;": '\U00000152', - "Oacute;": '\U000000D3', - "Ocirc;": '\U000000D4', - "Ocy;": '\U0000041E', - "Odblac;": '\U00000150', - "Ofr;": '\U0001D512', - "Ograve;": '\U000000D2', - "Omacr;": '\U0000014C', - "Omega;": '\U000003A9', - "Omicron;": '\U0000039F', - "Oopf;": '\U0001D546', - "OpenCurlyDoubleQuote;": '\U0000201C', - "OpenCurlyQuote;": '\U00002018', - "Or;": '\U00002A54', - "Oscr;": '\U0001D4AA', - "Oslash;": '\U000000D8', - "Otilde;": '\U000000D5', - "Otimes;": '\U00002A37', - "Ouml;": '\U000000D6', - "OverBar;": '\U0000203E', - "OverBrace;": '\U000023DE', - "OverBracket;": '\U000023B4', - "OverParenthesis;": '\U000023DC', - "PartialD;": '\U00002202', - "Pcy;": '\U0000041F', - "Pfr;": '\U0001D513', - "Phi;": '\U000003A6', - "Pi;": '\U000003A0', - "PlusMinus;": '\U000000B1', - "Poincareplane;": '\U0000210C', - "Popf;": '\U00002119', - "Pr;": '\U00002ABB', - "Precedes;": '\U0000227A', - "PrecedesEqual;": '\U00002AAF', - "PrecedesSlantEqual;": '\U0000227C', - "PrecedesTilde;": '\U0000227E', - "Prime;": '\U00002033', - "Product;": '\U0000220F', - "Proportion;": '\U00002237', - "Proportional;": '\U0000221D', - "Pscr;": '\U0001D4AB', - "Psi;": '\U000003A8', - "QUOT;": '\U00000022', - "Qfr;": '\U0001D514', - "Qopf;": '\U0000211A', - "Qscr;": '\U0001D4AC', - "RBarr;": '\U00002910', - "REG;": '\U000000AE', - "Racute;": '\U00000154', - "Rang;": '\U000027EB', - "Rarr;": '\U000021A0', - "Rarrtl;": '\U00002916', - "Rcaron;": '\U00000158', - "Rcedil;": '\U00000156', - "Rcy;": '\U00000420', - "Re;": '\U0000211C', - "ReverseElement;": '\U0000220B', - "ReverseEquilibrium;": '\U000021CB', - "ReverseUpEquilibrium;": '\U0000296F', - "Rfr;": '\U0000211C', - "Rho;": '\U000003A1', - "RightAngleBracket;": '\U000027E9', - "RightArrow;": '\U00002192', - "RightArrowBar;": '\U000021E5', - "RightArrowLeftArrow;": '\U000021C4', - "RightCeiling;": '\U00002309', - "RightDoubleBracket;": '\U000027E7', - "RightDownTeeVector;": '\U0000295D', - "RightDownVector;": '\U000021C2', - "RightDownVectorBar;": '\U00002955', - "RightFloor;": '\U0000230B', - "RightTee;": '\U000022A2', - "RightTeeArrow;": '\U000021A6', - "RightTeeVector;": '\U0000295B', - "RightTriangle;": '\U000022B3', - "RightTriangleBar;": '\U000029D0', - "RightTriangleEqual;": '\U000022B5', - "RightUpDownVector;": '\U0000294F', - "RightUpTeeVector;": '\U0000295C', - "RightUpVector;": '\U000021BE', - "RightUpVectorBar;": '\U00002954', - "RightVector;": '\U000021C0', - "RightVectorBar;": '\U00002953', - "Rightarrow;": '\U000021D2', - "Ropf;": '\U0000211D', - "RoundImplies;": '\U00002970', - "Rrightarrow;": '\U000021DB', - "Rscr;": '\U0000211B', - "Rsh;": '\U000021B1', - "RuleDelayed;": '\U000029F4', - "SHCHcy;": '\U00000429', - "SHcy;": '\U00000428', - "SOFTcy;": '\U0000042C', - "Sacute;": '\U0000015A', - "Sc;": '\U00002ABC', - "Scaron;": '\U00000160', - "Scedil;": '\U0000015E', - "Scirc;": '\U0000015C', - "Scy;": '\U00000421', - "Sfr;": '\U0001D516', - "ShortDownArrow;": '\U00002193', - "ShortLeftArrow;": '\U00002190', - "ShortRightArrow;": '\U00002192', - "ShortUpArrow;": '\U00002191', - "Sigma;": '\U000003A3', - "SmallCircle;": '\U00002218', - "Sopf;": '\U0001D54A', - "Sqrt;": '\U0000221A', - "Square;": '\U000025A1', - "SquareIntersection;": '\U00002293', - "SquareSubset;": '\U0000228F', - "SquareSubsetEqual;": '\U00002291', - "SquareSuperset;": '\U00002290', - "SquareSupersetEqual;": '\U00002292', - "SquareUnion;": '\U00002294', - "Sscr;": '\U0001D4AE', - "Star;": '\U000022C6', - "Sub;": '\U000022D0', - "Subset;": '\U000022D0', - "SubsetEqual;": '\U00002286', - "Succeeds;": '\U0000227B', - "SucceedsEqual;": '\U00002AB0', - "SucceedsSlantEqual;": '\U0000227D', - "SucceedsTilde;": '\U0000227F', - "SuchThat;": '\U0000220B', - "Sum;": '\U00002211', - "Sup;": '\U000022D1', - "Superset;": '\U00002283', - "SupersetEqual;": '\U00002287', - "Supset;": '\U000022D1', - "THORN;": '\U000000DE', - "TRADE;": '\U00002122', - "TSHcy;": '\U0000040B', - "TScy;": '\U00000426', - "Tab;": '\U00000009', - "Tau;": '\U000003A4', - "Tcaron;": '\U00000164', - "Tcedil;": '\U00000162', - "Tcy;": '\U00000422', - "Tfr;": '\U0001D517', - "Therefore;": '\U00002234', - "Theta;": '\U00000398', - "ThinSpace;": '\U00002009', - "Tilde;": '\U0000223C', - "TildeEqual;": '\U00002243', - "TildeFullEqual;": '\U00002245', - "TildeTilde;": '\U00002248', - "Topf;": '\U0001D54B', - "TripleDot;": '\U000020DB', - "Tscr;": '\U0001D4AF', - "Tstrok;": '\U00000166', - "Uacute;": '\U000000DA', - "Uarr;": '\U0000219F', - "Uarrocir;": '\U00002949', - "Ubrcy;": '\U0000040E', - "Ubreve;": '\U0000016C', - "Ucirc;": '\U000000DB', - "Ucy;": '\U00000423', - "Udblac;": '\U00000170', - "Ufr;": '\U0001D518', - "Ugrave;": '\U000000D9', - "Umacr;": '\U0000016A', - "UnderBar;": '\U0000005F', - "UnderBrace;": '\U000023DF', - "UnderBracket;": '\U000023B5', - "UnderParenthesis;": '\U000023DD', - "Union;": '\U000022C3', - "UnionPlus;": '\U0000228E', - "Uogon;": '\U00000172', - "Uopf;": '\U0001D54C', - "UpArrow;": '\U00002191', - "UpArrowBar;": '\U00002912', - "UpArrowDownArrow;": '\U000021C5', - "UpDownArrow;": '\U00002195', - "UpEquilibrium;": '\U0000296E', - "UpTee;": '\U000022A5', - "UpTeeArrow;": '\U000021A5', - "Uparrow;": '\U000021D1', - "Updownarrow;": '\U000021D5', - "UpperLeftArrow;": '\U00002196', - "UpperRightArrow;": '\U00002197', - "Upsi;": '\U000003D2', - "Upsilon;": '\U000003A5', - "Uring;": '\U0000016E', - "Uscr;": '\U0001D4B0', - "Utilde;": '\U00000168', - "Uuml;": '\U000000DC', - "VDash;": '\U000022AB', - "Vbar;": '\U00002AEB', - "Vcy;": '\U00000412', - "Vdash;": '\U000022A9', - "Vdashl;": '\U00002AE6', - "Vee;": '\U000022C1', - "Verbar;": '\U00002016', - "Vert;": '\U00002016', - "VerticalBar;": '\U00002223', - "VerticalLine;": '\U0000007C', - "VerticalSeparator;": '\U00002758', - "VerticalTilde;": '\U00002240', - "VeryThinSpace;": '\U0000200A', - "Vfr;": '\U0001D519', - "Vopf;": '\U0001D54D', - "Vscr;": '\U0001D4B1', - "Vvdash;": '\U000022AA', - "Wcirc;": '\U00000174', - "Wedge;": '\U000022C0', - "Wfr;": '\U0001D51A', - "Wopf;": '\U0001D54E', - "Wscr;": '\U0001D4B2', - "Xfr;": '\U0001D51B', - "Xi;": '\U0000039E', - "Xopf;": '\U0001D54F', - "Xscr;": '\U0001D4B3', - "YAcy;": '\U0000042F', - "YIcy;": '\U00000407', - "YUcy;": '\U0000042E', - "Yacute;": '\U000000DD', - "Ycirc;": '\U00000176', - "Ycy;": '\U0000042B', - "Yfr;": '\U0001D51C', - "Yopf;": '\U0001D550', - "Yscr;": '\U0001D4B4', - "Yuml;": '\U00000178', - "ZHcy;": '\U00000416', - "Zacute;": '\U00000179', - "Zcaron;": '\U0000017D', - "Zcy;": '\U00000417', - "Zdot;": '\U0000017B', - "ZeroWidthSpace;": '\U0000200B', - "Zeta;": '\U00000396', - "Zfr;": '\U00002128', - "Zopf;": '\U00002124', - "Zscr;": '\U0001D4B5', - "aacute;": '\U000000E1', - "abreve;": '\U00000103', - "ac;": '\U0000223E', - "acd;": '\U0000223F', - "acirc;": '\U000000E2', - "acute;": '\U000000B4', - "acy;": '\U00000430', - "aelig;": '\U000000E6', - "af;": '\U00002061', - "afr;": '\U0001D51E', - "agrave;": '\U000000E0', - "alefsym;": '\U00002135', - "aleph;": '\U00002135', - "alpha;": '\U000003B1', - "amacr;": '\U00000101', - "amalg;": '\U00002A3F', - "amp;": '\U00000026', - "and;": '\U00002227', - "andand;": '\U00002A55', - "andd;": '\U00002A5C', - "andslope;": '\U00002A58', - "andv;": '\U00002A5A', - "ang;": '\U00002220', - "ange;": '\U000029A4', - "angle;": '\U00002220', - "angmsd;": '\U00002221', - "angmsdaa;": '\U000029A8', - "angmsdab;": '\U000029A9', - "angmsdac;": '\U000029AA', - "angmsdad;": '\U000029AB', - "angmsdae;": '\U000029AC', - "angmsdaf;": '\U000029AD', - "angmsdag;": '\U000029AE', - "angmsdah;": '\U000029AF', - "angrt;": '\U0000221F', - "angrtvb;": '\U000022BE', - "angrtvbd;": '\U0000299D', - "angsph;": '\U00002222', - "angst;": '\U000000C5', - "angzarr;": '\U0000237C', - "aogon;": '\U00000105', - "aopf;": '\U0001D552', - "ap;": '\U00002248', - "apE;": '\U00002A70', - "apacir;": '\U00002A6F', - "ape;": '\U0000224A', - "apid;": '\U0000224B', - "apos;": '\U00000027', - "approx;": '\U00002248', - "approxeq;": '\U0000224A', - "aring;": '\U000000E5', - "ascr;": '\U0001D4B6', - "ast;": '\U0000002A', - "asymp;": '\U00002248', - "asympeq;": '\U0000224D', - "atilde;": '\U000000E3', - "auml;": '\U000000E4', - "awconint;": '\U00002233', - "awint;": '\U00002A11', - "bNot;": '\U00002AED', - "backcong;": '\U0000224C', - "backepsilon;": '\U000003F6', - "backprime;": '\U00002035', - "backsim;": '\U0000223D', - "backsimeq;": '\U000022CD', - "barvee;": '\U000022BD', - "barwed;": '\U00002305', - "barwedge;": '\U00002305', - "bbrk;": '\U000023B5', - "bbrktbrk;": '\U000023B6', - "bcong;": '\U0000224C', - "bcy;": '\U00000431', - "bdquo;": '\U0000201E', - "becaus;": '\U00002235', - "because;": '\U00002235', - "bemptyv;": '\U000029B0', - "bepsi;": '\U000003F6', - "bernou;": '\U0000212C', - "beta;": '\U000003B2', - "beth;": '\U00002136', - "between;": '\U0000226C', - "bfr;": '\U0001D51F', - "bigcap;": '\U000022C2', - "bigcirc;": '\U000025EF', - "bigcup;": '\U000022C3', - "bigodot;": '\U00002A00', - "bigoplus;": '\U00002A01', - "bigotimes;": '\U00002A02', - "bigsqcup;": '\U00002A06', - "bigstar;": '\U00002605', - "bigtriangledown;": '\U000025BD', - "bigtriangleup;": '\U000025B3', - "biguplus;": '\U00002A04', - "bigvee;": '\U000022C1', - "bigwedge;": '\U000022C0', - "bkarow;": '\U0000290D', - "blacklozenge;": '\U000029EB', - "blacksquare;": '\U000025AA', - "blacktriangle;": '\U000025B4', - "blacktriangledown;": '\U000025BE', - "blacktriangleleft;": '\U000025C2', - "blacktriangleright;": '\U000025B8', - "blank;": '\U00002423', - "blk12;": '\U00002592', - "blk14;": '\U00002591', - "blk34;": '\U00002593', - "block;": '\U00002588', - "bnot;": '\U00002310', - "bopf;": '\U0001D553', - "bot;": '\U000022A5', - "bottom;": '\U000022A5', - "bowtie;": '\U000022C8', - "boxDL;": '\U00002557', - "boxDR;": '\U00002554', - "boxDl;": '\U00002556', - "boxDr;": '\U00002553', - "boxH;": '\U00002550', - "boxHD;": '\U00002566', - "boxHU;": '\U00002569', - "boxHd;": '\U00002564', - "boxHu;": '\U00002567', - "boxUL;": '\U0000255D', - "boxUR;": '\U0000255A', - "boxUl;": '\U0000255C', - "boxUr;": '\U00002559', - "boxV;": '\U00002551', - "boxVH;": '\U0000256C', - "boxVL;": '\U00002563', - "boxVR;": '\U00002560', - "boxVh;": '\U0000256B', - "boxVl;": '\U00002562', - "boxVr;": '\U0000255F', - "boxbox;": '\U000029C9', - "boxdL;": '\U00002555', - "boxdR;": '\U00002552', - "boxdl;": '\U00002510', - "boxdr;": '\U0000250C', - "boxh;": '\U00002500', - "boxhD;": '\U00002565', - "boxhU;": '\U00002568', - "boxhd;": '\U0000252C', - "boxhu;": '\U00002534', - "boxminus;": '\U0000229F', - "boxplus;": '\U0000229E', - "boxtimes;": '\U000022A0', - "boxuL;": '\U0000255B', - "boxuR;": '\U00002558', - "boxul;": '\U00002518', - "boxur;": '\U00002514', - "boxv;": '\U00002502', - "boxvH;": '\U0000256A', - "boxvL;": '\U00002561', - "boxvR;": '\U0000255E', - "boxvh;": '\U0000253C', - "boxvl;": '\U00002524', - "boxvr;": '\U0000251C', - "bprime;": '\U00002035', - "breve;": '\U000002D8', - "brvbar;": '\U000000A6', - "bscr;": '\U0001D4B7', - "bsemi;": '\U0000204F', - "bsim;": '\U0000223D', - "bsime;": '\U000022CD', - "bsol;": '\U0000005C', - "bsolb;": '\U000029C5', - "bsolhsub;": '\U000027C8', - "bull;": '\U00002022', - "bullet;": '\U00002022', - "bump;": '\U0000224E', - "bumpE;": '\U00002AAE', - "bumpe;": '\U0000224F', - "bumpeq;": '\U0000224F', - "cacute;": '\U00000107', - "cap;": '\U00002229', - "capand;": '\U00002A44', - "capbrcup;": '\U00002A49', - "capcap;": '\U00002A4B', - "capcup;": '\U00002A47', - "capdot;": '\U00002A40', - "caret;": '\U00002041', - "caron;": '\U000002C7', - "ccaps;": '\U00002A4D', - "ccaron;": '\U0000010D', - "ccedil;": '\U000000E7', - "ccirc;": '\U00000109', - "ccups;": '\U00002A4C', - "ccupssm;": '\U00002A50', - "cdot;": '\U0000010B', - "cedil;": '\U000000B8', - "cemptyv;": '\U000029B2', - "cent;": '\U000000A2', - "centerdot;": '\U000000B7', - "cfr;": '\U0001D520', - "chcy;": '\U00000447', - "check;": '\U00002713', - "checkmark;": '\U00002713', - "chi;": '\U000003C7', - "cir;": '\U000025CB', - "cirE;": '\U000029C3', - "circ;": '\U000002C6', - "circeq;": '\U00002257', - "circlearrowleft;": '\U000021BA', - "circlearrowright;": '\U000021BB', - "circledR;": '\U000000AE', - "circledS;": '\U000024C8', - "circledast;": '\U0000229B', - "circledcirc;": '\U0000229A', - "circleddash;": '\U0000229D', - "cire;": '\U00002257', - "cirfnint;": '\U00002A10', - "cirmid;": '\U00002AEF', - "cirscir;": '\U000029C2', - "clubs;": '\U00002663', - "clubsuit;": '\U00002663', - "colon;": '\U0000003A', - "colone;": '\U00002254', - "coloneq;": '\U00002254', - "comma;": '\U0000002C', - "commat;": '\U00000040', - "comp;": '\U00002201', - "compfn;": '\U00002218', - "complement;": '\U00002201', - "complexes;": '\U00002102', - "cong;": '\U00002245', - "congdot;": '\U00002A6D', - "conint;": '\U0000222E', - "copf;": '\U0001D554', - "coprod;": '\U00002210', - "copy;": '\U000000A9', - "copysr;": '\U00002117', - "crarr;": '\U000021B5', - "cross;": '\U00002717', - "cscr;": '\U0001D4B8', - "csub;": '\U00002ACF', - "csube;": '\U00002AD1', - "csup;": '\U00002AD0', - "csupe;": '\U00002AD2', - "ctdot;": '\U000022EF', - "cudarrl;": '\U00002938', - "cudarrr;": '\U00002935', - "cuepr;": '\U000022DE', - "cuesc;": '\U000022DF', - "cularr;": '\U000021B6', - "cularrp;": '\U0000293D', - "cup;": '\U0000222A', - "cupbrcap;": '\U00002A48', - "cupcap;": '\U00002A46', - "cupcup;": '\U00002A4A', - "cupdot;": '\U0000228D', - "cupor;": '\U00002A45', - "curarr;": '\U000021B7', - "curarrm;": '\U0000293C', - "curlyeqprec;": '\U000022DE', - "curlyeqsucc;": '\U000022DF', - "curlyvee;": '\U000022CE', - "curlywedge;": '\U000022CF', - "curren;": '\U000000A4', - "curvearrowleft;": '\U000021B6', - "curvearrowright;": '\U000021B7', - "cuvee;": '\U000022CE', - "cuwed;": '\U000022CF', - "cwconint;": '\U00002232', - "cwint;": '\U00002231', - "cylcty;": '\U0000232D', - "dArr;": '\U000021D3', - "dHar;": '\U00002965', - "dagger;": '\U00002020', - "daleth;": '\U00002138', - "darr;": '\U00002193', - "dash;": '\U00002010', - "dashv;": '\U000022A3', - "dbkarow;": '\U0000290F', - "dblac;": '\U000002DD', - "dcaron;": '\U0000010F', - "dcy;": '\U00000434', - "dd;": '\U00002146', - "ddagger;": '\U00002021', - "ddarr;": '\U000021CA', - "ddotseq;": '\U00002A77', - "deg;": '\U000000B0', - "delta;": '\U000003B4', - "demptyv;": '\U000029B1', - "dfisht;": '\U0000297F', - "dfr;": '\U0001D521', - "dharl;": '\U000021C3', - "dharr;": '\U000021C2', - "diam;": '\U000022C4', - "diamond;": '\U000022C4', - "diamondsuit;": '\U00002666', - "diams;": '\U00002666', - "die;": '\U000000A8', - "digamma;": '\U000003DD', - "disin;": '\U000022F2', - "div;": '\U000000F7', - "divide;": '\U000000F7', - "divideontimes;": '\U000022C7', - "divonx;": '\U000022C7', - "djcy;": '\U00000452', - "dlcorn;": '\U0000231E', - "dlcrop;": '\U0000230D', - "dollar;": '\U00000024', - "dopf;": '\U0001D555', - "dot;": '\U000002D9', - "doteq;": '\U00002250', - "doteqdot;": '\U00002251', - "dotminus;": '\U00002238', - "dotplus;": '\U00002214', - "dotsquare;": '\U000022A1', - "doublebarwedge;": '\U00002306', - "downarrow;": '\U00002193', - "downdownarrows;": '\U000021CA', - "downharpoonleft;": '\U000021C3', - "downharpoonright;": '\U000021C2', - "drbkarow;": '\U00002910', - "drcorn;": '\U0000231F', - "drcrop;": '\U0000230C', - "dscr;": '\U0001D4B9', - "dscy;": '\U00000455', - "dsol;": '\U000029F6', - "dstrok;": '\U00000111', - "dtdot;": '\U000022F1', - "dtri;": '\U000025BF', - "dtrif;": '\U000025BE', - "duarr;": '\U000021F5', - "duhar;": '\U0000296F', - "dwangle;": '\U000029A6', - "dzcy;": '\U0000045F', - "dzigrarr;": '\U000027FF', - "eDDot;": '\U00002A77', - "eDot;": '\U00002251', - "eacute;": '\U000000E9', - "easter;": '\U00002A6E', - "ecaron;": '\U0000011B', - "ecir;": '\U00002256', - "ecirc;": '\U000000EA', - "ecolon;": '\U00002255', - "ecy;": '\U0000044D', - "edot;": '\U00000117', - "ee;": '\U00002147', - "efDot;": '\U00002252', - "efr;": '\U0001D522', - "eg;": '\U00002A9A', - "egrave;": '\U000000E8', - "egs;": '\U00002A96', - "egsdot;": '\U00002A98', - "el;": '\U00002A99', - "elinters;": '\U000023E7', - "ell;": '\U00002113', - "els;": '\U00002A95', - "elsdot;": '\U00002A97', - "emacr;": '\U00000113', - "empty;": '\U00002205', - "emptyset;": '\U00002205', - "emptyv;": '\U00002205', - "emsp;": '\U00002003', - "emsp13;": '\U00002004', - "emsp14;": '\U00002005', - "eng;": '\U0000014B', - "ensp;": '\U00002002', - "eogon;": '\U00000119', - "eopf;": '\U0001D556', - "epar;": '\U000022D5', - "eparsl;": '\U000029E3', - "eplus;": '\U00002A71', - "epsi;": '\U000003B5', - "epsilon;": '\U000003B5', - "epsiv;": '\U000003F5', - "eqcirc;": '\U00002256', - "eqcolon;": '\U00002255', - "eqsim;": '\U00002242', - "eqslantgtr;": '\U00002A96', - "eqslantless;": '\U00002A95', - "equals;": '\U0000003D', - "equest;": '\U0000225F', - "equiv;": '\U00002261', - "equivDD;": '\U00002A78', - "eqvparsl;": '\U000029E5', - "erDot;": '\U00002253', - "erarr;": '\U00002971', - "escr;": '\U0000212F', - "esdot;": '\U00002250', - "esim;": '\U00002242', - "eta;": '\U000003B7', - "eth;": '\U000000F0', - "euml;": '\U000000EB', - "euro;": '\U000020AC', - "excl;": '\U00000021', - "exist;": '\U00002203', - "expectation;": '\U00002130', - "exponentiale;": '\U00002147', - "fallingdotseq;": '\U00002252', - "fcy;": '\U00000444', - "female;": '\U00002640', - "ffilig;": '\U0000FB03', - "fflig;": '\U0000FB00', - "ffllig;": '\U0000FB04', - "ffr;": '\U0001D523', - "filig;": '\U0000FB01', - "flat;": '\U0000266D', - "fllig;": '\U0000FB02', - "fltns;": '\U000025B1', - "fnof;": '\U00000192', - "fopf;": '\U0001D557', - "forall;": '\U00002200', - "fork;": '\U000022D4', - "forkv;": '\U00002AD9', - "fpartint;": '\U00002A0D', - "frac12;": '\U000000BD', - "frac13;": '\U00002153', - "frac14;": '\U000000BC', - "frac15;": '\U00002155', - "frac16;": '\U00002159', - "frac18;": '\U0000215B', - "frac23;": '\U00002154', - "frac25;": '\U00002156', - "frac34;": '\U000000BE', - "frac35;": '\U00002157', - "frac38;": '\U0000215C', - "frac45;": '\U00002158', - "frac56;": '\U0000215A', - "frac58;": '\U0000215D', - "frac78;": '\U0000215E', - "frasl;": '\U00002044', - "frown;": '\U00002322', - "fscr;": '\U0001D4BB', - "gE;": '\U00002267', - "gEl;": '\U00002A8C', - "gacute;": '\U000001F5', - "gamma;": '\U000003B3', - "gammad;": '\U000003DD', - "gap;": '\U00002A86', - "gbreve;": '\U0000011F', - "gcirc;": '\U0000011D', - "gcy;": '\U00000433', - "gdot;": '\U00000121', - "ge;": '\U00002265', - "gel;": '\U000022DB', - "geq;": '\U00002265', - "geqq;": '\U00002267', - "geqslant;": '\U00002A7E', - "ges;": '\U00002A7E', - "gescc;": '\U00002AA9', - "gesdot;": '\U00002A80', - "gesdoto;": '\U00002A82', - "gesdotol;": '\U00002A84', - "gesles;": '\U00002A94', - "gfr;": '\U0001D524', - "gg;": '\U0000226B', - "ggg;": '\U000022D9', - "gimel;": '\U00002137', - "gjcy;": '\U00000453', - "gl;": '\U00002277', - "glE;": '\U00002A92', - "gla;": '\U00002AA5', - "glj;": '\U00002AA4', - "gnE;": '\U00002269', - "gnap;": '\U00002A8A', - "gnapprox;": '\U00002A8A', - "gne;": '\U00002A88', - "gneq;": '\U00002A88', - "gneqq;": '\U00002269', - "gnsim;": '\U000022E7', - "gopf;": '\U0001D558', - "grave;": '\U00000060', - "gscr;": '\U0000210A', - "gsim;": '\U00002273', - "gsime;": '\U00002A8E', - "gsiml;": '\U00002A90', - "gt;": '\U0000003E', - "gtcc;": '\U00002AA7', - "gtcir;": '\U00002A7A', - "gtdot;": '\U000022D7', - "gtlPar;": '\U00002995', - "gtquest;": '\U00002A7C', - "gtrapprox;": '\U00002A86', - "gtrarr;": '\U00002978', - "gtrdot;": '\U000022D7', - "gtreqless;": '\U000022DB', - "gtreqqless;": '\U00002A8C', - "gtrless;": '\U00002277', - "gtrsim;": '\U00002273', - "hArr;": '\U000021D4', - "hairsp;": '\U0000200A', - "half;": '\U000000BD', - "hamilt;": '\U0000210B', - "hardcy;": '\U0000044A', - "harr;": '\U00002194', - "harrcir;": '\U00002948', - "harrw;": '\U000021AD', - "hbar;": '\U0000210F', - "hcirc;": '\U00000125', - "hearts;": '\U00002665', - "heartsuit;": '\U00002665', - "hellip;": '\U00002026', - "hercon;": '\U000022B9', - "hfr;": '\U0001D525', - "hksearow;": '\U00002925', - "hkswarow;": '\U00002926', - "hoarr;": '\U000021FF', - "homtht;": '\U0000223B', - "hookleftarrow;": '\U000021A9', - "hookrightarrow;": '\U000021AA', - "hopf;": '\U0001D559', - "horbar;": '\U00002015', - "hscr;": '\U0001D4BD', - "hslash;": '\U0000210F', - "hstrok;": '\U00000127', - "hybull;": '\U00002043', - "hyphen;": '\U00002010', - "iacute;": '\U000000ED', - "ic;": '\U00002063', - "icirc;": '\U000000EE', - "icy;": '\U00000438', - "iecy;": '\U00000435', - "iexcl;": '\U000000A1', - "iff;": '\U000021D4', - "ifr;": '\U0001D526', - "igrave;": '\U000000EC', - "ii;": '\U00002148', - "iiiint;": '\U00002A0C', - "iiint;": '\U0000222D', - "iinfin;": '\U000029DC', - "iiota;": '\U00002129', - "ijlig;": '\U00000133', - "imacr;": '\U0000012B', - "image;": '\U00002111', - "imagline;": '\U00002110', - "imagpart;": '\U00002111', - "imath;": '\U00000131', - "imof;": '\U000022B7', - "imped;": '\U000001B5', - "in;": '\U00002208', - "incare;": '\U00002105', - "infin;": '\U0000221E', - "infintie;": '\U000029DD', - "inodot;": '\U00000131', - "int;": '\U0000222B', - "intcal;": '\U000022BA', - "integers;": '\U00002124', - "intercal;": '\U000022BA', - "intlarhk;": '\U00002A17', - "intprod;": '\U00002A3C', - "iocy;": '\U00000451', - "iogon;": '\U0000012F', - "iopf;": '\U0001D55A', - "iota;": '\U000003B9', - "iprod;": '\U00002A3C', - "iquest;": '\U000000BF', - "iscr;": '\U0001D4BE', - "isin;": '\U00002208', - "isinE;": '\U000022F9', - "isindot;": '\U000022F5', - "isins;": '\U000022F4', - "isinsv;": '\U000022F3', - "isinv;": '\U00002208', - "it;": '\U00002062', - "itilde;": '\U00000129', - "iukcy;": '\U00000456', - "iuml;": '\U000000EF', - "jcirc;": '\U00000135', - "jcy;": '\U00000439', - "jfr;": '\U0001D527', - "jmath;": '\U00000237', - "jopf;": '\U0001D55B', - "jscr;": '\U0001D4BF', - "jsercy;": '\U00000458', - "jukcy;": '\U00000454', - "kappa;": '\U000003BA', - "kappav;": '\U000003F0', - "kcedil;": '\U00000137', - "kcy;": '\U0000043A', - "kfr;": '\U0001D528', - "kgreen;": '\U00000138', - "khcy;": '\U00000445', - "kjcy;": '\U0000045C', - "kopf;": '\U0001D55C', - "kscr;": '\U0001D4C0', - "lAarr;": '\U000021DA', - "lArr;": '\U000021D0', - "lAtail;": '\U0000291B', - "lBarr;": '\U0000290E', - "lE;": '\U00002266', - "lEg;": '\U00002A8B', - "lHar;": '\U00002962', - "lacute;": '\U0000013A', - "laemptyv;": '\U000029B4', - "lagran;": '\U00002112', - "lambda;": '\U000003BB', - "lang;": '\U000027E8', - "langd;": '\U00002991', - "langle;": '\U000027E8', - "lap;": '\U00002A85', - "laquo;": '\U000000AB', - "larr;": '\U00002190', - "larrb;": '\U000021E4', - "larrbfs;": '\U0000291F', - "larrfs;": '\U0000291D', - "larrhk;": '\U000021A9', - "larrlp;": '\U000021AB', - "larrpl;": '\U00002939', - "larrsim;": '\U00002973', - "larrtl;": '\U000021A2', - "lat;": '\U00002AAB', - "latail;": '\U00002919', - "late;": '\U00002AAD', - "lbarr;": '\U0000290C', - "lbbrk;": '\U00002772', - "lbrace;": '\U0000007B', - "lbrack;": '\U0000005B', - "lbrke;": '\U0000298B', - "lbrksld;": '\U0000298F', - "lbrkslu;": '\U0000298D', - "lcaron;": '\U0000013E', - "lcedil;": '\U0000013C', - "lceil;": '\U00002308', - "lcub;": '\U0000007B', - "lcy;": '\U0000043B', - "ldca;": '\U00002936', - "ldquo;": '\U0000201C', - "ldquor;": '\U0000201E', - "ldrdhar;": '\U00002967', - "ldrushar;": '\U0000294B', - "ldsh;": '\U000021B2', - "le;": '\U00002264', - "leftarrow;": '\U00002190', - "leftarrowtail;": '\U000021A2', - "leftharpoondown;": '\U000021BD', - "leftharpoonup;": '\U000021BC', - "leftleftarrows;": '\U000021C7', - "leftrightarrow;": '\U00002194', - "leftrightarrows;": '\U000021C6', - "leftrightharpoons;": '\U000021CB', - "leftrightsquigarrow;": '\U000021AD', - "leftthreetimes;": '\U000022CB', - "leg;": '\U000022DA', - "leq;": '\U00002264', - "leqq;": '\U00002266', - "leqslant;": '\U00002A7D', - "les;": '\U00002A7D', - "lescc;": '\U00002AA8', - "lesdot;": '\U00002A7F', - "lesdoto;": '\U00002A81', - "lesdotor;": '\U00002A83', - "lesges;": '\U00002A93', - "lessapprox;": '\U00002A85', - "lessdot;": '\U000022D6', - "lesseqgtr;": '\U000022DA', - "lesseqqgtr;": '\U00002A8B', - "lessgtr;": '\U00002276', - "lesssim;": '\U00002272', - "lfisht;": '\U0000297C', - "lfloor;": '\U0000230A', - "lfr;": '\U0001D529', - "lg;": '\U00002276', - "lgE;": '\U00002A91', - "lhard;": '\U000021BD', - "lharu;": '\U000021BC', - "lharul;": '\U0000296A', - "lhblk;": '\U00002584', - "ljcy;": '\U00000459', - "ll;": '\U0000226A', - "llarr;": '\U000021C7', - "llcorner;": '\U0000231E', - "llhard;": '\U0000296B', - "lltri;": '\U000025FA', - "lmidot;": '\U00000140', - "lmoust;": '\U000023B0', - "lmoustache;": '\U000023B0', - "lnE;": '\U00002268', - "lnap;": '\U00002A89', - "lnapprox;": '\U00002A89', - "lne;": '\U00002A87', - "lneq;": '\U00002A87', - "lneqq;": '\U00002268', - "lnsim;": '\U000022E6', - "loang;": '\U000027EC', - "loarr;": '\U000021FD', - "lobrk;": '\U000027E6', - "longleftarrow;": '\U000027F5', - "longleftrightarrow;": '\U000027F7', - "longmapsto;": '\U000027FC', - "longrightarrow;": '\U000027F6', - "looparrowleft;": '\U000021AB', - "looparrowright;": '\U000021AC', - "lopar;": '\U00002985', - "lopf;": '\U0001D55D', - "loplus;": '\U00002A2D', - "lotimes;": '\U00002A34', - "lowast;": '\U00002217', - "lowbar;": '\U0000005F', - "loz;": '\U000025CA', - "lozenge;": '\U000025CA', - "lozf;": '\U000029EB', - "lpar;": '\U00000028', - "lparlt;": '\U00002993', - "lrarr;": '\U000021C6', - "lrcorner;": '\U0000231F', - "lrhar;": '\U000021CB', - "lrhard;": '\U0000296D', - "lrm;": '\U0000200E', - "lrtri;": '\U000022BF', - "lsaquo;": '\U00002039', - "lscr;": '\U0001D4C1', - "lsh;": '\U000021B0', - "lsim;": '\U00002272', - "lsime;": '\U00002A8D', - "lsimg;": '\U00002A8F', - "lsqb;": '\U0000005B', - "lsquo;": '\U00002018', - "lsquor;": '\U0000201A', - "lstrok;": '\U00000142', - "lt;": '\U0000003C', - "ltcc;": '\U00002AA6', - "ltcir;": '\U00002A79', - "ltdot;": '\U000022D6', - "lthree;": '\U000022CB', - "ltimes;": '\U000022C9', - "ltlarr;": '\U00002976', - "ltquest;": '\U00002A7B', - "ltrPar;": '\U00002996', - "ltri;": '\U000025C3', - "ltrie;": '\U000022B4', - "ltrif;": '\U000025C2', - "lurdshar;": '\U0000294A', - "luruhar;": '\U00002966', - "mDDot;": '\U0000223A', - "macr;": '\U000000AF', - "male;": '\U00002642', - "malt;": '\U00002720', - "maltese;": '\U00002720', - "map;": '\U000021A6', - "mapsto;": '\U000021A6', - "mapstodown;": '\U000021A7', - "mapstoleft;": '\U000021A4', - "mapstoup;": '\U000021A5', - "marker;": '\U000025AE', - "mcomma;": '\U00002A29', - "mcy;": '\U0000043C', - "mdash;": '\U00002014', - "measuredangle;": '\U00002221', - "mfr;": '\U0001D52A', - "mho;": '\U00002127', - "micro;": '\U000000B5', - "mid;": '\U00002223', - "midast;": '\U0000002A', - "midcir;": '\U00002AF0', - "middot;": '\U000000B7', - "minus;": '\U00002212', - "minusb;": '\U0000229F', - "minusd;": '\U00002238', - "minusdu;": '\U00002A2A', - "mlcp;": '\U00002ADB', - "mldr;": '\U00002026', - "mnplus;": '\U00002213', - "models;": '\U000022A7', - "mopf;": '\U0001D55E', - "mp;": '\U00002213', - "mscr;": '\U0001D4C2', - "mstpos;": '\U0000223E', - "mu;": '\U000003BC', - "multimap;": '\U000022B8', - "mumap;": '\U000022B8', - "nLeftarrow;": '\U000021CD', - "nLeftrightarrow;": '\U000021CE', - "nRightarrow;": '\U000021CF', - "nVDash;": '\U000022AF', - "nVdash;": '\U000022AE', - "nabla;": '\U00002207', - "nacute;": '\U00000144', - "nap;": '\U00002249', - "napos;": '\U00000149', - "napprox;": '\U00002249', - "natur;": '\U0000266E', - "natural;": '\U0000266E', - "naturals;": '\U00002115', - "nbsp;": '\U000000A0', - "ncap;": '\U00002A43', - "ncaron;": '\U00000148', - "ncedil;": '\U00000146', - "ncong;": '\U00002247', - "ncup;": '\U00002A42', - "ncy;": '\U0000043D', - "ndash;": '\U00002013', - "ne;": '\U00002260', - "neArr;": '\U000021D7', - "nearhk;": '\U00002924', - "nearr;": '\U00002197', - "nearrow;": '\U00002197', - "nequiv;": '\U00002262', - "nesear;": '\U00002928', - "nexist;": '\U00002204', - "nexists;": '\U00002204', - "nfr;": '\U0001D52B', - "nge;": '\U00002271', - "ngeq;": '\U00002271', - "ngsim;": '\U00002275', - "ngt;": '\U0000226F', - "ngtr;": '\U0000226F', - "nhArr;": '\U000021CE', - "nharr;": '\U000021AE', - "nhpar;": '\U00002AF2', - "ni;": '\U0000220B', - "nis;": '\U000022FC', - "nisd;": '\U000022FA', - "niv;": '\U0000220B', - "njcy;": '\U0000045A', - "nlArr;": '\U000021CD', - "nlarr;": '\U0000219A', - "nldr;": '\U00002025', - "nle;": '\U00002270', - "nleftarrow;": '\U0000219A', - "nleftrightarrow;": '\U000021AE', - "nleq;": '\U00002270', - "nless;": '\U0000226E', - "nlsim;": '\U00002274', - "nlt;": '\U0000226E', - "nltri;": '\U000022EA', - "nltrie;": '\U000022EC', - "nmid;": '\U00002224', - "nopf;": '\U0001D55F', - "not;": '\U000000AC', - "notin;": '\U00002209', - "notinva;": '\U00002209', - "notinvb;": '\U000022F7', - "notinvc;": '\U000022F6', - "notni;": '\U0000220C', - "notniva;": '\U0000220C', - "notnivb;": '\U000022FE', - "notnivc;": '\U000022FD', - "npar;": '\U00002226', - "nparallel;": '\U00002226', - "npolint;": '\U00002A14', - "npr;": '\U00002280', - "nprcue;": '\U000022E0', - "nprec;": '\U00002280', - "nrArr;": '\U000021CF', - "nrarr;": '\U0000219B', - "nrightarrow;": '\U0000219B', - "nrtri;": '\U000022EB', - "nrtrie;": '\U000022ED', - "nsc;": '\U00002281', - "nsccue;": '\U000022E1', - "nscr;": '\U0001D4C3', - "nshortmid;": '\U00002224', - "nshortparallel;": '\U00002226', - "nsim;": '\U00002241', - "nsime;": '\U00002244', - "nsimeq;": '\U00002244', - "nsmid;": '\U00002224', - "nspar;": '\U00002226', - "nsqsube;": '\U000022E2', - "nsqsupe;": '\U000022E3', - "nsub;": '\U00002284', - "nsube;": '\U00002288', - "nsubseteq;": '\U00002288', - "nsucc;": '\U00002281', - "nsup;": '\U00002285', - "nsupe;": '\U00002289', - "nsupseteq;": '\U00002289', - "ntgl;": '\U00002279', - "ntilde;": '\U000000F1', - "ntlg;": '\U00002278', - "ntriangleleft;": '\U000022EA', - "ntrianglelefteq;": '\U000022EC', - "ntriangleright;": '\U000022EB', - "ntrianglerighteq;": '\U000022ED', - "nu;": '\U000003BD', - "num;": '\U00000023', - "numero;": '\U00002116', - "numsp;": '\U00002007', - "nvDash;": '\U000022AD', - "nvHarr;": '\U00002904', - "nvdash;": '\U000022AC', - "nvinfin;": '\U000029DE', - "nvlArr;": '\U00002902', - "nvrArr;": '\U00002903', - "nwArr;": '\U000021D6', - "nwarhk;": '\U00002923', - "nwarr;": '\U00002196', - "nwarrow;": '\U00002196', - "nwnear;": '\U00002927', - "oS;": '\U000024C8', - "oacute;": '\U000000F3', - "oast;": '\U0000229B', - "ocir;": '\U0000229A', - "ocirc;": '\U000000F4', - "ocy;": '\U0000043E', - "odash;": '\U0000229D', - "odblac;": '\U00000151', - "odiv;": '\U00002A38', - "odot;": '\U00002299', - "odsold;": '\U000029BC', - "oelig;": '\U00000153', - "ofcir;": '\U000029BF', - "ofr;": '\U0001D52C', - "ogon;": '\U000002DB', - "ograve;": '\U000000F2', - "ogt;": '\U000029C1', - "ohbar;": '\U000029B5', - "ohm;": '\U000003A9', - "oint;": '\U0000222E', - "olarr;": '\U000021BA', - "olcir;": '\U000029BE', - "olcross;": '\U000029BB', - "oline;": '\U0000203E', - "olt;": '\U000029C0', - "omacr;": '\U0000014D', - "omega;": '\U000003C9', - "omicron;": '\U000003BF', - "omid;": '\U000029B6', - "ominus;": '\U00002296', - "oopf;": '\U0001D560', - "opar;": '\U000029B7', - "operp;": '\U000029B9', - "oplus;": '\U00002295', - "or;": '\U00002228', - "orarr;": '\U000021BB', - "ord;": '\U00002A5D', - "order;": '\U00002134', - "orderof;": '\U00002134', - "ordf;": '\U000000AA', - "ordm;": '\U000000BA', - "origof;": '\U000022B6', - "oror;": '\U00002A56', - "orslope;": '\U00002A57', - "orv;": '\U00002A5B', - "oscr;": '\U00002134', - "oslash;": '\U000000F8', - "osol;": '\U00002298', - "otilde;": '\U000000F5', - "otimes;": '\U00002297', - "otimesas;": '\U00002A36', - "ouml;": '\U000000F6', - "ovbar;": '\U0000233D', - "par;": '\U00002225', - "para;": '\U000000B6', - "parallel;": '\U00002225', - "parsim;": '\U00002AF3', - "parsl;": '\U00002AFD', - "part;": '\U00002202', - "pcy;": '\U0000043F', - "percnt;": '\U00000025', - "period;": '\U0000002E', - "permil;": '\U00002030', - "perp;": '\U000022A5', - "pertenk;": '\U00002031', - "pfr;": '\U0001D52D', - "phi;": '\U000003C6', - "phiv;": '\U000003D5', - "phmmat;": '\U00002133', - "phone;": '\U0000260E', - "pi;": '\U000003C0', - "pitchfork;": '\U000022D4', - "piv;": '\U000003D6', - "planck;": '\U0000210F', - "planckh;": '\U0000210E', - "plankv;": '\U0000210F', - "plus;": '\U0000002B', - "plusacir;": '\U00002A23', - "plusb;": '\U0000229E', - "pluscir;": '\U00002A22', - "plusdo;": '\U00002214', - "plusdu;": '\U00002A25', - "pluse;": '\U00002A72', - "plusmn;": '\U000000B1', - "plussim;": '\U00002A26', - "plustwo;": '\U00002A27', - "pm;": '\U000000B1', - "pointint;": '\U00002A15', - "popf;": '\U0001D561', - "pound;": '\U000000A3', - "pr;": '\U0000227A', - "prE;": '\U00002AB3', - "prap;": '\U00002AB7', - "prcue;": '\U0000227C', - "pre;": '\U00002AAF', - "prec;": '\U0000227A', - "precapprox;": '\U00002AB7', - "preccurlyeq;": '\U0000227C', - "preceq;": '\U00002AAF', - "precnapprox;": '\U00002AB9', - "precneqq;": '\U00002AB5', - "precnsim;": '\U000022E8', - "precsim;": '\U0000227E', - "prime;": '\U00002032', - "primes;": '\U00002119', - "prnE;": '\U00002AB5', - "prnap;": '\U00002AB9', - "prnsim;": '\U000022E8', - "prod;": '\U0000220F', - "profalar;": '\U0000232E', - "profline;": '\U00002312', - "profsurf;": '\U00002313', - "prop;": '\U0000221D', - "propto;": '\U0000221D', - "prsim;": '\U0000227E', - "prurel;": '\U000022B0', - "pscr;": '\U0001D4C5', - "psi;": '\U000003C8', - "puncsp;": '\U00002008', - "qfr;": '\U0001D52E', - "qint;": '\U00002A0C', - "qopf;": '\U0001D562', - "qprime;": '\U00002057', - "qscr;": '\U0001D4C6', - "quaternions;": '\U0000210D', - "quatint;": '\U00002A16', - "quest;": '\U0000003F', - "questeq;": '\U0000225F', - "quot;": '\U00000022', - "rAarr;": '\U000021DB', - "rArr;": '\U000021D2', - "rAtail;": '\U0000291C', - "rBarr;": '\U0000290F', - "rHar;": '\U00002964', - "racute;": '\U00000155', - "radic;": '\U0000221A', - "raemptyv;": '\U000029B3', - "rang;": '\U000027E9', - "rangd;": '\U00002992', - "range;": '\U000029A5', - "rangle;": '\U000027E9', - "raquo;": '\U000000BB', - "rarr;": '\U00002192', - "rarrap;": '\U00002975', - "rarrb;": '\U000021E5', - "rarrbfs;": '\U00002920', - "rarrc;": '\U00002933', - "rarrfs;": '\U0000291E', - "rarrhk;": '\U000021AA', - "rarrlp;": '\U000021AC', - "rarrpl;": '\U00002945', - "rarrsim;": '\U00002974', - "rarrtl;": '\U000021A3', - "rarrw;": '\U0000219D', - "ratail;": '\U0000291A', - "ratio;": '\U00002236', - "rationals;": '\U0000211A', - "rbarr;": '\U0000290D', - "rbbrk;": '\U00002773', - "rbrace;": '\U0000007D', - "rbrack;": '\U0000005D', - "rbrke;": '\U0000298C', - "rbrksld;": '\U0000298E', - "rbrkslu;": '\U00002990', - "rcaron;": '\U00000159', - "rcedil;": '\U00000157', - "rceil;": '\U00002309', - "rcub;": '\U0000007D', - "rcy;": '\U00000440', - "rdca;": '\U00002937', - "rdldhar;": '\U00002969', - "rdquo;": '\U0000201D', - "rdquor;": '\U0000201D', - "rdsh;": '\U000021B3', - "real;": '\U0000211C', - "realine;": '\U0000211B', - "realpart;": '\U0000211C', - "reals;": '\U0000211D', - "rect;": '\U000025AD', - "reg;": '\U000000AE', - "rfisht;": '\U0000297D', - "rfloor;": '\U0000230B', - "rfr;": '\U0001D52F', - "rhard;": '\U000021C1', - "rharu;": '\U000021C0', - "rharul;": '\U0000296C', - "rho;": '\U000003C1', - "rhov;": '\U000003F1', - "rightarrow;": '\U00002192', - "rightarrowtail;": '\U000021A3', - "rightharpoondown;": '\U000021C1', - "rightharpoonup;": '\U000021C0', - "rightleftarrows;": '\U000021C4', - "rightleftharpoons;": '\U000021CC', - "rightrightarrows;": '\U000021C9', - "rightsquigarrow;": '\U0000219D', - "rightthreetimes;": '\U000022CC', - "ring;": '\U000002DA', - "risingdotseq;": '\U00002253', - "rlarr;": '\U000021C4', - "rlhar;": '\U000021CC', - "rlm;": '\U0000200F', - "rmoust;": '\U000023B1', - "rmoustache;": '\U000023B1', - "rnmid;": '\U00002AEE', - "roang;": '\U000027ED', - "roarr;": '\U000021FE', - "robrk;": '\U000027E7', - "ropar;": '\U00002986', - "ropf;": '\U0001D563', - "roplus;": '\U00002A2E', - "rotimes;": '\U00002A35', - "rpar;": '\U00000029', - "rpargt;": '\U00002994', - "rppolint;": '\U00002A12', - "rrarr;": '\U000021C9', - "rsaquo;": '\U0000203A', - "rscr;": '\U0001D4C7', - "rsh;": '\U000021B1', - "rsqb;": '\U0000005D', - "rsquo;": '\U00002019', - "rsquor;": '\U00002019', - "rthree;": '\U000022CC', - "rtimes;": '\U000022CA', - "rtri;": '\U000025B9', - "rtrie;": '\U000022B5', - "rtrif;": '\U000025B8', - "rtriltri;": '\U000029CE', - "ruluhar;": '\U00002968', - "rx;": '\U0000211E', - "sacute;": '\U0000015B', - "sbquo;": '\U0000201A', - "sc;": '\U0000227B', - "scE;": '\U00002AB4', - "scap;": '\U00002AB8', - "scaron;": '\U00000161', - "sccue;": '\U0000227D', - "sce;": '\U00002AB0', - "scedil;": '\U0000015F', - "scirc;": '\U0000015D', - "scnE;": '\U00002AB6', - "scnap;": '\U00002ABA', - "scnsim;": '\U000022E9', - "scpolint;": '\U00002A13', - "scsim;": '\U0000227F', - "scy;": '\U00000441', - "sdot;": '\U000022C5', - "sdotb;": '\U000022A1', - "sdote;": '\U00002A66', - "seArr;": '\U000021D8', - "searhk;": '\U00002925', - "searr;": '\U00002198', - "searrow;": '\U00002198', - "sect;": '\U000000A7', - "semi;": '\U0000003B', - "seswar;": '\U00002929', - "setminus;": '\U00002216', - "setmn;": '\U00002216', - "sext;": '\U00002736', - "sfr;": '\U0001D530', - "sfrown;": '\U00002322', - "sharp;": '\U0000266F', - "shchcy;": '\U00000449', - "shcy;": '\U00000448', - "shortmid;": '\U00002223', - "shortparallel;": '\U00002225', - "shy;": '\U000000AD', - "sigma;": '\U000003C3', - "sigmaf;": '\U000003C2', - "sigmav;": '\U000003C2', - "sim;": '\U0000223C', - "simdot;": '\U00002A6A', - "sime;": '\U00002243', - "simeq;": '\U00002243', - "simg;": '\U00002A9E', - "simgE;": '\U00002AA0', - "siml;": '\U00002A9D', - "simlE;": '\U00002A9F', - "simne;": '\U00002246', - "simplus;": '\U00002A24', - "simrarr;": '\U00002972', - "slarr;": '\U00002190', - "smallsetminus;": '\U00002216', - "smashp;": '\U00002A33', - "smeparsl;": '\U000029E4', - "smid;": '\U00002223', - "smile;": '\U00002323', - "smt;": '\U00002AAA', - "smte;": '\U00002AAC', - "softcy;": '\U0000044C', - "sol;": '\U0000002F', - "solb;": '\U000029C4', - "solbar;": '\U0000233F', - "sopf;": '\U0001D564', - "spades;": '\U00002660', - "spadesuit;": '\U00002660', - "spar;": '\U00002225', - "sqcap;": '\U00002293', - "sqcup;": '\U00002294', - "sqsub;": '\U0000228F', - "sqsube;": '\U00002291', - "sqsubset;": '\U0000228F', - "sqsubseteq;": '\U00002291', - "sqsup;": '\U00002290', - "sqsupe;": '\U00002292', - "sqsupset;": '\U00002290', - "sqsupseteq;": '\U00002292', - "squ;": '\U000025A1', - "square;": '\U000025A1', - "squarf;": '\U000025AA', - "squf;": '\U000025AA', - "srarr;": '\U00002192', - "sscr;": '\U0001D4C8', - "ssetmn;": '\U00002216', - "ssmile;": '\U00002323', - "sstarf;": '\U000022C6', - "star;": '\U00002606', - "starf;": '\U00002605', - "straightepsilon;": '\U000003F5', - "straightphi;": '\U000003D5', - "strns;": '\U000000AF', - "sub;": '\U00002282', - "subE;": '\U00002AC5', - "subdot;": '\U00002ABD', - "sube;": '\U00002286', - "subedot;": '\U00002AC3', - "submult;": '\U00002AC1', - "subnE;": '\U00002ACB', - "subne;": '\U0000228A', - "subplus;": '\U00002ABF', - "subrarr;": '\U00002979', - "subset;": '\U00002282', - "subseteq;": '\U00002286', - "subseteqq;": '\U00002AC5', - "subsetneq;": '\U0000228A', - "subsetneqq;": '\U00002ACB', - "subsim;": '\U00002AC7', - "subsub;": '\U00002AD5', - "subsup;": '\U00002AD3', - "succ;": '\U0000227B', - "succapprox;": '\U00002AB8', - "succcurlyeq;": '\U0000227D', - "succeq;": '\U00002AB0', - "succnapprox;": '\U00002ABA', - "succneqq;": '\U00002AB6', - "succnsim;": '\U000022E9', - "succsim;": '\U0000227F', - "sum;": '\U00002211', - "sung;": '\U0000266A', - "sup;": '\U00002283', - "sup1;": '\U000000B9', - "sup2;": '\U000000B2', - "sup3;": '\U000000B3', - "supE;": '\U00002AC6', - "supdot;": '\U00002ABE', - "supdsub;": '\U00002AD8', - "supe;": '\U00002287', - "supedot;": '\U00002AC4', - "suphsol;": '\U000027C9', - "suphsub;": '\U00002AD7', - "suplarr;": '\U0000297B', - "supmult;": '\U00002AC2', - "supnE;": '\U00002ACC', - "supne;": '\U0000228B', - "supplus;": '\U00002AC0', - "supset;": '\U00002283', - "supseteq;": '\U00002287', - "supseteqq;": '\U00002AC6', - "supsetneq;": '\U0000228B', - "supsetneqq;": '\U00002ACC', - "supsim;": '\U00002AC8', - "supsub;": '\U00002AD4', - "supsup;": '\U00002AD6', - "swArr;": '\U000021D9', - "swarhk;": '\U00002926', - "swarr;": '\U00002199', - "swarrow;": '\U00002199', - "swnwar;": '\U0000292A', - "szlig;": '\U000000DF', - "target;": '\U00002316', - "tau;": '\U000003C4', - "tbrk;": '\U000023B4', - "tcaron;": '\U00000165', - "tcedil;": '\U00000163', - "tcy;": '\U00000442', - "tdot;": '\U000020DB', - "telrec;": '\U00002315', - "tfr;": '\U0001D531', - "there4;": '\U00002234', - "therefore;": '\U00002234', - "theta;": '\U000003B8', - "thetasym;": '\U000003D1', - "thetav;": '\U000003D1', - "thickapprox;": '\U00002248', - "thicksim;": '\U0000223C', - "thinsp;": '\U00002009', - "thkap;": '\U00002248', - "thksim;": '\U0000223C', - "thorn;": '\U000000FE', - "tilde;": '\U000002DC', - "times;": '\U000000D7', - "timesb;": '\U000022A0', - "timesbar;": '\U00002A31', - "timesd;": '\U00002A30', - "tint;": '\U0000222D', - "toea;": '\U00002928', - "top;": '\U000022A4', - "topbot;": '\U00002336', - "topcir;": '\U00002AF1', - "topf;": '\U0001D565', - "topfork;": '\U00002ADA', - "tosa;": '\U00002929', - "tprime;": '\U00002034', - "trade;": '\U00002122', - "triangle;": '\U000025B5', - "triangledown;": '\U000025BF', - "triangleleft;": '\U000025C3', - "trianglelefteq;": '\U000022B4', - "triangleq;": '\U0000225C', - "triangleright;": '\U000025B9', - "trianglerighteq;": '\U000022B5', - "tridot;": '\U000025EC', - "trie;": '\U0000225C', - "triminus;": '\U00002A3A', - "triplus;": '\U00002A39', - "trisb;": '\U000029CD', - "tritime;": '\U00002A3B', - "trpezium;": '\U000023E2', - "tscr;": '\U0001D4C9', - "tscy;": '\U00000446', - "tshcy;": '\U0000045B', - "tstrok;": '\U00000167', - "twixt;": '\U0000226C', - "twoheadleftarrow;": '\U0000219E', - "twoheadrightarrow;": '\U000021A0', - "uArr;": '\U000021D1', - "uHar;": '\U00002963', - "uacute;": '\U000000FA', - "uarr;": '\U00002191', - "ubrcy;": '\U0000045E', - "ubreve;": '\U0000016D', - "ucirc;": '\U000000FB', - "ucy;": '\U00000443', - "udarr;": '\U000021C5', - "udblac;": '\U00000171', - "udhar;": '\U0000296E', - "ufisht;": '\U0000297E', - "ufr;": '\U0001D532', - "ugrave;": '\U000000F9', - "uharl;": '\U000021BF', - "uharr;": '\U000021BE', - "uhblk;": '\U00002580', - "ulcorn;": '\U0000231C', - "ulcorner;": '\U0000231C', - "ulcrop;": '\U0000230F', - "ultri;": '\U000025F8', - "umacr;": '\U0000016B', - "uml;": '\U000000A8', - "uogon;": '\U00000173', - "uopf;": '\U0001D566', - "uparrow;": '\U00002191', - "updownarrow;": '\U00002195', - "upharpoonleft;": '\U000021BF', - "upharpoonright;": '\U000021BE', - "uplus;": '\U0000228E', - "upsi;": '\U000003C5', - "upsih;": '\U000003D2', - "upsilon;": '\U000003C5', - "upuparrows;": '\U000021C8', - "urcorn;": '\U0000231D', - "urcorner;": '\U0000231D', - "urcrop;": '\U0000230E', - "uring;": '\U0000016F', - "urtri;": '\U000025F9', - "uscr;": '\U0001D4CA', - "utdot;": '\U000022F0', - "utilde;": '\U00000169', - "utri;": '\U000025B5', - "utrif;": '\U000025B4', - "uuarr;": '\U000021C8', - "uuml;": '\U000000FC', - "uwangle;": '\U000029A7', - "vArr;": '\U000021D5', - "vBar;": '\U00002AE8', - "vBarv;": '\U00002AE9', - "vDash;": '\U000022A8', - "vangrt;": '\U0000299C', - "varepsilon;": '\U000003F5', - "varkappa;": '\U000003F0', - "varnothing;": '\U00002205', - "varphi;": '\U000003D5', - "varpi;": '\U000003D6', - "varpropto;": '\U0000221D', - "varr;": '\U00002195', - "varrho;": '\U000003F1', - "varsigma;": '\U000003C2', - "vartheta;": '\U000003D1', - "vartriangleleft;": '\U000022B2', - "vartriangleright;": '\U000022B3', - "vcy;": '\U00000432', - "vdash;": '\U000022A2', - "vee;": '\U00002228', - "veebar;": '\U000022BB', - "veeeq;": '\U0000225A', - "vellip;": '\U000022EE', - "verbar;": '\U0000007C', - "vert;": '\U0000007C', - "vfr;": '\U0001D533', - "vltri;": '\U000022B2', - "vopf;": '\U0001D567', - "vprop;": '\U0000221D', - "vrtri;": '\U000022B3', - "vscr;": '\U0001D4CB', - "vzigzag;": '\U0000299A', - "wcirc;": '\U00000175', - "wedbar;": '\U00002A5F', - "wedge;": '\U00002227', - "wedgeq;": '\U00002259', - "weierp;": '\U00002118', - "wfr;": '\U0001D534', - "wopf;": '\U0001D568', - "wp;": '\U00002118', - "wr;": '\U00002240', - "wreath;": '\U00002240', - "wscr;": '\U0001D4CC', - "xcap;": '\U000022C2', - "xcirc;": '\U000025EF', - "xcup;": '\U000022C3', - "xdtri;": '\U000025BD', - "xfr;": '\U0001D535', - "xhArr;": '\U000027FA', - "xharr;": '\U000027F7', - "xi;": '\U000003BE', - "xlArr;": '\U000027F8', - "xlarr;": '\U000027F5', - "xmap;": '\U000027FC', - "xnis;": '\U000022FB', - "xodot;": '\U00002A00', - "xopf;": '\U0001D569', - "xoplus;": '\U00002A01', - "xotime;": '\U00002A02', - "xrArr;": '\U000027F9', - "xrarr;": '\U000027F6', - "xscr;": '\U0001D4CD', - "xsqcup;": '\U00002A06', - "xuplus;": '\U00002A04', - "xutri;": '\U000025B3', - "xvee;": '\U000022C1', - "xwedge;": '\U000022C0', - "yacute;": '\U000000FD', - "yacy;": '\U0000044F', - "ycirc;": '\U00000177', - "ycy;": '\U0000044B', - "yen;": '\U000000A5', - "yfr;": '\U0001D536', - "yicy;": '\U00000457', - "yopf;": '\U0001D56A', - "yscr;": '\U0001D4CE', - "yucy;": '\U0000044E', - "yuml;": '\U000000FF', - "zacute;": '\U0000017A', - "zcaron;": '\U0000017E', - "zcy;": '\U00000437', - "zdot;": '\U0000017C', - "zeetrf;": '\U00002128', - "zeta;": '\U000003B6', - "zfr;": '\U0001D537', - "zhcy;": '\U00000436', - "zigrarr;": '\U000021DD', - "zopf;": '\U0001D56B', - "zscr;": '\U0001D4CF', - "zwj;": '\U0000200D', - "zwnj;": '\U0000200C', - "AElig": '\U000000C6', - "AMP": '\U00000026', - "Aacute": '\U000000C1', - "Acirc": '\U000000C2', - "Agrave": '\U000000C0', - "Aring": '\U000000C5', - "Atilde": '\U000000C3', - "Auml": '\U000000C4', - "COPY": '\U000000A9', - "Ccedil": '\U000000C7', - "ETH": '\U000000D0', - "Eacute": '\U000000C9', - "Ecirc": '\U000000CA', - "Egrave": '\U000000C8', - "Euml": '\U000000CB', - "GT": '\U0000003E', - "Iacute": '\U000000CD', - "Icirc": '\U000000CE', - "Igrave": '\U000000CC', - "Iuml": '\U000000CF', - "LT": '\U0000003C', - "Ntilde": '\U000000D1', - "Oacute": '\U000000D3', - "Ocirc": '\U000000D4', - "Ograve": '\U000000D2', - "Oslash": '\U000000D8', - "Otilde": '\U000000D5', - "Ouml": '\U000000D6', - "QUOT": '\U00000022', - "REG": '\U000000AE', - "THORN": '\U000000DE', - "Uacute": '\U000000DA', - "Ucirc": '\U000000DB', - "Ugrave": '\U000000D9', - "Uuml": '\U000000DC', - "Yacute": '\U000000DD', - "aacute": '\U000000E1', - "acirc": '\U000000E2', - "acute": '\U000000B4', - "aelig": '\U000000E6', - "agrave": '\U000000E0', - "amp": '\U00000026', - "aring": '\U000000E5', - "atilde": '\U000000E3', - "auml": '\U000000E4', - "brvbar": '\U000000A6', - "ccedil": '\U000000E7', - "cedil": '\U000000B8', - "cent": '\U000000A2', - "copy": '\U000000A9', - "curren": '\U000000A4', - "deg": '\U000000B0', - "divide": '\U000000F7', - "eacute": '\U000000E9', - "ecirc": '\U000000EA', - "egrave": '\U000000E8', - "eth": '\U000000F0', - "euml": '\U000000EB', - "frac12": '\U000000BD', - "frac14": '\U000000BC', - "frac34": '\U000000BE', - "gt": '\U0000003E', - "iacute": '\U000000ED', - "icirc": '\U000000EE', - "iexcl": '\U000000A1', - "igrave": '\U000000EC', - "iquest": '\U000000BF', - "iuml": '\U000000EF', - "laquo": '\U000000AB', - "lt": '\U0000003C', - "macr": '\U000000AF', - "micro": '\U000000B5', - "middot": '\U000000B7', - "nbsp": '\U000000A0', - "not": '\U000000AC', - "ntilde": '\U000000F1', - "oacute": '\U000000F3', - "ocirc": '\U000000F4', - "ograve": '\U000000F2', - "ordf": '\U000000AA', - "ordm": '\U000000BA', - "oslash": '\U000000F8', - "otilde": '\U000000F5', - "ouml": '\U000000F6', - "para": '\U000000B6', - "plusmn": '\U000000B1', - "pound": '\U000000A3', - "quot": '\U00000022', - "raquo": '\U000000BB', - "reg": '\U000000AE', - "sect": '\U000000A7', - "shy": '\U000000AD', - "sup1": '\U000000B9', - "sup2": '\U000000B2', - "sup3": '\U000000B3', - "szlig": '\U000000DF', - "thorn": '\U000000FE', - "times": '\U000000D7', - "uacute": '\U000000FA', - "ucirc": '\U000000FB', - "ugrave": '\U000000F9', - "uml": '\U000000A8', - "uuml": '\U000000FC', - "yacute": '\U000000FD', - "yen": '\U000000A5', - "yuml": '\U000000FF', -} - -// HTML entities that are two unicode codepoints. -var entity2 = map[string][2]rune{ - // TODO(nigeltao): Handle replacements that are wider than their names. - // "nLt;": {'\u226A', '\u20D2'}, - // "nGt;": {'\u226B', '\u20D2'}, - "NotEqualTilde;": {'\u2242', '\u0338'}, - "NotGreaterFullEqual;": {'\u2267', '\u0338'}, - "NotGreaterGreater;": {'\u226B', '\u0338'}, - "NotGreaterSlantEqual;": {'\u2A7E', '\u0338'}, - "NotHumpDownHump;": {'\u224E', '\u0338'}, - "NotHumpEqual;": {'\u224F', '\u0338'}, - "NotLeftTriangleBar;": {'\u29CF', '\u0338'}, - "NotLessLess;": {'\u226A', '\u0338'}, - "NotLessSlantEqual;": {'\u2A7D', '\u0338'}, - "NotNestedGreaterGreater;": {'\u2AA2', '\u0338'}, - "NotNestedLessLess;": {'\u2AA1', '\u0338'}, - "NotPrecedesEqual;": {'\u2AAF', '\u0338'}, - "NotRightTriangleBar;": {'\u29D0', '\u0338'}, - "NotSquareSubset;": {'\u228F', '\u0338'}, - "NotSquareSuperset;": {'\u2290', '\u0338'}, - "NotSubset;": {'\u2282', '\u20D2'}, - "NotSucceedsEqual;": {'\u2AB0', '\u0338'}, - "NotSucceedsTilde;": {'\u227F', '\u0338'}, - "NotSuperset;": {'\u2283', '\u20D2'}, - "ThickSpace;": {'\u205F', '\u200A'}, - "acE;": {'\u223E', '\u0333'}, - "bne;": {'\u003D', '\u20E5'}, - "bnequiv;": {'\u2261', '\u20E5'}, - "caps;": {'\u2229', '\uFE00'}, - "cups;": {'\u222A', '\uFE00'}, - "fjlig;": {'\u0066', '\u006A'}, - "gesl;": {'\u22DB', '\uFE00'}, - "gvertneqq;": {'\u2269', '\uFE00'}, - "gvnE;": {'\u2269', '\uFE00'}, - "lates;": {'\u2AAD', '\uFE00'}, - "lesg;": {'\u22DA', '\uFE00'}, - "lvertneqq;": {'\u2268', '\uFE00'}, - "lvnE;": {'\u2268', '\uFE00'}, - "nGg;": {'\u22D9', '\u0338'}, - "nGtv;": {'\u226B', '\u0338'}, - "nLl;": {'\u22D8', '\u0338'}, - "nLtv;": {'\u226A', '\u0338'}, - "nang;": {'\u2220', '\u20D2'}, - "napE;": {'\u2A70', '\u0338'}, - "napid;": {'\u224B', '\u0338'}, - "nbump;": {'\u224E', '\u0338'}, - "nbumpe;": {'\u224F', '\u0338'}, - "ncongdot;": {'\u2A6D', '\u0338'}, - "nedot;": {'\u2250', '\u0338'}, - "nesim;": {'\u2242', '\u0338'}, - "ngE;": {'\u2267', '\u0338'}, - "ngeqq;": {'\u2267', '\u0338'}, - "ngeqslant;": {'\u2A7E', '\u0338'}, - "nges;": {'\u2A7E', '\u0338'}, - "nlE;": {'\u2266', '\u0338'}, - "nleqq;": {'\u2266', '\u0338'}, - "nleqslant;": {'\u2A7D', '\u0338'}, - "nles;": {'\u2A7D', '\u0338'}, - "notinE;": {'\u22F9', '\u0338'}, - "notindot;": {'\u22F5', '\u0338'}, - "nparsl;": {'\u2AFD', '\u20E5'}, - "npart;": {'\u2202', '\u0338'}, - "npre;": {'\u2AAF', '\u0338'}, - "npreceq;": {'\u2AAF', '\u0338'}, - "nrarrc;": {'\u2933', '\u0338'}, - "nrarrw;": {'\u219D', '\u0338'}, - "nsce;": {'\u2AB0', '\u0338'}, - "nsubE;": {'\u2AC5', '\u0338'}, - "nsubset;": {'\u2282', '\u20D2'}, - "nsubseteqq;": {'\u2AC5', '\u0338'}, - "nsucceq;": {'\u2AB0', '\u0338'}, - "nsupE;": {'\u2AC6', '\u0338'}, - "nsupset;": {'\u2283', '\u20D2'}, - "nsupseteqq;": {'\u2AC6', '\u0338'}, - "nvap;": {'\u224D', '\u20D2'}, - "nvge;": {'\u2265', '\u20D2'}, - "nvgt;": {'\u003E', '\u20D2'}, - "nvle;": {'\u2264', '\u20D2'}, - "nvlt;": {'\u003C', '\u20D2'}, - "nvltrie;": {'\u22B4', '\u20D2'}, - "nvrtrie;": {'\u22B5', '\u20D2'}, - "nvsim;": {'\u223C', '\u20D2'}, - "race;": {'\u223D', '\u0331'}, - "smtes;": {'\u2AAC', '\uFE00'}, - "sqcaps;": {'\u2293', '\uFE00'}, - "sqcups;": {'\u2294', '\uFE00'}, - "varsubsetneq;": {'\u228A', '\uFE00'}, - "varsubsetneqq;": {'\u2ACB', '\uFE00'}, - "varsupsetneq;": {'\u228B', '\uFE00'}, - "varsupsetneqq;": {'\u2ACC', '\uFE00'}, - "vnsub;": {'\u2282', '\u20D2'}, - "vnsup;": {'\u2283', '\u20D2'}, - "vsubnE;": {'\u2ACB', '\uFE00'}, - "vsubne;": {'\u228A', '\uFE00'}, - "vsupnE;": {'\u2ACC', '\uFE00'}, - "vsupne;": {'\u228B', '\uFE00'}, -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/entity_test.go gcc-4.8.1/libgo/go/exp/html/entity_test.go --- gcc-4.8.1.orig/libgo/go/exp/html/entity_test.go 2012-02-01 13:26:59.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/html/entity_test.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,29 +0,0 @@ -// Copyright 2010 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 html - -import ( - "testing" - "unicode/utf8" -) - -func TestEntityLength(t *testing.T) { - // We verify that the length of UTF-8 encoding of each value is <= 1 + len(key). - // The +1 comes from the leading "&". This property implies that the length of - // unescaped text is <= the length of escaped text. - for k, v := range entity { - if 1+len(k) < utf8.RuneLen(v) { - t.Error("escaped entity &" + k + " is shorter than its UTF-8 encoding " + string(v)) - } - if len(k) > longestEntityWithoutSemicolon && k[len(k)-1] != ';' { - t.Errorf("entity name %s is %d characters, but longestEntityWithoutSemicolon=%d", k, len(k), longestEntityWithoutSemicolon) - } - } - for k, v := range entity2 { - if 1+len(k) < utf8.RuneLen(v[0])+utf8.RuneLen(v[1]) { - t.Error("escaped entity &" + k + " is shorter than its UTF-8 encoding " + string(v[0]) + string(v[1])) - } - } -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/escape.go gcc-4.8.1/libgo/go/exp/html/escape.go --- gcc-4.8.1.orig/libgo/go/exp/html/escape.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/html/escape.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,258 +0,0 @@ -// Copyright 2010 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 html - -import ( - "bytes" - "strings" - "unicode/utf8" -) - -// These replacements permit compatibility with old numeric entities that -// assumed Windows-1252 encoding. -// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference -var replacementTable = [...]rune{ - '\u20AC', // First entry is what 0x80 should be replaced with. - '\u0081', - '\u201A', - '\u0192', - '\u201E', - '\u2026', - '\u2020', - '\u2021', - '\u02C6', - '\u2030', - '\u0160', - '\u2039', - '\u0152', - '\u008D', - '\u017D', - '\u008F', - '\u0090', - '\u2018', - '\u2019', - '\u201C', - '\u201D', - '\u2022', - '\u2013', - '\u2014', - '\u02DC', - '\u2122', - '\u0161', - '\u203A', - '\u0153', - '\u009D', - '\u017E', - '\u0178', // Last entry is 0x9F. - // 0x00->'\uFFFD' is handled programmatically. - // 0x0D->'\u000D' is a no-op. -} - -// unescapeEntity reads an entity like "<" from b[src:] and writes the -// corresponding "<" to b[dst:], returning the incremented dst and src cursors. -// Precondition: b[src] == '&' && dst <= src. -// attribute should be true if parsing an attribute value. -func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) { - // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference - - // i starts at 1 because we already know that s[0] == '&'. - i, s := 1, b[src:] - - if len(s) <= 1 { - b[dst] = b[src] - return dst + 1, src + 1 - } - - if s[i] == '#' { - if len(s) <= 3 { // We need to have at least "&#.". - b[dst] = b[src] - return dst + 1, src + 1 - } - i++ - c := s[i] - hex := false - if c == 'x' || c == 'X' { - hex = true - i++ - } - - x := '\x00' - for i < len(s) { - c = s[i] - i++ - if hex { - if '0' <= c && c <= '9' { - x = 16*x + rune(c) - '0' - continue - } else if 'a' <= c && c <= 'f' { - x = 16*x + rune(c) - 'a' + 10 - continue - } else if 'A' <= c && c <= 'F' { - x = 16*x + rune(c) - 'A' + 10 - continue - } - } else if '0' <= c && c <= '9' { - x = 10*x + rune(c) - '0' - continue - } - if c != ';' { - i-- - } - break - } - - if i <= 3 { // No characters matched. - b[dst] = b[src] - return dst + 1, src + 1 - } - - if 0x80 <= x && x <= 0x9F { - // Replace characters from Windows-1252 with UTF-8 equivalents. - x = replacementTable[x-0x80] - } else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF { - // Replace invalid characters with the replacement character. - x = '\uFFFD' - } - - return dst + utf8.EncodeRune(b[dst:], x), src + i - } - - // Consume the maximum number of characters possible, with the - // consumed characters matching one of the named references. - - for i < len(s) { - c := s[i] - i++ - // Lower-cased characters are more common in entities, so we check for them first. - if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' { - continue - } - if c != ';' { - i-- - } - break - } - - entityName := string(s[1:i]) - if entityName == "" { - // No-op. - } else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' { - // No-op. - } else if x := entity[entityName]; x != 0 { - return dst + utf8.EncodeRune(b[dst:], x), src + i - } else if x := entity2[entityName]; x[0] != 0 { - dst1 := dst + utf8.EncodeRune(b[dst:], x[0]) - return dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i - } else if !attribute { - maxLen := len(entityName) - 1 - if maxLen > longestEntityWithoutSemicolon { - maxLen = longestEntityWithoutSemicolon - } - for j := maxLen; j > 1; j-- { - if x := entity[entityName[:j]]; x != 0 { - return dst + utf8.EncodeRune(b[dst:], x), src + j + 1 - } - } - } - - dst1, src1 = dst+i, src+i - copy(b[dst:dst1], b[src:src1]) - return dst1, src1 -} - -// unescape unescapes b's entities in-place, so that "a<b" becomes "a': - esc = ">" - case '"': - // """ is shorter than """. - esc = """ - case '\r': - esc = " " - default: - panic("unrecognized escape character") - } - s = s[i+1:] - if _, err := w.WriteString(esc); err != nil { - return err - } - i = strings.IndexAny(s, escapedChars) - } - _, err := w.WriteString(s) - return err -} - -// EscapeString escapes special characters like "<" to become "<". It -// escapes only five such characters: <, >, &, ' and ". -// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't -// always true. -func EscapeString(s string) string { - if strings.IndexAny(s, escapedChars) == -1 { - return s - } - var buf bytes.Buffer - escape(&buf, s) - return buf.String() -} - -// UnescapeString unescapes entities like "<" to become "<". It unescapes a -// larger range of entities than EscapeString escapes. For example, "á" -// unescapes to "á", as does "á" and "&xE1;". -// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't -// always true. -func UnescapeString(s string) string { - for _, c := range s { - if c == '&' { - return string(unescape([]byte(s), false)) - } - } - return s -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/foreign.go gcc-4.8.1/libgo/go/exp/html/foreign.go --- gcc-4.8.1.orig/libgo/go/exp/html/foreign.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/html/foreign.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,226 +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 html - -import ( - "strings" -) - -func adjustAttributeNames(aa []Attribute, nameMap map[string]string) { - for i := range aa { - if newName, ok := nameMap[aa[i].Key]; ok { - aa[i].Key = newName - } - } -} - -func adjustForeignAttributes(aa []Attribute) { - for i, a := range aa { - if a.Key == "" || a.Key[0] != 'x' { - continue - } - switch a.Key { - case "xlink:actuate", "xlink:arcrole", "xlink:href", "xlink:role", "xlink:show", - "xlink:title", "xlink:type", "xml:base", "xml:lang", "xml:space", "xmlns:xlink": - j := strings.Index(a.Key, ":") - aa[i].Namespace = a.Key[:j] - aa[i].Key = a.Key[j+1:] - } - } -} - -func htmlIntegrationPoint(n *Node) bool { - if n.Type != ElementNode { - return false - } - switch n.Namespace { - case "math": - if n.Data == "annotation-xml" { - for _, a := range n.Attr { - if a.Key == "encoding" { - val := strings.ToLower(a.Val) - if val == "text/html" || val == "application/xhtml+xml" { - return true - } - } - } - } - case "svg": - switch n.Data { - case "desc", "foreignObject", "title": - return true - } - } - return false -} - -func mathMLTextIntegrationPoint(n *Node) bool { - if n.Namespace != "math" { - return false - } - switch n.Data { - case "mi", "mo", "mn", "ms", "mtext": - return true - } - return false -} - -// Section 12.2.5.5. -var breakout = map[string]bool{ - "b": true, - "big": true, - "blockquote": true, - "body": true, - "br": true, - "center": true, - "code": true, - "dd": true, - "div": true, - "dl": true, - "dt": true, - "em": true, - "embed": true, - "h1": true, - "h2": true, - "h3": true, - "h4": true, - "h5": true, - "h6": true, - "head": true, - "hr": true, - "i": true, - "img": true, - "li": true, - "listing": true, - "menu": true, - "meta": true, - "nobr": true, - "ol": true, - "p": true, - "pre": true, - "ruby": true, - "s": true, - "small": true, - "span": true, - "strong": true, - "strike": true, - "sub": true, - "sup": true, - "table": true, - "tt": true, - "u": true, - "ul": true, - "var": true, -} - -// Section 12.2.5.5. -var svgTagNameAdjustments = map[string]string{ - "altglyph": "altGlyph", - "altglyphdef": "altGlyphDef", - "altglyphitem": "altGlyphItem", - "animatecolor": "animateColor", - "animatemotion": "animateMotion", - "animatetransform": "animateTransform", - "clippath": "clipPath", - "feblend": "feBlend", - "fecolormatrix": "feColorMatrix", - "fecomponenttransfer": "feComponentTransfer", - "fecomposite": "feComposite", - "feconvolvematrix": "feConvolveMatrix", - "fediffuselighting": "feDiffuseLighting", - "fedisplacementmap": "feDisplacementMap", - "fedistantlight": "feDistantLight", - "feflood": "feFlood", - "fefunca": "feFuncA", - "fefuncb": "feFuncB", - "fefuncg": "feFuncG", - "fefuncr": "feFuncR", - "fegaussianblur": "feGaussianBlur", - "feimage": "feImage", - "femerge": "feMerge", - "femergenode": "feMergeNode", - "femorphology": "feMorphology", - "feoffset": "feOffset", - "fepointlight": "fePointLight", - "fespecularlighting": "feSpecularLighting", - "fespotlight": "feSpotLight", - "fetile": "feTile", - "feturbulence": "feTurbulence", - "foreignobject": "foreignObject", - "glyphref": "glyphRef", - "lineargradient": "linearGradient", - "radialgradient": "radialGradient", - "textpath": "textPath", -} - -// Section 12.2.5.1 -var mathMLAttributeAdjustments = map[string]string{ - "definitionurl": "definitionURL", -} - -var svgAttributeAdjustments = map[string]string{ - "attributename": "attributeName", - "attributetype": "attributeType", - "basefrequency": "baseFrequency", - "baseprofile": "baseProfile", - "calcmode": "calcMode", - "clippathunits": "clipPathUnits", - "contentscripttype": "contentScriptType", - "contentstyletype": "contentStyleType", - "diffuseconstant": "diffuseConstant", - "edgemode": "edgeMode", - "externalresourcesrequired": "externalResourcesRequired", - "filterres": "filterRes", - "filterunits": "filterUnits", - "glyphref": "glyphRef", - "gradienttransform": "gradientTransform", - "gradientunits": "gradientUnits", - "kernelmatrix": "kernelMatrix", - "kernelunitlength": "kernelUnitLength", - "keypoints": "keyPoints", - "keysplines": "keySplines", - "keytimes": "keyTimes", - "lengthadjust": "lengthAdjust", - "limitingconeangle": "limitingConeAngle", - "markerheight": "markerHeight", - "markerunits": "markerUnits", - "markerwidth": "markerWidth", - "maskcontentunits": "maskContentUnits", - "maskunits": "maskUnits", - "numoctaves": "numOctaves", - "pathlength": "pathLength", - "patterncontentunits": "patternContentUnits", - "patterntransform": "patternTransform", - "patternunits": "patternUnits", - "pointsatx": "pointsAtX", - "pointsaty": "pointsAtY", - "pointsatz": "pointsAtZ", - "preservealpha": "preserveAlpha", - "preserveaspectratio": "preserveAspectRatio", - "primitiveunits": "primitiveUnits", - "refx": "refX", - "refy": "refY", - "repeatcount": "repeatCount", - "repeatdur": "repeatDur", - "requiredextensions": "requiredExtensions", - "requiredfeatures": "requiredFeatures", - "specularconstant": "specularConstant", - "specularexponent": "specularExponent", - "spreadmethod": "spreadMethod", - "startoffset": "startOffset", - "stddeviation": "stdDeviation", - "stitchtiles": "stitchTiles", - "surfacescale": "surfaceScale", - "systemlanguage": "systemLanguage", - "tablevalues": "tableValues", - "targetx": "targetX", - "targety": "targetY", - "textlength": "textLength", - "viewbox": "viewBox", - "viewtarget": "viewTarget", - "xchannelselector": "xChannelSelector", - "ychannelselector": "yChannelSelector", - "zoomandpan": "zoomAndPan", -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/node.go gcc-4.8.1/libgo/go/exp/html/node.go --- gcc-4.8.1.orig/libgo/go/exp/html/node.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/html/node.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,193 +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 html - -import ( - "exp/html/atom" -) - -// A NodeType is the type of a Node. -type NodeType uint32 - -const ( - ErrorNode NodeType = iota - TextNode - DocumentNode - ElementNode - CommentNode - DoctypeNode - scopeMarkerNode -) - -// Section 12.2.3.3 says "scope markers are inserted when entering applet -// elements, buttons, object elements, marquees, table cells, and table -// captions, and are used to prevent formatting from 'leaking'". -var scopeMarker = Node{Type: scopeMarkerNode} - -// A Node consists of a NodeType and some Data (tag name for element nodes, -// content for text) and are part of a tree of Nodes. Element nodes may also -// have a Namespace and contain a slice of Attributes. Data is unescaped, so -// that it looks like "a 0 { - return (*s)[i-1] - } - return nil -} - -// index returns the index of the top-most occurrence of n in the stack, or -1 -// if n is not present. -func (s *nodeStack) index(n *Node) int { - for i := len(*s) - 1; i >= 0; i-- { - if (*s)[i] == n { - return i - } - } - return -1 -} - -// insert inserts a node at the given index. -func (s *nodeStack) insert(i int, n *Node) { - (*s) = append(*s, nil) - copy((*s)[i+1:], (*s)[i:]) - (*s)[i] = n -} - -// remove removes a node from the stack. It is a no-op if n is not present. -func (s *nodeStack) remove(n *Node) { - i := s.index(n) - if i == -1 { - return - } - copy((*s)[i:], (*s)[i+1:]) - j := len(*s) - 1 - (*s)[j] = nil - *s = (*s)[:j] -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/node_test.go gcc-4.8.1/libgo/go/exp/html/node_test.go --- gcc-4.8.1.orig/libgo/go/exp/html/node_test.go 2012-10-22 23:31:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/html/node_test.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,146 +0,0 @@ -// Copyright 2010 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 html - -import ( - "fmt" -) - -// checkTreeConsistency checks that a node and its descendants are all -// consistent in their parent/child/sibling relationships. -func checkTreeConsistency(n *Node) error { - return checkTreeConsistency1(n, 0) -} - -func checkTreeConsistency1(n *Node, depth int) error { - if depth == 1e4 { - return fmt.Errorf("html: tree looks like it contains a cycle") - } - if err := checkNodeConsistency(n); err != nil { - return err - } - for c := n.FirstChild; c != nil; c = c.NextSibling { - if err := checkTreeConsistency1(c, depth+1); err != nil { - return err - } - } - return nil -} - -// checkNodeConsistency checks that a node's parent/child/sibling relationships -// are consistent. -func checkNodeConsistency(n *Node) error { - if n == nil { - return nil - } - - nParent := 0 - for p := n.Parent; p != nil; p = p.Parent { - nParent++ - if nParent == 1e4 { - return fmt.Errorf("html: parent list looks like an infinite loop") - } - } - - nForward := 0 - for c := n.FirstChild; c != nil; c = c.NextSibling { - nForward++ - if nForward == 1e6 { - return fmt.Errorf("html: forward list of children looks like an infinite loop") - } - if c.Parent != n { - return fmt.Errorf("html: inconsistent child/parent relationship") - } - } - - nBackward := 0 - for c := n.LastChild; c != nil; c = c.PrevSibling { - nBackward++ - if nBackward == 1e6 { - return fmt.Errorf("html: backward list of children looks like an infinite loop") - } - if c.Parent != n { - return fmt.Errorf("html: inconsistent child/parent relationship") - } - } - - if n.Parent != nil { - if n.Parent == n { - return fmt.Errorf("html: inconsistent parent relationship") - } - if n.Parent == n.FirstChild { - return fmt.Errorf("html: inconsistent parent/first relationship") - } - if n.Parent == n.LastChild { - return fmt.Errorf("html: inconsistent parent/last relationship") - } - if n.Parent == n.PrevSibling { - return fmt.Errorf("html: inconsistent parent/prev relationship") - } - if n.Parent == n.NextSibling { - return fmt.Errorf("html: inconsistent parent/next relationship") - } - - parentHasNAsAChild := false - for c := n.Parent.FirstChild; c != nil; c = c.NextSibling { - if c == n { - parentHasNAsAChild = true - break - } - } - if !parentHasNAsAChild { - return fmt.Errorf("html: inconsistent parent/child relationship") - } - } - - if n.PrevSibling != nil && n.PrevSibling.NextSibling != n { - return fmt.Errorf("html: inconsistent prev/next relationship") - } - if n.NextSibling != nil && n.NextSibling.PrevSibling != n { - return fmt.Errorf("html: inconsistent next/prev relationship") - } - - if (n.FirstChild == nil) != (n.LastChild == nil) { - return fmt.Errorf("html: inconsistent first/last relationship") - } - if n.FirstChild != nil && n.FirstChild == n.LastChild { - // We have a sole child. - if n.FirstChild.PrevSibling != nil || n.FirstChild.NextSibling != nil { - return fmt.Errorf("html: inconsistent sole child's sibling relationship") - } - } - - seen := map[*Node]bool{} - - var last *Node - for c := n.FirstChild; c != nil; c = c.NextSibling { - if seen[c] { - return fmt.Errorf("html: inconsistent repeated child") - } - seen[c] = true - last = c - } - if last != n.LastChild { - return fmt.Errorf("html: inconsistent last relationship") - } - - var first *Node - for c := n.LastChild; c != nil; c = c.PrevSibling { - if !seen[c] { - return fmt.Errorf("html: inconsistent missing child") - } - delete(seen, c) - first = c - } - if first != n.FirstChild { - return fmt.Errorf("html: inconsistent first relationship") - } - - if len(seen) != 0 { - return fmt.Errorf("html: inconsistent forwards/backwards child list") - } - - return nil -} diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/parse.go gcc-4.8.1/libgo/go/exp/html/parse.go --- gcc-4.8.1.orig/libgo/go/exp/html/parse.go 2012-11-21 01:03:38.000000000 -0600 +++ gcc-4.8.1/libgo/go/exp/html/parse.go 1969-12-31 18:00:00.000000000 -0600 @@ -1,2091 +0,0 @@ -// Copyright 2010 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 html - -import ( - "errors" - a "exp/html/atom" - "fmt" - "io" - "strings" -) - -// A parser implements the HTML5 parsing algorithm: -// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#tree-construction -type parser struct { - // tokenizer provides the tokens for the parser. - tokenizer *Tokenizer - // tok is the most recently read token. - tok Token - // Self-closing tags like
are treated as start tags, except that - // hasSelfClosingToken is set while they are being processed. - hasSelfClosingToken bool - // doc is the document root element. - doc *Node - // The stack of open elements (section 12.2.3.2) and active formatting - // elements (section 12.2.3.3). - oe, afe nodeStack - // Element pointers (section 12.2.3.4). - head, form *Node - // Other parsing state flags (section 12.2.3.5). - scripting, framesetOK bool - // im is the current insertion mode. - im insertionMode - // originalIM is the insertion mode to go back to after completing a text - // or inTableText insertion mode. - originalIM insertionMode - // fosterParenting is whether new elements should be inserted according to - // the foster parenting rules (section 12.2.5.3). - fosterParenting bool - // quirks is whether the parser is operating in "quirks mode." - quirks bool - // fragment is whether the parser is parsing an HTML fragment. - fragment bool - // context is the context element when parsing an HTML fragment - // (section 12.4). - context *Node -} - -func (p *parser) top() *Node { - if n := p.oe.top(); n != nil { - return n - } - return p.doc -} - -// Stop tags for use in popUntil. These come from section 12.2.3.2. -var ( - defaultScopeStopTags = map[string][]a.Atom{ - "": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object}, - "math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext}, - "svg": {a.Desc, a.ForeignObject, a.Title}, - } -) - -type scope int - -const ( - defaultScope scope = iota - listItemScope - buttonScope - tableScope - tableRowScope - tableBodyScope - selectScope -) - -// popUntil pops the stack of open elements at the highest element whose tag -// is in matchTags, provided there is no higher element in the scope's stop -// tags (as defined in section 12.2.3.2). It returns whether or not there was -// such an element. If there was not, popUntil leaves the stack unchanged. -// -// For example, the set of stop tags for table scope is: "html", "table". If -// the stack was: -// ["html", "body", "font", "table", "b", "i", "u"] -// then popUntil(tableScope, "font") would return false, but -// popUntil(tableScope, "i") would return true and the stack would become: -// ["html", "body", "font", "table", "b"] -// -// If an element's tag is in both the stop tags and matchTags, then the stack -// will be popped and the function returns true (provided, of course, there was -// no higher element in the stack that was also in the stop tags). For example, -// popUntil(tableScope, "table") returns true and leaves: -// ["html", "body", "font"] -func (p *parser) popUntil(s scope, matchTags ...a.Atom) bool { - if i := p.indexOfElementInScope(s, matchTags...); i != -1 { - p.oe = p.oe[:i] - return true - } - return false -} - -// indexOfElementInScope returns the index in p.oe of the highest element whose -// tag is in matchTags that is in scope. If no matching element is in scope, it -// returns -1. -func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int { - for i := len(p.oe) - 1; i >= 0; i-- { - tagAtom := p.oe[i].DataAtom - if p.oe[i].Namespace == "" { - for _, t := range matchTags { - if t == tagAtom { - return i - } - } - switch s { - case defaultScope: - // No-op. - case listItemScope: - if tagAtom == a.Ol || tagAtom == a.Ul { - return -1 - } - case buttonScope: - if tagAtom == a.Button { - return -1 - } - case tableScope: - if tagAtom == a.Html || tagAtom == a.Table { - return -1 - } - case selectScope: - if tagAtom != a.Optgroup && tagAtom != a.Option { - return -1 - } - default: - panic("unreachable") - } - } - switch s { - case defaultScope, listItemScope, buttonScope: - for _, t := range defaultScopeStopTags[p.oe[i].Namespace] { - if t == tagAtom { - return -1 - } - } - } - } - return -1 -} - -// elementInScope is like popUntil, except that it doesn't modify the stack of -// open elements. -func (p *parser) elementInScope(s scope, matchTags ...a.Atom) bool { - return p.indexOfElementInScope(s, matchTags...) != -1 -} - -// clearStackToContext pops elements off the stack of open elements until a -// scope-defined element is found. -func (p *parser) clearStackToContext(s scope) { - for i := len(p.oe) - 1; i >= 0; i-- { - tagAtom := p.oe[i].DataAtom - switch s { - case tableScope: - if tagAtom == a.Html || tagAtom == a.Table { - p.oe = p.oe[:i+1] - return - } - case tableRowScope: - if tagAtom == a.Html || tagAtom == a.Tr { - p.oe = p.oe[:i+1] - return - } - case tableBodyScope: - if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead { - p.oe = p.oe[:i+1] - return - } - default: - panic("unreachable") - } - } -} - -// generateImpliedEndTags pops nodes off the stack of open elements as long as -// the top node has a tag name of dd, dt, li, option, optgroup, p, rp, or rt. -// If exceptions are specified, nodes with that name will not be popped off. -func (p *parser) generateImpliedEndTags(exceptions ...string) { - var i int -loop: - for i = len(p.oe) - 1; i >= 0; i-- { - n := p.oe[i] - if n.Type == ElementNode { - switch n.DataAtom { - case a.Dd, a.Dt, a.Li, a.Option, a.Optgroup, a.P, a.Rp, a.Rt: - for _, except := range exceptions { - if n.Data == except { - break loop - } - } - continue - } - } - break - } - - p.oe = p.oe[:i+1] -} - -// addChild adds a child node n to the top element, and pushes n onto the stack -// of open elements if it is an element node. -func (p *parser) addChild(n *Node) { - if p.shouldFosterParent() { - p.fosterParent(n) - } else { - p.top().AppendChild(n) - } - - if n.Type == ElementNode { - p.oe = append(p.oe, n) - } -} - -// shouldFosterParent returns whether the next node to be added should be -// foster parented. -func (p *parser) shouldFosterParent() bool { - if p.fosterParenting { - switch p.top().DataAtom { - case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr: - return true - } - } - return false -} - -// fosterParent adds a child node according to the foster parenting rules. -// Section 12.2.5.3, "foster parenting". -func (p *parser) fosterParent(n *Node) { - var table, parent, prev *Node - var i int - for i = len(p.oe) - 1; i >= 0; i-- { - if p.oe[i].DataAtom == a.Table { - table = p.oe[i] - break - } - } - - if table == nil { - // The foster parent is the html element. - parent = p.oe[0] - } else { - parent = table.Parent - } - if parent == nil { - parent = p.oe[i-1] - } - - if table != nil { - prev = table.PrevSibling - } else { - prev = parent.LastChild - } - if prev != nil && prev.Type == TextNode && n.Type == TextNode { - prev.Data += n.Data - return - } - - parent.InsertBefore(n, table) -} - -// addText adds text to the preceding node if it is a text node, or else it -// calls addChild with a new text node. -func (p *parser) addText(text string) { - if text == "" { - return - } - - if p.shouldFosterParent() { - p.fosterParent(&Node{ - Type: TextNode, - Data: text, - }) - return - } - - t := p.top() - if n := t.LastChild; n != nil && n.Type == TextNode { - n.Data += text - return - } - p.addChild(&Node{ - Type: TextNode, - Data: text, - }) -} - -// addElement adds a child element based on the current token. -func (p *parser) addElement() { - p.addChild(&Node{ - Type: ElementNode, - DataAtom: p.tok.DataAtom, - Data: p.tok.Data, - Attr: p.tok.Attr, - }) -} - -// Section 12.2.3.3. -func (p *parser) addFormattingElement() { - tagAtom, attr := p.tok.DataAtom, p.tok.Attr - p.addElement() - - // Implement the Noah's Ark clause, but with three per family instead of two. - identicalElements := 0 -findIdenticalElements: - for i := len(p.afe) - 1; i >= 0; i-- { - n := p.afe[i] - if n.Type == scopeMarkerNode { - break - } - if n.Type != ElementNode { - continue - } - if n.Namespace != "" { - continue - } - if n.DataAtom != tagAtom { - continue - } - if len(n.Attr) != len(attr) { - continue - } - compareAttributes: - for _, t0 := range n.Attr { - for _, t1 := range attr { - if t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val { - // Found a match for this attribute, continue with the next attribute. - continue compareAttributes - } - } - // If we get here, there is no attribute that matches a. - // Therefore the element is not identical to the new one. - continue findIdenticalElements - } - - identicalElements++ - if identicalElements >= 3 { - p.afe.remove(n) - } - } - - p.afe = append(p.afe, p.top()) -} - -// Section 12.2.3.3. -func (p *parser) clearActiveFormattingElements() { - for { - n := p.afe.pop() - if len(p.afe) == 0 || n.Type == scopeMarkerNode { - return - } - } -} - -// Section 12.2.3.3. -func (p *parser) reconstructActiveFormattingElements() { - n := p.afe.top() - if n == nil { - return - } - if n.Type == scopeMarkerNode || p.oe.index(n) != -1 { - return - } - i := len(p.afe) - 1 - for n.Type != scopeMarkerNode && p.oe.index(n) == -1 { - if i == 0 { - i = -1 - break - } - i-- - n = p.afe[i] - } - for { - i++ - clone := p.afe[i].clone() - p.addChild(clone) - p.afe[i] = clone - if i == len(p.afe)-1 { - break - } - } -} - -// Section 12.2.4. -func (p *parser) acknowledgeSelfClosingTag() { - p.hasSelfClosingToken = false -} - -// An insertion mode (section 12.2.3.1) is the state transition function from -// a particular state in the HTML5 parser's state machine. It updates the -// parser's fields depending on parser.tok (where ErrorToken means EOF). -// It returns whether the token was consumed. -type insertionMode func(*parser) bool - -// setOriginalIM sets the insertion mode to return to after completing a text or -// inTableText insertion mode. -// Section 12.2.3.1, "using the rules for". -func (p *parser) setOriginalIM() { - if p.originalIM != nil { - panic("html: bad parser state: originalIM was set twice") - } - p.originalIM = p.im -} - -// Section 12.2.3.1, "reset the insertion mode". -func (p *parser) resetInsertionMode() { - for i := len(p.oe) - 1; i >= 0; i-- { - n := p.oe[i] - if i == 0 && p.context != nil { - n = p.context - } - - switch n.DataAtom { - case a.Select: - p.im = inSelectIM - case a.Td, a.Th: - p.im = inCellIM - case a.Tr: - p.im = inRowIM - case a.Tbody, a.Thead, a.Tfoot: - p.im = inTableBodyIM - case a.Caption: - p.im = inCaptionIM - case a.Colgroup: - p.im = inColumnGroupIM - case a.Table: - p.im = inTableIM - case a.Head: - p.im = inBodyIM - case a.Body: - p.im = inBodyIM - case a.Frameset: - p.im = inFramesetIM - case a.Html: - p.im = beforeHeadIM - default: - continue - } - return - } - p.im = inBodyIM -} - -const whitespace = " \t\r\n\f" - -// Section 12.2.5.4.1. -func initialIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) - if len(p.tok.Data) == 0 { - // It was all whitespace, so ignore it. - return true - } - case CommentToken: - p.doc.AppendChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - n, quirks := parseDoctype(p.tok.Data) - p.doc.AppendChild(n) - p.quirks = quirks - p.im = beforeHTMLIM - return true - } - p.quirks = true - p.im = beforeHTMLIM - return false -} - -// Section 12.2.5.4.2. -func beforeHTMLIM(p *parser) bool { - switch p.tok.Type { - case DoctypeToken: - // Ignore the token. - return true - case TextToken: - p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) - if len(p.tok.Data) == 0 { - // It was all whitespace, so ignore it. - return true - } - case StartTagToken: - if p.tok.DataAtom == a.Html { - p.addElement() - p.im = beforeHeadIM - return true - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Head, a.Body, a.Html, a.Br: - p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) - return false - default: - // Ignore the token. - return true - } - case CommentToken: - p.doc.AppendChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - } - p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) - return false -} - -// Section 12.2.5.4.3. -func beforeHeadIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) - if len(p.tok.Data) == 0 { - // It was all whitespace, so ignore it. - return true - } - case StartTagToken: - switch p.tok.DataAtom { - case a.Head: - p.addElement() - p.head = p.top() - p.im = inHeadIM - return true - case a.Html: - return inBodyIM(p) - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Head, a.Body, a.Html, a.Br: - p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) - return false - default: - // Ignore the token. - return true - } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - // Ignore the token. - return true - } - - p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) - return false -} - -// Section 12.2.5.4.4. -func inHeadIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - s := strings.TrimLeft(p.tok.Data, whitespace) - if len(s) < len(p.tok.Data) { - // Add the initial whitespace to the current node. - p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) - if s == "" { - return true - } - p.tok.Data = s - } - case StartTagToken: - switch p.tok.DataAtom { - case a.Html: - return inBodyIM(p) - case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta: - p.addElement() - p.oe.pop() - p.acknowledgeSelfClosingTag() - return true - case a.Script, a.Title, a.Noscript, a.Noframes, a.Style: - p.addElement() - p.setOriginalIM() - p.im = textIM - return true - case a.Head: - // Ignore the token. - return true - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Head: - n := p.oe.pop() - if n.DataAtom != a.Head { - panic("html: bad parser state: element not found, in the in-head insertion mode") - } - p.im = afterHeadIM - return true - case a.Body, a.Html, a.Br: - p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) - return false - default: - // Ignore the token. - return true - } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - // Ignore the token. - return true - } - - p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) - return false -} - -// Section 12.2.5.4.6. -func afterHeadIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - s := strings.TrimLeft(p.tok.Data, whitespace) - if len(s) < len(p.tok.Data) { - // Add the initial whitespace to the current node. - p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) - if s == "" { - return true - } - p.tok.Data = s - } - case StartTagToken: - switch p.tok.DataAtom { - case a.Html: - return inBodyIM(p) - case a.Body: - p.addElement() - p.framesetOK = false - p.im = inBodyIM - return true - case a.Frameset: - p.addElement() - p.im = inFramesetIM - return true - case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title: - p.oe = append(p.oe, p.head) - defer p.oe.remove(p.head) - return inHeadIM(p) - case a.Head: - // Ignore the token. - return true - } - case EndTagToken: - switch p.tok.DataAtom { - case a.Body, a.Html, a.Br: - // Drop down to creating an implied tag. - default: - // Ignore the token. - return true - } - case CommentToken: - p.addChild(&Node{ - Type: CommentNode, - Data: p.tok.Data, - }) - return true - case DoctypeToken: - // Ignore the token. - return true - } - - p.parseImpliedToken(StartTagToken, a.Body, a.Body.String()) - p.framesetOK = true - return false -} - -// copyAttributes copies attributes of src not found on dst to dst. -func copyAttributes(dst *Node, src Token) { - if len(src.Attr) == 0 { - return - } - attr := map[string]string{} - for _, t := range dst.Attr { - attr[t.Key] = t.Val - } - for _, t := range src.Attr { - if _, ok := attr[t.Key]; !ok { - dst.Attr = append(dst.Attr, t) - attr[t.Key] = t.Val - } - } -} - -// Section 12.2.5.4.7. -func inBodyIM(p *parser) bool { - switch p.tok.Type { - case TextToken: - d := p.tok.Data - switch n := p.oe.top(); n.DataAtom { - case a.Pre, a.Listing: - if n.FirstChild == nil { - // Ignore a newline at the start of a
 block.
-				if d != "" && d[0] == '\r' {
-					d = d[1:]
-				}
-				if d != "" && d[0] == '\n' {
-					d = d[1:]
-				}
-			}
-		}
-		d = strings.Replace(d, "\x00", "", -1)
-		if d == "" {
-			return true
-		}
-		p.reconstructActiveFormattingElements()
-		p.addText(d)
-		if p.framesetOK && strings.TrimLeft(d, whitespace) != "" {
-			// There were non-whitespace characters inserted.
-			p.framesetOK = false
-		}
-	case StartTagToken:
-		switch p.tok.DataAtom {
-		case a.Html:
-			copyAttributes(p.oe[0], p.tok)
-		case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
-			return inHeadIM(p)
-		case a.Body:
-			if len(p.oe) >= 2 {
-				body := p.oe[1]
-				if body.Type == ElementNode && body.DataAtom == a.Body {
-					p.framesetOK = false
-					copyAttributes(body, p.tok)
-				}
-			}
-		case a.Frameset:
-			if !p.framesetOK || len(p.oe) < 2 || p.oe[1].DataAtom != a.Body {
-				// Ignore the token.
-				return true
-			}
-			body := p.oe[1]
-			if body.Parent != nil {
-				body.Parent.RemoveChild(body)
-			}
-			p.oe = p.oe[:1]
-			p.addElement()
-			p.im = inFramesetIM
-			return true
-		case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
-			p.popUntil(buttonScope, a.P)
-			switch n := p.top(); n.DataAtom {
-			case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
-				p.oe.pop()
-			}
-			p.addElement()
-		case a.Pre, a.Listing:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-			// The newline, if any, will be dealt with by the TextToken case.
-			p.framesetOK = false
-		case a.Form:
-			if p.form == nil {
-				p.popUntil(buttonScope, a.P)
-				p.addElement()
-				p.form = p.top()
-			}
-		case a.Li:
-			p.framesetOK = false
-			for i := len(p.oe) - 1; i >= 0; i-- {
-				node := p.oe[i]
-				switch node.DataAtom {
-				case a.Li:
-					p.oe = p.oe[:i]
-				case a.Address, a.Div, a.P:
-					continue
-				default:
-					if !isSpecialElement(node) {
-						continue
-					}
-				}
-				break
-			}
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.Dd, a.Dt:
-			p.framesetOK = false
-			for i := len(p.oe) - 1; i >= 0; i-- {
-				node := p.oe[i]
-				switch node.DataAtom {
-				case a.Dd, a.Dt:
-					p.oe = p.oe[:i]
-				case a.Address, a.Div, a.P:
-					continue
-				default:
-					if !isSpecialElement(node) {
-						continue
-					}
-				}
-				break
-			}
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.Plaintext:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-		case a.Button:
-			p.popUntil(defaultScope, a.Button)
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.framesetOK = false
-		case a.A:
-			for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {
-				if n := p.afe[i]; n.Type == ElementNode && n.DataAtom == a.A {
-					p.inBodyEndTagFormatting(a.A)
-					p.oe.remove(n)
-					p.afe.remove(n)
-					break
-				}
-			}
-			p.reconstructActiveFormattingElements()
-			p.addFormattingElement()
-		case a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
-			p.reconstructActiveFormattingElements()
-			p.addFormattingElement()
-		case a.Nobr:
-			p.reconstructActiveFormattingElements()
-			if p.elementInScope(defaultScope, a.Nobr) {
-				p.inBodyEndTagFormatting(a.Nobr)
-				p.reconstructActiveFormattingElements()
-			}
-			p.addFormattingElement()
-		case a.Applet, a.Marquee, a.Object:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.afe = append(p.afe, &scopeMarker)
-			p.framesetOK = false
-		case a.Table:
-			if !p.quirks {
-				p.popUntil(buttonScope, a.P)
-			}
-			p.addElement()
-			p.framesetOK = false
-			p.im = inTableIM
-			return true
-		case a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.oe.pop()
-			p.acknowledgeSelfClosingTag()
-			if p.tok.DataAtom == a.Input {
-				for _, t := range p.tok.Attr {
-					if t.Key == "type" {
-						if strings.ToLower(t.Val) == "hidden" {
-							// Skip setting framesetOK = false
-							return true
-						}
-					}
-				}
-			}
-			p.framesetOK = false
-		case a.Param, a.Source, a.Track:
-			p.addElement()
-			p.oe.pop()
-			p.acknowledgeSelfClosingTag()
-		case a.Hr:
-			p.popUntil(buttonScope, a.P)
-			p.addElement()
-			p.oe.pop()
-			p.acknowledgeSelfClosingTag()
-			p.framesetOK = false
-		case a.Image:
-			p.tok.DataAtom = a.Img
-			p.tok.Data = a.Img.String()
-			return false
-		case a.Isindex:
-			if p.form != nil {
-				// Ignore the token.
-				return true
-			}
-			action := ""
-			prompt := "This is a searchable index. Enter search keywords: "
-			attr := []Attribute{{Key: "name", Val: "isindex"}}
-			for _, t := range p.tok.Attr {
-				switch t.Key {
-				case "action":
-					action = t.Val
-				case "name":
-					// Ignore the attribute.
-				case "prompt":
-					prompt = t.Val
-				default:
-					attr = append(attr, t)
-				}
-			}
-			p.acknowledgeSelfClosingTag()
-			p.popUntil(buttonScope, a.P)
-			p.parseImpliedToken(StartTagToken, a.Form, a.Form.String())
-			if action != "" {
-				p.form.Attr = []Attribute{{Key: "action", Val: action}}
-			}
-			p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
-			p.parseImpliedToken(StartTagToken, a.Label, a.Label.String())
-			p.addText(prompt)
-			p.addChild(&Node{
-				Type:     ElementNode,
-				DataAtom: a.Input,
-				Data:     a.Input.String(),
-				Attr:     attr,
-			})
-			p.oe.pop()
-			p.parseImpliedToken(EndTagToken, a.Label, a.Label.String())
-			p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
-			p.parseImpliedToken(EndTagToken, a.Form, a.Form.String())
-		case a.Textarea:
-			p.addElement()
-			p.setOriginalIM()
-			p.framesetOK = false
-			p.im = textIM
-		case a.Xmp:
-			p.popUntil(buttonScope, a.P)
-			p.reconstructActiveFormattingElements()
-			p.framesetOK = false
-			p.addElement()
-			p.setOriginalIM()
-			p.im = textIM
-		case a.Iframe:
-			p.framesetOK = false
-			p.addElement()
-			p.setOriginalIM()
-			p.im = textIM
-		case a.Noembed, a.Noscript:
-			p.addElement()
-			p.setOriginalIM()
-			p.im = textIM
-		case a.Select:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-			p.framesetOK = false
-			p.im = inSelectIM
-			return true
-		case a.Optgroup, a.Option:
-			if p.top().DataAtom == a.Option {
-				p.oe.pop()
-			}
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-		case a.Rp, a.Rt:
-			if p.elementInScope(defaultScope, a.Ruby) {
-				p.generateImpliedEndTags()
-			}
-			p.addElement()
-		case a.Math, a.Svg:
-			p.reconstructActiveFormattingElements()
-			if p.tok.DataAtom == a.Math {
-				adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
-			} else {
-				adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)
-			}
-			adjustForeignAttributes(p.tok.Attr)
-			p.addElement()
-			p.top().Namespace = p.tok.Data
-			if p.hasSelfClosingToken {
-				p.oe.pop()
-				p.acknowledgeSelfClosingTag()
-			}
-			return true
-		case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
-			// Ignore the token.
-		default:
-			p.reconstructActiveFormattingElements()
-			p.addElement()
-		}
-	case EndTagToken:
-		switch p.tok.DataAtom {
-		case a.Body:
-			if p.elementInScope(defaultScope, a.Body) {
-				p.im = afterBodyIM
-			}
-		case a.Html:
-			if p.elementInScope(defaultScope, a.Body) {
-				p.parseImpliedToken(EndTagToken, a.Body, a.Body.String())
-				return false
-			}
-			return true
-		case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
-			p.popUntil(defaultScope, p.tok.DataAtom)
-		case a.Form:
-			node := p.form
-			p.form = nil
-			i := p.indexOfElementInScope(defaultScope, a.Form)
-			if node == nil || i == -1 || p.oe[i] != node {
-				// Ignore the token.
-				return true
-			}
-			p.generateImpliedEndTags()
-			p.oe.remove(node)
-		case a.P:
-			if !p.elementInScope(buttonScope, a.P) {
-				p.parseImpliedToken(StartTagToken, a.P, a.P.String())
-			}
-			p.popUntil(buttonScope, a.P)
-		case a.Li:
-			p.popUntil(listItemScope, a.Li)
-		case a.Dd, a.Dt:
-			p.popUntil(defaultScope, p.tok.DataAtom)
-		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
-			p.popUntil(defaultScope, a.H1, a.H2, a.H3, a.H4, a.H5, a.H6)
-		case a.A, a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.Nobr, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
-			p.inBodyEndTagFormatting(p.tok.DataAtom)
-		case a.Applet, a.Marquee, a.Object:
-			if p.popUntil(defaultScope, p.tok.DataAtom) {
-				p.clearActiveFormattingElements()
-			}
-		case a.Br:
-			p.tok.Type = StartTagToken
-			return false
-		default:
-			p.inBodyEndTagOther(p.tok.DataAtom)
-		}
-	case CommentToken:
-		p.addChild(&Node{
-			Type: CommentNode,
-			Data: p.tok.Data,
-		})
-	}
-
-	return true
-}
-
-func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
-	// This is the "adoption agency" algorithm, described at
-	// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#adoptionAgency
-
-	// TODO: this is a fairly literal line-by-line translation of that algorithm.
-	// Once the code successfully parses the comprehensive test suite, we should
-	// refactor this code to be more idiomatic.
-
-	// Steps 1-3. The outer loop.
-	for i := 0; i < 8; i++ {
-		// Step 4. Find the formatting element.
-		var formattingElement *Node
-		for j := len(p.afe) - 1; j >= 0; j-- {
-			if p.afe[j].Type == scopeMarkerNode {
-				break
-			}
-			if p.afe[j].DataAtom == tagAtom {
-				formattingElement = p.afe[j]
-				break
-			}
-		}
-		if formattingElement == nil {
-			p.inBodyEndTagOther(tagAtom)
-			return
-		}
-		feIndex := p.oe.index(formattingElement)
-		if feIndex == -1 {
-			p.afe.remove(formattingElement)
-			return
-		}
-		if !p.elementInScope(defaultScope, tagAtom) {
-			// Ignore the tag.
-			return
-		}
-
-		// Steps 5-6. Find the furthest block.
-		var furthestBlock *Node
-		for _, e := range p.oe[feIndex:] {
-			if isSpecialElement(e) {
-				furthestBlock = e
-				break
-			}
-		}
-		if furthestBlock == nil {
-			e := p.oe.pop()
-			for e != formattingElement {
-				e = p.oe.pop()
-			}
-			p.afe.remove(e)
-			return
-		}
-
-		// Steps 7-8. Find the common ancestor and bookmark node.
-		commonAncestor := p.oe[feIndex-1]
-		bookmark := p.afe.index(formattingElement)
-
-		// Step 9. The inner loop. Find the lastNode to reparent.
-		lastNode := furthestBlock
-		node := furthestBlock
-		x := p.oe.index(node)
-		// Steps 9.1-9.3.
-		for j := 0; j < 3; j++ {
-			// Step 9.4.
-			x--
-			node = p.oe[x]
-			// Step 9.5.
-			if p.afe.index(node) == -1 {
-				p.oe.remove(node)
-				continue
-			}
-			// Step 9.6.
-			if node == formattingElement {
-				break
-			}
-			// Step 9.7.
-			clone := node.clone()
-			p.afe[p.afe.index(node)] = clone
-			p.oe[p.oe.index(node)] = clone
-			node = clone
-			// Step 9.8.
-			if lastNode == furthestBlock {
-				bookmark = p.afe.index(node) + 1
-			}
-			// Step 9.9.
-			if lastNode.Parent != nil {
-				lastNode.Parent.RemoveChild(lastNode)
-			}
-			node.AppendChild(lastNode)
-			// Step 9.10.
-			lastNode = node
-		}
-
-		// Step 10. Reparent lastNode to the common ancestor,
-		// or for misnested table nodes, to the foster parent.
-		if lastNode.Parent != nil {
-			lastNode.Parent.RemoveChild(lastNode)
-		}
-		switch commonAncestor.DataAtom {
-		case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
-			p.fosterParent(lastNode)
-		default:
-			commonAncestor.AppendChild(lastNode)
-		}
-
-		// Steps 11-13. Reparent nodes from the furthest block's children
-		// to a clone of the formatting element.
-		clone := formattingElement.clone()
-		reparentChildren(clone, furthestBlock)
-		furthestBlock.AppendChild(clone)
-
-		// Step 14. Fix up the list of active formatting elements.
-		if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
-			// Move the bookmark with the rest of the list.
-			bookmark--
-		}
-		p.afe.remove(formattingElement)
-		p.afe.insert(bookmark, clone)
-
-		// Step 15. Fix up the stack of open elements.
-		p.oe.remove(formattingElement)
-		p.oe.insert(p.oe.index(furthestBlock)+1, clone)
-	}
-}
-
-// inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM.
-func (p *parser) inBodyEndTagOther(tagAtom a.Atom) {
-	for i := len(p.oe) - 1; i >= 0; i-- {
-		if p.oe[i].DataAtom == tagAtom {
-			p.oe = p.oe[:i]
-			break
-		}
-		if isSpecialElement(p.oe[i]) {
-			break
-		}
-	}
-}
-
-// Section 12.2.5.4.8.
-func textIM(p *parser) bool {
-	switch p.tok.Type {
-	case ErrorToken:
-		p.oe.pop()
-	case TextToken:
-		d := p.tok.Data
-		if n := p.oe.top(); n.DataAtom == a.Textarea && n.FirstChild == nil {
-			// Ignore a newline at the start of a -->
-#errors
-#document
-| 
-|   
-|   
-|     -->
-#errors
-#document
-| 
-|   
-|   
-|     -->
-#errors
-Line: 1 Col: 64 Unexpected end tag (textarea).
-#document
-| 
-| 
-|   
-|   
-|     
-#errors
-#document
-| 
-| 
-|   
-|   
-|     "
-
-#data
-
-#errors
-#document
-| 
-| 
-|   
-|   
-|     
-#errors
-#document
-| 
-| 
-|   
-|   
-|     -->
-#errors
-Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
-Line: 1 Col: 49 Unexpected end tag (textarea).
-#document
-| 
-|   
-|   
-|     
-#errors
-Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
-#document
-| 
-|   
-|   
-|     "
-
-#data
--->
-#errors
-Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE.
-Line: 1 Col: 41 Unexpected end tag (iframe).
-#document
-| 
-|   
-|   
-|     
-#errors
-Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE.
-#document
-| 
-|   
-|   
-|     
-#errors
-#document
-| 
-| 
-|   
-|   
-|     
-#errors
-Line: 1 Col: 9 Unexpected end tag (strong). Expected DOCTYPE.
-Line: 1 Col: 9 Unexpected end tag (strong) after the (implied) root element.
-Line: 1 Col: 13 Unexpected end tag (b) after the (implied) root element.
-Line: 1 Col: 18 Unexpected end tag (em) after the (implied) root element.
-Line: 1 Col: 22 Unexpected end tag (i) after the (implied) root element.
-Line: 1 Col: 26 Unexpected end tag (u) after the (implied) root element.
-Line: 1 Col: 35 Unexpected end tag (strike) after the (implied) root element.
-Line: 1 Col: 39 Unexpected end tag (s) after the (implied) root element.
-Line: 1 Col: 47 Unexpected end tag (blink) after the (implied) root element.
-Line: 1 Col: 52 Unexpected end tag (tt) after the (implied) root element.
-Line: 1 Col: 58 Unexpected end tag (pre) after the (implied) root element.
-Line: 1 Col: 64 Unexpected end tag (big) after the (implied) root element.
-Line: 1 Col: 72 Unexpected end tag (small) after the (implied) root element.
-Line: 1 Col: 79 Unexpected end tag (font) after the (implied) root element.
-Line: 1 Col: 88 Unexpected end tag (select) after the (implied) root element.
-Line: 1 Col: 93 Unexpected end tag (h1) after the (implied) root element.
-Line: 1 Col: 98 Unexpected end tag (h2) after the (implied) root element.
-Line: 1 Col: 103 Unexpected end tag (h3) after the (implied) root element.
-Line: 1 Col: 108 Unexpected end tag (h4) after the (implied) root element.
-Line: 1 Col: 113 Unexpected end tag (h5) after the (implied) root element.
-Line: 1 Col: 118 Unexpected end tag (h6) after the (implied) root element.
-Line: 1 Col: 125 Unexpected end tag (body) after the (implied) root element.
-Line: 1 Col: 130 Unexpected end tag (br). Treated as br element.
-Line: 1 Col: 134 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm.
-Line: 1 Col: 140 This element (img) has no end tag.
-Line: 1 Col: 148 Unexpected end tag (title). Ignored.
-Line: 1 Col: 155 Unexpected end tag (span). Ignored.
-Line: 1 Col: 163 Unexpected end tag (style). Ignored.
-Line: 1 Col: 172 Unexpected end tag (script). Ignored.
-Line: 1 Col: 180 Unexpected end tag (table). Ignored.
-Line: 1 Col: 185 Unexpected end tag (th). Ignored.
-Line: 1 Col: 190 Unexpected end tag (td). Ignored.
-Line: 1 Col: 195 Unexpected end tag (tr). Ignored.
-Line: 1 Col: 203 This element (frame) has no end tag.
-Line: 1 Col: 210 This element (area) has no end tag.
-Line: 1 Col: 217 Unexpected end tag (link). Ignored.
-Line: 1 Col: 225 This element (param) has no end tag.
-Line: 1 Col: 230 This element (hr) has no end tag.
-Line: 1 Col: 238 This element (input) has no end tag.
-Line: 1 Col: 244 Unexpected end tag (col). Ignored.
-Line: 1 Col: 251 Unexpected end tag (base). Ignored.
-Line: 1 Col: 258 Unexpected end tag (meta). Ignored.
-Line: 1 Col: 269 This element (basefont) has no end tag.
-Line: 1 Col: 279 This element (bgsound) has no end tag.
-Line: 1 Col: 287 This element (embed) has no end tag.
-Line: 1 Col: 296 This element (spacer) has no end tag.
-Line: 1 Col: 300 Unexpected end tag (p). Ignored.
-Line: 1 Col: 305 End tag (dd) seen too early. Expected other end tag.
-Line: 1 Col: 310 End tag (dt) seen too early. Expected other end tag.
-Line: 1 Col: 320 Unexpected end tag (caption). Ignored.
-Line: 1 Col: 331 Unexpected end tag (colgroup). Ignored.
-Line: 1 Col: 339 Unexpected end tag (tbody). Ignored.
-Line: 1 Col: 347 Unexpected end tag (tfoot). Ignored.
-Line: 1 Col: 355 Unexpected end tag (thead). Ignored.
-Line: 1 Col: 365 End tag (address) seen too early. Expected other end tag.
-Line: 1 Col: 378 End tag (blockquote) seen too early. Expected other end tag.
-Line: 1 Col: 387 End tag (center) seen too early. Expected other end tag.
-Line: 1 Col: 393 Unexpected end tag (dir). Ignored.
-Line: 1 Col: 399 End tag (div) seen too early. Expected other end tag.
-Line: 1 Col: 404 End tag (dl) seen too early. Expected other end tag.
-Line: 1 Col: 415 End tag (fieldset) seen too early. Expected other end tag.
-Line: 1 Col: 425 End tag (listing) seen too early. Expected other end tag.
-Line: 1 Col: 432 End tag (menu) seen too early. Expected other end tag.
-Line: 1 Col: 437 End tag (ol) seen too early. Expected other end tag.
-Line: 1 Col: 442 End tag (ul) seen too early. Expected other end tag.
-Line: 1 Col: 447 End tag (li) seen too early. Expected other end tag.
-Line: 1 Col: 454 End tag (nobr) violates step 1, paragraph 1 of the adoption agency algorithm.
-Line: 1 Col: 460 This element (wbr) has no end tag.
-Line: 1 Col: 476 End tag (button) seen too early. Expected other end tag.
-Line: 1 Col: 486 End tag (marquee) seen too early. Expected other end tag.
-Line: 1 Col: 495 End tag (object) seen too early. Expected other end tag.
-Line: 1 Col: 513 Unexpected end tag (html). Ignored.
-Line: 1 Col: 513 Unexpected end tag (frameset). Ignored.
-Line: 1 Col: 520 Unexpected end tag (head). Ignored.
-Line: 1 Col: 529 Unexpected end tag (iframe). Ignored.
-Line: 1 Col: 537 This element (image) has no end tag.
-Line: 1 Col: 547 This element (isindex) has no end tag.
-Line: 1 Col: 557 Unexpected end tag (noembed). Ignored.
-Line: 1 Col: 568 Unexpected end tag (noframes). Ignored.
-Line: 1 Col: 579 Unexpected end tag (noscript). Ignored.
-Line: 1 Col: 590 Unexpected end tag (optgroup). Ignored.
-Line: 1 Col: 599 Unexpected end tag (option). Ignored.
-Line: 1 Col: 611 Unexpected end tag (plaintext). Ignored.
-Line: 1 Col: 622 Unexpected end tag (textarea). Ignored.
-#document
-| 
-|   
-|   
-|     
-|

- -#data -

-#errors -Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE. -Line: 1 Col: 20 Unexpected end tag (strong) in table context caused voodoo mode. -Line: 1 Col: 20 End tag (strong) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 24 Unexpected end tag (b) in table context caused voodoo mode. -Line: 1 Col: 24 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 29 Unexpected end tag (em) in table context caused voodoo mode. -Line: 1 Col: 29 End tag (em) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 33 Unexpected end tag (i) in table context caused voodoo mode. -Line: 1 Col: 33 End tag (i) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 37 Unexpected end tag (u) in table context caused voodoo mode. -Line: 1 Col: 37 End tag (u) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 46 Unexpected end tag (strike) in table context caused voodoo mode. -Line: 1 Col: 46 End tag (strike) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 50 Unexpected end tag (s) in table context caused voodoo mode. -Line: 1 Col: 50 End tag (s) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 58 Unexpected end tag (blink) in table context caused voodoo mode. -Line: 1 Col: 58 Unexpected end tag (blink). Ignored. -Line: 1 Col: 63 Unexpected end tag (tt) in table context caused voodoo mode. -Line: 1 Col: 63 End tag (tt) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 69 Unexpected end tag (pre) in table context caused voodoo mode. -Line: 1 Col: 69 End tag (pre) seen too early. Expected other end tag. -Line: 1 Col: 75 Unexpected end tag (big) in table context caused voodoo mode. -Line: 1 Col: 75 End tag (big) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 83 Unexpected end tag (small) in table context caused voodoo mode. -Line: 1 Col: 83 End tag (small) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 90 Unexpected end tag (font) in table context caused voodoo mode. -Line: 1 Col: 90 End tag (font) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 99 Unexpected end tag (select) in table context caused voodoo mode. -Line: 1 Col: 99 Unexpected end tag (select). Ignored. -Line: 1 Col: 104 Unexpected end tag (h1) in table context caused voodoo mode. -Line: 1 Col: 104 End tag (h1) seen too early. Expected other end tag. -Line: 1 Col: 109 Unexpected end tag (h2) in table context caused voodoo mode. -Line: 1 Col: 109 End tag (h2) seen too early. Expected other end tag. -Line: 1 Col: 114 Unexpected end tag (h3) in table context caused voodoo mode. -Line: 1 Col: 114 End tag (h3) seen too early. Expected other end tag. -Line: 1 Col: 119 Unexpected end tag (h4) in table context caused voodoo mode. -Line: 1 Col: 119 End tag (h4) seen too early. Expected other end tag. -Line: 1 Col: 124 Unexpected end tag (h5) in table context caused voodoo mode. -Line: 1 Col: 124 End tag (h5) seen too early. Expected other end tag. -Line: 1 Col: 129 Unexpected end tag (h6) in table context caused voodoo mode. -Line: 1 Col: 129 End tag (h6) seen too early. Expected other end tag. -Line: 1 Col: 136 Unexpected end tag (body) in the table row phase. Ignored. -Line: 1 Col: 141 Unexpected end tag (br) in table context caused voodoo mode. -Line: 1 Col: 141 Unexpected end tag (br). Treated as br element. -Line: 1 Col: 145 Unexpected end tag (a) in table context caused voodoo mode. -Line: 1 Col: 145 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 151 Unexpected end tag (img) in table context caused voodoo mode. -Line: 1 Col: 151 This element (img) has no end tag. -Line: 1 Col: 159 Unexpected end tag (title) in table context caused voodoo mode. -Line: 1 Col: 159 Unexpected end tag (title). Ignored. -Line: 1 Col: 166 Unexpected end tag (span) in table context caused voodoo mode. -Line: 1 Col: 166 Unexpected end tag (span). Ignored. -Line: 1 Col: 174 Unexpected end tag (style) in table context caused voodoo mode. -Line: 1 Col: 174 Unexpected end tag (style). Ignored. -Line: 1 Col: 183 Unexpected end tag (script) in table context caused voodoo mode. -Line: 1 Col: 183 Unexpected end tag (script). Ignored. -Line: 1 Col: 196 Unexpected end tag (th). Ignored. -Line: 1 Col: 201 Unexpected end tag (td). Ignored. -Line: 1 Col: 206 Unexpected end tag (tr). Ignored. -Line: 1 Col: 214 This element (frame) has no end tag. -Line: 1 Col: 221 This element (area) has no end tag. -Line: 1 Col: 228 Unexpected end tag (link). Ignored. -Line: 1 Col: 236 This element (param) has no end tag. -Line: 1 Col: 241 This element (hr) has no end tag. -Line: 1 Col: 249 This element (input) has no end tag. -Line: 1 Col: 255 Unexpected end tag (col). Ignored. -Line: 1 Col: 262 Unexpected end tag (base). Ignored. -Line: 1 Col: 269 Unexpected end tag (meta). Ignored. -Line: 1 Col: 280 This element (basefont) has no end tag. -Line: 1 Col: 290 This element (bgsound) has no end tag. -Line: 1 Col: 298 This element (embed) has no end tag. -Line: 1 Col: 307 This element (spacer) has no end tag. -Line: 1 Col: 311 Unexpected end tag (p). Ignored. -Line: 1 Col: 316 End tag (dd) seen too early. Expected other end tag. -Line: 1 Col: 321 End tag (dt) seen too early. Expected other end tag. -Line: 1 Col: 331 Unexpected end tag (caption). Ignored. -Line: 1 Col: 342 Unexpected end tag (colgroup). Ignored. -Line: 1 Col: 350 Unexpected end tag (tbody). Ignored. -Line: 1 Col: 358 Unexpected end tag (tfoot). Ignored. -Line: 1 Col: 366 Unexpected end tag (thead). Ignored. -Line: 1 Col: 376 End tag (address) seen too early. Expected other end tag. -Line: 1 Col: 389 End tag (blockquote) seen too early. Expected other end tag. -Line: 1 Col: 398 End tag (center) seen too early. Expected other end tag. -Line: 1 Col: 404 Unexpected end tag (dir). Ignored. -Line: 1 Col: 410 End tag (div) seen too early. Expected other end tag. -Line: 1 Col: 415 End tag (dl) seen too early. Expected other end tag. -Line: 1 Col: 426 End tag (fieldset) seen too early. Expected other end tag. -Line: 1 Col: 436 End tag (listing) seen too early. Expected other end tag. -Line: 1 Col: 443 End tag (menu) seen too early. Expected other end tag. -Line: 1 Col: 448 End tag (ol) seen too early. Expected other end tag. -Line: 1 Col: 453 End tag (ul) seen too early. Expected other end tag. -Line: 1 Col: 458 End tag (li) seen too early. Expected other end tag. -Line: 1 Col: 465 End tag (nobr) violates step 1, paragraph 1 of the adoption agency algorithm. -Line: 1 Col: 471 This element (wbr) has no end tag. -Line: 1 Col: 487 End tag (button) seen too early. Expected other end tag. -Line: 1 Col: 497 End tag (marquee) seen too early. Expected other end tag. -Line: 1 Col: 506 End tag (object) seen too early. Expected other end tag. -Line: 1 Col: 524 Unexpected end tag (html). Ignored. -Line: 1 Col: 524 Unexpected end tag (frameset). Ignored. -Line: 1 Col: 531 Unexpected end tag (head). Ignored. -Line: 1 Col: 540 Unexpected end tag (iframe). Ignored. -Line: 1 Col: 548 This element (image) has no end tag. -Line: 1 Col: 558 This element (isindex) has no end tag. -Line: 1 Col: 568 Unexpected end tag (noembed). Ignored. -Line: 1 Col: 579 Unexpected end tag (noframes). Ignored. -Line: 1 Col: 590 Unexpected end tag (noscript). Ignored. -Line: 1 Col: 601 Unexpected end tag (optgroup). Ignored. -Line: 1 Col: 610 Unexpected end tag (option). Ignored. -Line: 1 Col: 622 Unexpected end tag (plaintext). Ignored. -Line: 1 Col: 633 Unexpected end tag (textarea). Ignored. -#document -| -| -| -|
-| -| -| -|

- -#data - -#errors -Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE. -Line: 1 Col: 10 Expected closing tag. Unexpected end of file. -#document -| -| -| diff -Naur gcc-4.8.1.orig/libgo/go/exp/html/testdata/webkit/tests20.dat gcc-4.8.1/libgo/go/exp/html/testdata/webkit/tests20.dat --- gcc-4.8.1.orig/libgo/go/exp/html/testdata/webkit/tests20.dat 2011-09-21 23:02:11.000000000 -0500 +++ gcc-4.8.1/libgo/go/exp/html/testdata/webkit/tests20.dat 1969-12-31 18:00:00.000000000 -0600 @@ -1,455 +0,0 @@ -#data -