diff options
author | pfg <pfg@FreeBSD.org> | 2013-12-21 18:47:00 +0000 |
---|---|---|
committer | pfg <pfg@FreeBSD.org> | 2013-12-21 18:47:00 +0000 |
commit | 68205669abdad29d13f7e6b34f483ac1298065ed (patch) | |
tree | b0b89f0ab157d77eed267e3b82dd3ee8ed9e980b | |
parent | 8f82fe8c1f4a70975704e71ccca87132e0d9af6c (diff) | |
download | FreeBSD-src-68205669abdad29d13f7e6b34f483ac1298065ed.zip FreeBSD-src-68205669abdad29d13f7e6b34f483ac1298065ed.tar.gz |
MFC r258017, r258429, r258748, r258817:
Merge updates from FSF pre4.3 GCC inspired on Apple's gcc:
Updates to libiberty and mangling.
New align attribute.
Merge Apple updates to libstdc++.
35 files changed, 547 insertions, 244 deletions
diff --git a/contrib/binutils/binutils/cxxfilt.c b/contrib/binutils/binutils/cxxfilt.c index bed0537..a520026 100644 --- a/contrib/binutils/binutils/cxxfilt.c +++ b/contrib/binutils/binutils/cxxfilt.c @@ -63,12 +63,12 @@ demangle_it (char *mangled_name) result = cplus_demangle (mangled_name + skip_first, flags); if (result == NULL) - printf (mangled_name); + printf ("%s",mangled_name); else { if (mangled_name[0] == '.') putchar ('.'); - printf (result); + printf ("%s",result); free (result); } } diff --git a/contrib/gcc/ChangeLog.gcc43 b/contrib/gcc/ChangeLog.gcc43 index cd48024..5c6701a 100644 --- a/contrib/gcc/ChangeLog.gcc43 +++ b/contrib/gcc/ChangeLog.gcc43 @@ -4,6 +4,47 @@ * config/arm/unwind-arm.h (__gnu_Unwind_Backtrace): New. * config/arm/unwind-arm.c (__gnu_Unwind_Backtrace): New. +2007-07-12 Geoffrey Keating <geoffk@apple.com> (r126588) + + * builtins.c (get_pointer_alignment): Honor DECL_ALIGN on a + FUNCTION_DECL. + * tree.c (build_decl_stat): Move code from here... + (make_node_stat): ... to here. Don't uselessly clear DECL_USER_ALIGN. + (expr_align): Honor DECL_ALIGN on a FUNCTION_DECL. Add comment + about using DECL_ALIGN of LABEL_DECL and CONST_DECL. + * tree.h (DECL_USER_ALIGN): Fix misplaced comment. + * varasm.c (assemble_start_function): Use DECL_ALIGN instead of + FUNCTION_BOUNDARY. + +2007-07-09 Geoffrey Keating <geoffk@apple.com> (r126529) + + PR 32617 + * c-common.c (c_alignof_expr): Look at DECL_ALIGN of + FUNCTION_DECLs. + (handle_aligned_attribute): Allow use on FUNCTION_DECLs. + * varasm.c (assemble_start_function): Honor DECL_ALIGN + for FUNCTION_DECLs. Don't use align_functions_log if + DECL_USER_ALIGN. + * print-tree.c (print_node): Print DECL_ALIGN and DECL_USER_ALIGN + even for FUNCTION_DECLs. + * c-decl.c (merge_decls): Propagate DECL_ALIGN even for + FUNCTION_DECLs. + * tree.h (DECL_ALIGN): Update for new location of 'align'. + (DECL_FUNCTION_CODE): Update for new location and name of + 'function_code'. + (DECL_OFFSET_ALIGN): Update for new location of 'off_align'. + (struct tree_decl_common): Move 'align' and 'off_align' out + of union, ensure they're still on a 32-bit boundary. Remove + other fields in union 'u1'. + (struct tree_function_decl): Add field 'function_code' replacing + 'u1.f' in tree_decl_common. + * tree.c (build_decl_stat): Set initial value of DECL_ALIGN. + * doc/extend.texi (Function Attributes): Add 'aligned' attribute. + (Variable Attributes): Cross-reference 'aligned' attribute + to Function Attributes. + * flags.h (force_align_functions_log): Delete. + * toplev.c (force_align_functions_log): Delete. + 2007-06-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de> (r125346) PR preprocessor/23479 @@ -68,7 +109,7 @@ alignment for amdfam10 architecture. Increasing the max loop alignment to 24 bytes. -2007-04-16 Lawrence Crowl <crowl@google.com> +2007-04-16 Lawrence Crowl <crowl@google.com> (r123909) * doc/invoke.texi (Debugging Options): Add documentation for the -femit-struct-debug options -femit-struct-debug-baseonly, @@ -147,7 +188,7 @@ * config/i386/i386.c (override_options): Likewise. * doc/invoke.texi: Likewise. -2007-03-12 Seongbae Park <seongbae.park@gmail.com> +2007-03-12 Seongbae Park <seongbae.park@gmail.com> (r122851) * c-decl.c (warn_variable_length_array): New function. Refactored from grokdeclarator to handle warn_vla @@ -348,7 +389,7 @@ * config.gcc: Support core2 processor. -2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org> +2007-01-05 Manuel Lopez-Ibanez <manu@gcc.gnu.org> (r120505) PR c/19978 * tree.h (TREE_OVERFLOW_P): New. diff --git a/contrib/gcc/builtins.c b/contrib/gcc/builtins.c index ffae159..88c4668 100644 --- a/contrib/gcc/builtins.c +++ b/contrib/gcc/builtins.c @@ -315,9 +315,7 @@ get_pointer_alignment (tree exp, unsigned int max_align) else if (offset) inner = MIN (inner, BITS_PER_UNIT); } - if (TREE_CODE (exp) == FUNCTION_DECL) - align = FUNCTION_BOUNDARY; - else if (DECL_P (exp)) + if (DECL_P (exp)) align = MIN (inner, DECL_ALIGN (exp)); #ifdef CONSTANT_ALIGNMENT else if (CONSTANT_CLASS_P (exp)) diff --git a/contrib/gcc/c-common.c b/contrib/gcc/c-common.c index b650a48..fa89614 100644 --- a/contrib/gcc/c-common.c +++ b/contrib/gcc/c-common.c @@ -2995,16 +2995,16 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain) } /* Implement the __alignof keyword: Return the minimum required - alignment of EXPR, measured in bytes. For VAR_DECL's and - FIELD_DECL's return DECL_ALIGN (which can be set from an - "aligned" __attribute__ specification). */ + alignment of EXPR, measured in bytes. For VAR_DECLs, + FUNCTION_DECLs and FIELD_DECLs return DECL_ALIGN (which can be set + from an "aligned" __attribute__ specification). */ tree c_alignof_expr (tree expr) { tree t; - if (TREE_CODE (expr) == VAR_DECL) + if (VAR_OR_FUNCTION_DECL_P (expr)) t = size_int (DECL_ALIGN_UNIT (expr)); else if (TREE_CODE (expr) == COMPONENT_REF @@ -4809,12 +4809,24 @@ handle_aligned_attribute (tree *node, tree ARG_UNUSED (name), tree args, TYPE_ALIGN (*type) = (1 << i) * BITS_PER_UNIT; TYPE_USER_ALIGN (*type) = 1; } - else if (TREE_CODE (decl) != VAR_DECL + else if (! VAR_OR_FUNCTION_DECL_P (decl) && TREE_CODE (decl) != FIELD_DECL) { error ("alignment may not be specified for %q+D", decl); *no_add_attrs = true; } + else if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_ALIGN (decl) > (1 << i) * BITS_PER_UNIT) + { + if (DECL_USER_ALIGN (decl)) + error ("alignment for %q+D was previously specified as %d " + "and may not be decreased", decl, + DECL_ALIGN (decl) / BITS_PER_UNIT); + else + error ("alignment for %q+D must be at least %d", decl, + DECL_ALIGN (decl) / BITS_PER_UNIT); + *no_add_attrs = true; + } else { DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT; diff --git a/contrib/gcc/c-decl.c b/contrib/gcc/c-decl.c index 68ee23b..3cdd69b 100644 --- a/contrib/gcc/c-decl.c +++ b/contrib/gcc/c-decl.c @@ -1690,12 +1690,11 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) DECL_SIZE (newdecl) = DECL_SIZE (olddecl); DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl); DECL_MODE (newdecl) = DECL_MODE (olddecl); - if (TREE_CODE (olddecl) != FUNCTION_DECL) - if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl)) - { - DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); - DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl); - } + if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl)) + { + DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); + DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl); + } } diff --git a/contrib/gcc/cp/ChangeLog.gcc43 b/contrib/gcc/cp/ChangeLog.gcc43 index e232596..701bea8 100644 --- a/contrib/gcc/cp/ChangeLog.gcc43 +++ b/contrib/gcc/cp/ChangeLog.gcc43 @@ -1,3 +1,12 @@ +2007-07-09 Geoffrey Keating <geoffk@apple.com> (r126529) + + PR 32617 + * decl.c (cxx_init_decl_processing): Don't set + force_align_functions_log. + (grokfndecl): Honour ptrmemfunc_vbit_in_pfn. + * typeck.c (cxx_alignof_expr): When alignof is used on a plain + FUNCTION_DECL, return its alignment. + 2007-06-28 Geoffrey Keating <geoffk@apple.com> (r126080) * decl2.c (start_objects): Mark constructor-runnning function @@ -9,6 +18,13 @@ * decl2.c (determine_visibility): Remove duplicate code for handling type info. +2007-05-05 Geoffrey Keating <geoffk@apple.com> (r124467) + + PR 31775 + * mangle.c (write_mangled_name): Mangle static variable names. + (write_unqualified_name): Use local-source-name for + namespace-scope static variables. + 2007-03-12 Seongbae Park <seongbae.park@gmail.com> (r122851) * decl.c (compute_array_index_type): New warning flag warn_vla. diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c index 8b7a488..c6f6b07 100644 --- a/contrib/gcc/cp/decl.c +++ b/contrib/gcc/cp/decl.c @@ -3158,12 +3158,6 @@ cxx_init_decl_processing (void) if (flag_inline_functions) flag_inline_trees = 2; - /* Force minimum function alignment if using the least significant - bit of function pointers to store the virtual bit. */ - if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn - && force_align_functions_log < 1) - force_align_functions_log = 1; - /* Initially, C. */ current_lang_name = lang_name_c; @@ -6065,6 +6059,14 @@ grokfndecl (tree ctype, if (TYPE_VOLATILE (type)) TREE_THIS_VOLATILE (decl) = 1; + /* If pointers to member functions use the least significant bit to + indicate whether a function is virtual, ensure a pointer + to this function will have that bit clear. */ + if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn + && TREE_CODE (type) == METHOD_TYPE + && DECL_ALIGN (decl) < 2 * BITS_PER_UNIT) + DECL_ALIGN (decl) = 2 * BITS_PER_UNIT; + if (friendp && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR) { diff --git a/contrib/gcc/cp/mangle.c b/contrib/gcc/cp/mangle.c index 74ff854..c327133 100644 --- a/contrib/gcc/cp/mangle.c +++ b/contrib/gcc/cp/mangle.c @@ -688,7 +688,8 @@ write_mangled_name (const tree decl, bool top_level) } } else if (TREE_CODE (decl) == VAR_DECL - /* The names of global variables aren't mangled. */ + /* The names of non-static global variables aren't mangled. */ + && DECL_EXTERNAL_LINKAGE_P (decl) && (CP_DECL_CONTEXT (decl) == global_namespace /* And neither are `extern "C"' variables. */ || DECL_EXTERN_C_P (decl))) @@ -1086,7 +1087,10 @@ write_template_prefix (const tree node) <unqualified-name> ::= <operator-name> ::= <special-name> - ::= <source-name> */ + ::= <source-name> + ::= <local-source-name> + + <local-source-name> ::= L <source-name> <discriminator> */ static void write_unqualified_name (const tree decl) @@ -1126,6 +1130,16 @@ write_unqualified_name (const tree decl) write_string (oni[DECL_OVERLOADED_OPERATOR_P (decl)].mangled_name); } + else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl) + && DECL_NAMESPACE_SCOPE_P (decl) + && decl_linkage (decl) == lk_internal) + { + MANGLE_TRACE_TREE ("local-source-name", decl); + write_char ('L'); + write_source_name (DECL_NAME (decl)); + /* The default discriminator is 1, and that's all we ever use, + so there's no code to output one here. */ + } else write_source_name (DECL_NAME (decl)); } diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c index d17d0bb..5325989 100644 --- a/contrib/gcc/cp/typeck.c +++ b/contrib/gcc/cp/typeck.c @@ -1358,7 +1358,10 @@ cxx_alignof_expr (tree e) { pedwarn ("ISO C++ forbids applying %<__alignof%> to an expression of " "function type"); - t = size_one_node; + if (TREE_CODE (e) == FUNCTION_DECL) + t = size_int (DECL_ALIGN_UNIT (e)); + else + t = size_one_node; } else if (type_unknown_p (e)) { diff --git a/contrib/gcc/doc/extend.texi b/contrib/gcc/doc/extend.texi index 46cbc846..c6bd57d 100644 --- a/contrib/gcc/doc/extend.texi +++ b/contrib/gcc/doc/extend.texi @@ -1577,6 +1577,7 @@ The keyword @code{__attribute__} allows you to specify special attributes when making a declaration. This keyword is followed by an attribute specification inside double parentheses. The following attributes are currently defined for functions on all targets: +@code{aligned}, @code{noreturn}, @code{returns_twice}, @code{noinline}, @code{always_inline}, @code{flatten}, @code{pure}, @code{const}, @code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg}, @code{no_instrument_function}, @@ -1615,6 +1616,27 @@ is not defined in the same translation unit. Not all target machines support this attribute. +@item aligned (@var{alignment}) +@cindex @code{aligned} attribute +This attribute specifies a minimum alignment for the function, +measured in bytes. + +You cannot use this attribute to decrease the alignment of a function, +only to increase it. However, when you explicitly specify a function +alignment this will override the effect of the +@option{-falign-functions} (@pxref{Optimize Options}) option for this +function. + +Note that the effectiveness of @code{aligned} attributes may be +limited by inherent limitations in your linker. On many systems, the +linker is only able to arrange for functions to be aligned up to a +certain maximum alignment. (For some linkers, the maximum supported +alignment may be very very small.) See your linker documentation for +further information. + +The @code{aligned} attribute can also be used for variables and fields +(@pxref{Variable Attributes}.) + @item always_inline @cindex @code{always_inline} function attribute Generally, functions are not inlined unless optimization is specified. @@ -3044,6 +3066,9 @@ up to a maximum of 8 byte alignment, then specifying @code{aligned(16)} in an @code{__attribute__} will still only provide you with 8 byte alignment. See your linker documentation for further information. +The @code{aligned} attribute can also be used for functions +(@pxref{Function Attributes}.) + @item cleanup (@var{cleanup_function}) @cindex @code{cleanup} attribute The @code{cleanup} attribute runs a function when the variable goes diff --git a/contrib/gcc/flags.h b/contrib/gcc/flags.h index 6bcd028..1c1fd0d 100644 --- a/contrib/gcc/flags.h +++ b/contrib/gcc/flags.h @@ -261,10 +261,6 @@ extern int align_labels_log; extern int align_labels_max_skip; extern int align_functions_log; -/* Like align_functions_log above, but used by front-ends to force the - minimum function alignment. Zero means no alignment is forced. */ -extern int force_align_functions_log; - /* Nonzero if we dump in VCG format, not plain text. */ extern int dump_for_graph; diff --git a/contrib/gcc/print-tree.c b/contrib/gcc/print-tree.c index 57b07ac..ef87ab6 100644 --- a/contrib/gcc/print-tree.c +++ b/contrib/gcc/print-tree.c @@ -439,17 +439,15 @@ print_node (FILE *file, const char *prefix, tree node, int indent) || DECL_INLINE (node) || DECL_BUILT_IN (node)) indent_to (file, indent + 3); - if (TREE_CODE (node) != FUNCTION_DECL) - { - if (DECL_USER_ALIGN (node)) - fprintf (file, " user"); - - fprintf (file, " align %d", DECL_ALIGN (node)); - if (TREE_CODE (node) == FIELD_DECL) - fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED, - DECL_OFFSET_ALIGN (node)); - } - else if (DECL_BUILT_IN (node)) + if (DECL_USER_ALIGN (node)) + fprintf (file, " user"); + + fprintf (file, " align %d", DECL_ALIGN (node)); + if (TREE_CODE (node) == FIELD_DECL) + fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED, + DECL_OFFSET_ALIGN (node)); + + if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node)) { if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD) fprintf (file, " built-in BUILT_IN_MD %d", DECL_FUNCTION_CODE (node)); diff --git a/contrib/gcc/toplev.c b/contrib/gcc/toplev.c index 0b73a48..ab6a7ff 100644 --- a/contrib/gcc/toplev.c +++ b/contrib/gcc/toplev.c @@ -369,10 +369,6 @@ int align_labels_log; int align_labels_max_skip; int align_functions_log; -/* Like align_functions_log above, but used by front-ends to force the - minimum function alignment. Zero means no alignment is forced. */ -int force_align_functions_log; - typedef struct { const char *const string; diff --git a/contrib/gcc/tree.c b/contrib/gcc/tree.c index a778b08..8e0b801 100644 --- a/contrib/gcc/tree.c +++ b/contrib/gcc/tree.c @@ -541,9 +541,13 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) DECL_IN_SYSTEM_HEADER (t) = in_system_header; if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) { - if (code != FUNCTION_DECL) + if (code == FUNCTION_DECL) + { + DECL_ALIGN (t) = FUNCTION_BOUNDARY; + DECL_MODE (t) = FUNCTION_MODE; + } + else DECL_ALIGN (t) = 1; - DECL_USER_ALIGN (t) = 0; /* We have not yet computed the alias set for this declaration. */ DECL_POINTER_ALIAS_SET (t) = -1; } @@ -1881,14 +1885,13 @@ expr_align (tree t) align1 = expr_align (TREE_OPERAND (t, 2)); return MIN (align0, align1); + /* FIXME: LABEL_DECL and CONST_DECL never have DECL_ALIGN set + meaningfully, it's always 1. */ case LABEL_DECL: case CONST_DECL: case VAR_DECL: case PARM_DECL: case RESULT_DECL: - if (DECL_ALIGN (t) != 0) - return DECL_ALIGN (t); - break; - case FUNCTION_DECL: - return FUNCTION_BOUNDARY; + gcc_assert (DECL_ALIGN (t) != 0); + return DECL_ALIGN (t); default: break; @@ -3174,8 +3177,6 @@ build_decl_stat (enum tree_code code, tree name, tree type MEM_STAT_DECL) if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL) layout_decl (t, 0); - else if (code == FUNCTION_DECL) - DECL_MODE (t) = FUNCTION_MODE; return t; } diff --git a/contrib/gcc/tree.h b/contrib/gcc/tree.h index c502182..6cfc3d3 100644 --- a/contrib/gcc/tree.h +++ b/contrib/gcc/tree.h @@ -2426,13 +2426,11 @@ struct tree_struct_field_tag GTY(()) /* Likewise for the size in bytes. */ #define DECL_SIZE_UNIT(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.size_unit) /* Holds the alignment required for the datum, in bits. */ -#define DECL_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.u1.a.align) +#define DECL_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.align) /* The alignment of NODE, in bytes. */ #define DECL_ALIGN_UNIT(NODE) (DECL_ALIGN (NODE) / BITS_PER_UNIT) -/* For FIELD_DECLs, off_align holds the number of low-order bits of - DECL_FIELD_OFFSET which are known to be always zero. - DECL_OFFSET_ALIGN thus returns the alignment that DECL_FIELD_OFFSET - has. */ +/* Set if the alignment of this DECL has been set by the user, for + example with an 'aligned' attribute. */ #define DECL_USER_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.user_align) /* Holds the machine mode corresponding to the declaration of a variable or field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a @@ -2443,7 +2441,8 @@ struct tree_struct_field_tag GTY(()) operation it is. Note, however, that this field is overloaded, with DECL_BUILT_IN_CLASS as the discriminant, so the latter must always be checked before any access to the former. */ -#define DECL_FUNCTION_CODE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_common.u1.f) +#define DECL_FUNCTION_CODE(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.function_code) #define DECL_DEBUG_EXPR_IS_FROM(NODE) \ (DECL_COMMON_CHECK (NODE)->decl_common.debug_expr_is_from) @@ -2581,20 +2580,9 @@ struct tree_decl_common GTY(()) unsigned gimple_reg_flag : 1; unsigned call_clobbered_flag : 1; - union tree_decl_u1 { - /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is - DECL_FUNCTION_CODE. */ - enum built_in_function f; - /* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this - is used by language-dependent code. */ - HOST_WIDE_INT i; - /* DECL_ALIGN and DECL_OFFSET_ALIGN. (These are not used for - FUNCTION_DECLs). */ - struct tree_decl_u1_a { - unsigned int align : 24; - unsigned int off_align : 8; - } a; - } GTY ((skip)) u1; + unsigned int align : 24; + /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */ + unsigned int off_align : 8; tree size_unit; tree initial; @@ -2679,11 +2667,11 @@ struct tree_decl_with_rtl GTY(()) DECL_OFFSET_ALIGN thus returns the alignment that DECL_FIELD_OFFSET has. */ #define DECL_OFFSET_ALIGN(NODE) \ - (((unsigned HOST_WIDE_INT)1) << FIELD_DECL_CHECK (NODE)->decl_common.u1.a.off_align) + (((unsigned HOST_WIDE_INT)1) << FIELD_DECL_CHECK (NODE)->decl_common.off_align) /* Specify that DECL_ALIGN(NODE) is a multiple of X. */ #define SET_DECL_OFFSET_ALIGN(NODE, X) \ - (FIELD_DECL_CHECK (NODE)->decl_common.u1.a.off_align = exact_log2 ((X) & -(X))) + (FIELD_DECL_CHECK (NODE)->decl_common.off_align = exact_log2 ((X) & -(X))) /* 1 if the alignment for this type was requested by "aligned" attribute, 0 if it is the default for this type. */ @@ -3096,6 +3084,10 @@ struct tree_function_decl GTY(()) { struct tree_decl_non_common common; + /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is + DECL_FUNCTION_CODE. Otherwise unused. */ + enum built_in_function function_code; + unsigned static_ctor_flag : 1; unsigned static_dtor_flag : 1; unsigned uninlinable : 1; diff --git a/contrib/gcc/varasm.c b/contrib/gcc/varasm.c index 21b6904..ef3a83a 100644 --- a/contrib/gcc/varasm.c +++ b/contrib/gcc/varasm.c @@ -1383,7 +1383,7 @@ assemble_start_function (tree decl, const char *fnname) if (flag_reorder_blocks_and_partition) { switch_to_section (unlikely_text_section ()); - assemble_align (FUNCTION_BOUNDARY); + assemble_align (DECL_ALIGN (decl)); ASM_OUTPUT_LABEL (asm_out_file, cfun->cold_section_label); /* When the function starts with a cold section, we need to explicitly @@ -1393,7 +1393,7 @@ assemble_start_function (tree decl, const char *fnname) && BB_PARTITION (ENTRY_BLOCK_PTR->next_bb) == BB_COLD_PARTITION) { switch_to_section (text_section); - assemble_align (FUNCTION_BOUNDARY); + assemble_align (DECL_ALIGN (decl)); ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_label); hot_label_written = true; first_function_block_is_cold = true; @@ -1424,18 +1424,17 @@ assemble_start_function (tree decl, const char *fnname) ASM_OUTPUT_LABEL (asm_out_file, cfun->hot_section_label); /* Tell assembler to move to target machine's alignment for functions. */ - align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT); - if (align < force_align_functions_log) - align = force_align_functions_log; + align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT); if (align > 0) { ASM_OUTPUT_ALIGN (asm_out_file, align); } /* Handle a user-specified function alignment. - Note that we still need to align to FUNCTION_BOUNDARY, as above, + Note that we still need to align to DECL_ALIGN, as above, because ASM_OUTPUT_MAX_SKIP_ALIGN might not do any alignment at all. */ - if (align_functions_log > align + if (! DECL_USER_ALIGN (decl) + && align_functions_log > align && cfun->function_frequency != FUNCTION_FREQUENCY_UNLIKELY_EXECUTED) { #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN diff --git a/contrib/gcclibs/libiberty/ChangeLog.gcc43 b/contrib/gcclibs/libiberty/ChangeLog.gcc43 new file mode 100644 index 0000000..1bf5e37 --- /dev/null +++ b/contrib/gcclibs/libiberty/ChangeLog.gcc43 @@ -0,0 +1,60 @@ +2007-05-05 Geoffrey Keating <geoffk@apple.com> (r124467) + + PR 31775 + * mangle.c (write_mangled_name): Mangle static variable names. + (write_unqualified_name): Use local-source-name for + namespace-scope static variables. + +2007-03-15 Geoffrey Keating <geoffk@apple.com> (r122972) + + * cp-demangle.c (d_encoding): Exit early on error. + (d_pointer_to_member_type): Exit early if cplus_demangle_type + returns NULL. + (cplus_demangle_type): Likewise. + * testsuite/demangle-expected: New testcase. + +2007-01-31 Ben Elliston <bje@au.ibm.com> (r121364) + + * strsignal.c (psignal): Change type of signo to int. + * functions.texi: Regenerate. + +2007-01-12 Ben Elliston <bje@au.ibm.com> (r120702) + + * pex-unix.c (writeerr): Cast write result to void. + + * choose-temp.c (choose_temp_base): Check the result of the call + to mktemp rather than testing the length of the modified string. + +2006-12-20 Geoffrey Keating <geoffk@apple.com> (r120097) + + * cp-demangle.h: Add comment explaining what to do to avoid + overrunning string. + (d_check_char): New. + (d_next_char): Don't advance past trailing '\0'. + * cp-demangle.c (cplus_demangle_mangled_name): Use d_check_char. + (d_nested_name): Likewise. + (d_special_name): Likewise. + (d_call_offset): Likewise. + (d_function_type): Likewise. + (d_array_type): Likewise. + (d_pointer_to_member_type): Likewise. + (d_template_param): Likewise. + (d_template_args): Likewise. + (d_template_arg): Likewise. + (d_expr_primary): Likewise. + (d_local_name): Likewise. + (d_substitution): Likewise. + (d_ctor_dtor_name): Use d_advance rather than d_next_char. + * testsuite/test-demangle.c: Include sys/mman.h. + (MAP_ANONYMOUS): Define. + (protect_end): New. + (main): Use protect_end. + * testsuite/demangle-expected: Add testcases for overrunning + the end of the string. + +2006-11-07 Julian Brown <julian@codesourcery.com> (r118552) + + * floatformat.c (get_field): Fix segfault with little-endian word + order on 64-bit hosts. + (put_field): Likewise. + (min): Move definition. diff --git a/contrib/gcclibs/libiberty/choose-temp.c b/contrib/gcclibs/libiberty/choose-temp.c index 0cba990..4a26a82 100644 --- a/contrib/gcclibs/libiberty/choose-temp.c +++ b/contrib/gcclibs/libiberty/choose-temp.c @@ -65,8 +65,7 @@ choose_temp_base (void) strcpy (temp_filename, base); strcpy (temp_filename + len, TEMP_FILE); - mktemp (temp_filename); - if (strlen (temp_filename) == 0) + if (mktemp (temp_filename) == 0) abort (); return temp_filename; } diff --git a/contrib/gcclibs/libiberty/cp-demangle.c b/contrib/gcclibs/libiberty/cp-demangle.c index 2fa5978..6b4781e 100644 --- a/contrib/gcclibs/libiberty/cp-demangle.c +++ b/contrib/gcclibs/libiberty/cp-demangle.c @@ -913,9 +913,9 @@ CP_STATIC_IF_GLIBCPP_V3 struct demangle_component * cplus_demangle_mangled_name (struct d_info *di, int top_level) { - if (d_next_char (di) != '_') + if (! d_check_char (di, '_')) return NULL; - if (d_next_char (di) != 'Z') + if (! d_check_char (di, 'Z')) return NULL; return d_encoding (di, top_level); } @@ -1021,7 +1021,7 @@ d_encoding (struct d_info *di, int top_level) } peek = d_peek_char (di); - if (peek == '\0' || peek == 'E') + if (dc == NULL || peek == '\0' || peek == 'E') return dc; return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc, d_bare_function_type (di, has_return_type (dc))); @@ -1054,6 +1054,9 @@ d_name (struct d_info *di) case 'Z': return d_local_name (di); + case 'L': + return d_unqualified_name (di); + case 'S': { int subst; @@ -1123,7 +1126,7 @@ d_nested_name (struct d_info *di) struct demangle_component *ret; struct demangle_component **pret; - if (d_next_char (di) != 'N') + if (! d_check_char (di, 'N')) return NULL; pret = d_cv_qualifiers (di, &ret, 1); @@ -1134,7 +1137,7 @@ d_nested_name (struct d_info *di) if (*pret == NULL) return NULL; - if (d_next_char (di) != 'E') + if (! d_check_char (di, 'E')) return NULL; return ret; @@ -1174,7 +1177,8 @@ d_prefix (struct d_info *di) if (IS_DIGIT (peek) || IS_LOWER (peek) || peek == 'C' - || peek == 'D') + || peek == 'D' + || peek == 'L') dc = d_unqualified_name (di); else if (peek == 'S') dc = d_substitution (di, 1); @@ -1208,6 +1212,9 @@ d_prefix (struct d_info *di) /* <unqualified-name> ::= <operator-name> ::= <ctor-dtor-name> ::= <source-name> + ::= <local-source-name> + + <local-source-name> ::= L <source-name> <discriminator> */ static struct demangle_component * @@ -1229,6 +1236,19 @@ d_unqualified_name (struct d_info *di) } else if (peek == 'C' || peek == 'D') return d_ctor_dtor_name (di); + else if (peek == 'L') + { + struct demangle_component * ret; + + d_advance (di, 1); + + ret = d_source_name (di); + if (ret == NULL) + return NULL; + if (! d_discriminator (di)) + return NULL; + return ret; + } else return NULL; } @@ -1449,11 +1469,8 @@ d_operator_name (struct d_info *di) static struct demangle_component * d_special_name (struct d_info *di) { - char c; - di->expansion += 20; - c = d_next_char (di); - if (c == 'T') + if (d_check_char (di, 'T')) { switch (d_next_char (di)) { @@ -1502,7 +1519,7 @@ d_special_name (struct d_info *di) offset = d_number (di); if (offset < 0) return NULL; - if (d_next_char (di) != '_') + if (! d_check_char (di, '_')) return NULL; base_type = cplus_demangle_type (di); /* We don't display the offset. FIXME: We should display @@ -1523,7 +1540,7 @@ d_special_name (struct d_info *di) return NULL; } } - else if (c == 'G') + else if (d_check_char (di, 'G')) { switch (d_next_char (di)) { @@ -1570,14 +1587,14 @@ d_call_offset (struct d_info *di, int c) else if (c == 'v') { d_number (di); - if (d_next_char (di) != '_') + if (! d_check_char (di, '_')) return 0; d_number (di); } else return 0; - if (d_next_char (di) != '_') + if (! d_check_char (di, '_')) return 0; return 1; @@ -1601,13 +1618,13 @@ d_ctor_dtor_name (struct d_info *di) else if (di->last_name->type == DEMANGLE_COMPONENT_SUB_STD) di->expansion += di->last_name->u.s_string.len; } - switch (d_next_char (di)) + switch (d_peek_char (di)) { case 'C': { enum gnu_v3_ctor_kinds kind; - switch (d_next_char (di)) + switch (d_peek_next_char (di)) { case '1': kind = gnu_v3_complete_object_ctor; @@ -1621,6 +1638,7 @@ d_ctor_dtor_name (struct d_info *di) default: return NULL; } + d_advance (di, 2); return d_make_ctor (di, kind, di->last_name); } @@ -1628,7 +1646,7 @@ d_ctor_dtor_name (struct d_info *di) { enum gnu_v3_dtor_kinds kind; - switch (d_next_char (di)) + switch (d_peek_next_char (di)) { case '0': kind = gnu_v3_deleting_dtor; @@ -1642,6 +1660,7 @@ d_ctor_dtor_name (struct d_info *di) default: return NULL; } + d_advance (di, 2); return d_make_dtor (di, kind, di->last_name); } @@ -1735,7 +1754,7 @@ cplus_demangle_type (struct d_info *di) if (pret == NULL) return NULL; *pret = cplus_demangle_type (di); - if (! d_add_substitution (di, ret)) + if (! *pret || ! d_add_substitution (di, ret)) return NULL; return ret; } @@ -1925,7 +1944,7 @@ d_function_type (struct d_info *di) { struct demangle_component *ret; - if (d_next_char (di) != 'F') + if (! d_check_char (di, 'F')) return NULL; if (d_peek_char (di) == 'Y') { @@ -1934,7 +1953,7 @@ d_function_type (struct d_info *di) d_advance (di, 1); } ret = d_bare_function_type (di, 1); - if (d_next_char (di) != 'E') + if (! d_check_char (di, 'E')) return NULL; return ret; } @@ -2021,7 +2040,7 @@ d_array_type (struct d_info *di) char peek; struct demangle_component *dim; - if (d_next_char (di) != 'A') + if (! d_check_char (di, 'A')) return NULL; peek = d_peek_char (di); @@ -2049,7 +2068,7 @@ d_array_type (struct d_info *di) return NULL; } - if (d_next_char (di) != '_') + if (! d_check_char (di, '_')) return NULL; return d_make_comp (di, DEMANGLE_COMPONENT_ARRAY_TYPE, dim, @@ -2065,7 +2084,7 @@ d_pointer_to_member_type (struct d_info *di) struct demangle_component *mem; struct demangle_component **pmem; - if (d_next_char (di) != 'M') + if (! d_check_char (di, 'M')) return NULL; cl = cplus_demangle_type (di); @@ -2090,6 +2109,8 @@ d_pointer_to_member_type (struct d_info *di) if (pmem == NULL) return NULL; *pmem = cplus_demangle_type (di); + if (*pmem == NULL) + return NULL; if (pmem != &mem && (*pmem)->type != DEMANGLE_COMPONENT_FUNCTION_TYPE) { @@ -2109,7 +2130,7 @@ d_template_param (struct d_info *di) { long param; - if (d_next_char (di) != 'T') + if (! d_check_char (di, 'T')) return NULL; if (d_peek_char (di) == '_') @@ -2122,7 +2143,7 @@ d_template_param (struct d_info *di) param += 1; } - if (d_next_char (di) != '_') + if (! d_check_char (di, '_')) return NULL; ++di->did_subs; @@ -2144,7 +2165,7 @@ d_template_args (struct d_info *di) constructor or destructor. */ hold_last_name = di->last_name; - if (d_next_char (di) != 'I') + if (! d_check_char (di, 'I')) return NULL; al = NULL; @@ -2189,7 +2210,7 @@ d_template_arg (struct d_info *di) case 'X': d_advance (di, 1); ret = d_expression (di); - if (d_next_char (di) != 'E') + if (! d_check_char (di, 'E')) return NULL; return ret; @@ -2316,7 +2337,7 @@ d_expr_primary (struct d_info *di) { struct demangle_component *ret; - if (d_next_char (di) != 'L') + if (! d_check_char (di, 'L')) return NULL; if (d_peek_char (di) == '_') ret = cplus_demangle_mangled_name (di, 0); @@ -2362,7 +2383,7 @@ d_expr_primary (struct d_info *di) } ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s)); } - if (d_next_char (di) != 'E') + if (! d_check_char (di, 'E')) return NULL; return ret; } @@ -2376,12 +2397,12 @@ d_local_name (struct d_info *di) { struct demangle_component *function; - if (d_next_char (di) != 'Z') + if (! d_check_char (di, 'Z')) return NULL; function = d_encoding (di, 0); - if (d_next_char (di) != 'E') + if (! d_check_char (di, 'E')) return NULL; if (d_peek_char (di) == 's') @@ -2486,7 +2507,7 @@ d_substitution (struct d_info *di, int prefix) { char c; - if (d_next_char (di) != 'S') + if (! d_check_char (di, 'S')) return NULL; c = d_next_char (di); diff --git a/contrib/gcclibs/libiberty/cp-demangle.h b/contrib/gcclibs/libiberty/cp-demangle.h index 2517a57..920ca47 100644 --- a/contrib/gcclibs/libiberty/cp-demangle.h +++ b/contrib/gcclibs/libiberty/cp-demangle.h @@ -123,10 +123,16 @@ struct d_info int expansion; }; +/* To avoid running past the ending '\0', don't: + - call d_peek_next_char if d_peek_char returned '\0' + - call d_advance with an 'i' that is too large + - call d_check_char(di, '\0') + Everything else is safe. */ #define d_peek_char(di) (*((di)->n)) #define d_peek_next_char(di) ((di)->n[1]) #define d_advance(di, i) ((di)->n += (i)) -#define d_next_char(di) (*((di)->n++)) +#define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0) +#define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++)) #define d_str(di) ((di)->n) /* Functions and arrays in cp-demangle.c which are referenced by diff --git a/contrib/gcclibs/libiberty/floatformat.c b/contrib/gcclibs/libiberty/floatformat.c index 0bbb8ed..c5abbb1 100644 --- a/contrib/gcclibs/libiberty/floatformat.c +++ b/contrib/gcclibs/libiberty/floatformat.c @@ -249,53 +249,51 @@ const struct floatformat floatformat_ia64_quad_little = floatformat_always_valid }; + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + /* Extract a field which starts at START and is LEN bits long. DATA and TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */ static unsigned long get_field (const unsigned char *data, enum floatformat_byteorders order, unsigned int total_len, unsigned int start, unsigned int len) { - unsigned long result; + unsigned long result = 0; unsigned int cur_byte; - int cur_bitshift; + int lo_bit, hi_bit, cur_bitshift = 0; + int nextbyte = (order == floatformat_little) ? 1 : -1; + + /* Start is in big-endian bit order! Fix that first. */ + start = total_len - (start + len); /* Start at the least significant part of the field. */ - cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT; if (order == floatformat_little) - cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1; - cur_bitshift = - ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT; - result = *(data + cur_byte) >> (-cur_bitshift); - cur_bitshift += FLOATFORMAT_CHAR_BIT; - if (order == floatformat_little) - ++cur_byte; + cur_byte = start / FLOATFORMAT_CHAR_BIT; else - --cur_byte; + cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT; - /* Move towards the most significant part of the field. */ - while ((unsigned int) cur_bitshift < len) + lo_bit = start % FLOATFORMAT_CHAR_BIT; + hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT); + + do { - if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT) - /* This is the last byte; zero out the bits which are not part of - this field. */ - result |= - (*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1)) - << cur_bitshift; - else - result |= *(data + cur_byte) << cur_bitshift; - cur_bitshift += FLOATFORMAT_CHAR_BIT; - if (order == floatformat_little) - ++cur_byte; - else - --cur_byte; + unsigned int shifted = *(data + cur_byte) >> lo_bit; + unsigned int bits = hi_bit - lo_bit; + unsigned int mask = (1 << bits) - 1; + result |= (shifted & mask) << cur_bitshift; + len -= bits; + cur_bitshift += bits; + cur_byte += nextbyte; + lo_bit = 0; + hi_bit = min (len, FLOATFORMAT_CHAR_BIT); } + while (len != 0); + return result; } -#ifndef min -#define min(a, b) ((a) < (b) ? (a) : (b)) -#endif - /* Convert from FMT to a double. FROM is the address of the extended float. Store the double in *TO. */ @@ -428,43 +426,34 @@ put_field (unsigned char *data, enum floatformat_byteorders order, unsigned long stuff_to_put) { unsigned int cur_byte; - int cur_bitshift; + int lo_bit, hi_bit; + int nextbyte = (order == floatformat_little) ? 1 : -1; + + /* Start is in big-endian bit order! Fix that first. */ + start = total_len - (start + len); /* Start at the least significant part of the field. */ - cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT; - if (order == floatformat_little) - cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1; - cur_bitshift = - ((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT; - *(data + cur_byte) &= - ~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) << (-cur_bitshift)); - *(data + cur_byte) |= - (stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift); - cur_bitshift += FLOATFORMAT_CHAR_BIT; if (order == floatformat_little) - ++cur_byte; + cur_byte = start / FLOATFORMAT_CHAR_BIT; else - --cur_byte; + cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT; - /* Move towards the most significant part of the field. */ - while ((unsigned int) cur_bitshift < len) + lo_bit = start % FLOATFORMAT_CHAR_BIT; + hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT); + + do { - if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT) - { - /* This is the last byte. */ - *(data + cur_byte) &= - ~((1 << (len - cur_bitshift)) - 1); - *(data + cur_byte) |= (stuff_to_put >> cur_bitshift); - } - else - *(data + cur_byte) = ((stuff_to_put >> cur_bitshift) - & ((1 << FLOATFORMAT_CHAR_BIT) - 1)); - cur_bitshift += FLOATFORMAT_CHAR_BIT; - if (order == floatformat_little) - ++cur_byte; - else - --cur_byte; + unsigned char *byte_ptr = data + cur_byte; + unsigned int bits = hi_bit - lo_bit; + unsigned int mask = ((1 << bits) - 1) << lo_bit; + *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask); + stuff_to_put >>= bits; + len -= bits; + cur_byte += nextbyte; + lo_bit = 0; + hi_bit = min (len, FLOATFORMAT_CHAR_BIT); } + while (len != 0); } /* The converse: convert the double *FROM to an extended float diff --git a/contrib/gcclibs/libiberty/functions.texi b/contrib/gcclibs/libiberty/functions.texi index 68c0648..45dcd4c 100644 --- a/contrib/gcclibs/libiberty/functions.texi +++ b/contrib/gcclibs/libiberty/functions.texi @@ -948,7 +948,7 @@ documented. @end deftypefn @c strsignal.c:539 -@deftypefn Supplemental void psignal (unsigned @var{signo}, char *@var{message}) +@deftypefn Supplemental void psignal (int @var{signo}, char *@var{message}) Print @var{message} to the standard error, followed by a colon, followed by the description of the signal specified by @var{signo}, diff --git a/contrib/gcclibs/libiberty/pex-unix.c b/contrib/gcclibs/libiberty/pex-unix.c index c5fa984..a776041 100644 --- a/contrib/gcclibs/libiberty/pex-unix.c +++ b/contrib/gcclibs/libiberty/pex-unix.c @@ -339,7 +339,7 @@ static void pex_child_error (struct pex_obj *obj, const char *executable, const char *errmsg, int err) { -#define writeerr(s) write (STDERR_FILE_NO, s, strlen (s)) +#define writeerr(s) (void) write (STDERR_FILE_NO, s, strlen (s)) writeerr (obj->pname); writeerr (": error trying to exec '"); writeerr (executable); diff --git a/contrib/gcclibs/libiberty/strsignal.c b/contrib/gcclibs/libiberty/strsignal.c index c3a16ab..4ca9e21 100644 --- a/contrib/gcclibs/libiberty/strsignal.c +++ b/contrib/gcclibs/libiberty/strsignal.c @@ -9,7 +9,7 @@ /* We need to declare sys_siglist, because even if the system provides it we can't assume that it is declared in <signal.h> (for example, SunOS provides sys_siglist, but it does not declare it in any - header file). fHowever, we can't declare sys_siglist portably, + header file). However, we can't declare sys_siglist portably, because on some systems it is declared with const and on some systems it is declared without const. If we were using autoconf, we could work out the right declaration. Until, then we just @@ -536,7 +536,7 @@ strtosigno (const char *name) /* -@deftypefn Supplemental void psignal (unsigned @var{signo}, char *@var{message}) +@deftypefn Supplemental void psignal (int @var{signo}, char *@var{message}) Print @var{message} to the standard error, followed by a colon, followed by the description of the signal specified by @var{signo}, @@ -549,7 +549,7 @@ followed by a newline. #ifndef HAVE_PSIGNAL void -psignal (unsigned signo, char *message) +psignal (int signo, char *message) { if (signal_names == NULL) { diff --git a/contrib/gcclibs/libiberty/testsuite/demangle-expected b/contrib/gcclibs/libiberty/testsuite/demangle-expected index 3f5622f..3c5f313 100644 --- a/contrib/gcclibs/libiberty/testsuite/demangle-expected +++ b/contrib/gcclibs/libiberty/testsuite/demangle-expected @@ -3816,3 +3816,68 @@ f SASDASDFASDF_sdfsdf SASDASDFASDF_sdfsdf SASDASDFASDF_sdfsdf +# These are all cases of invalid manglings where the demangler would read +# past the end of the string. +# d_name wasn't honouring a NULL from d_substitution +--format=gnu-v3 +_ZSA +_ZSA +# d_expr_primary wasn't honouring NULL from cplus_demangle_mangled_name +--format=gnu-v3 +_ZN1fIL_ +_ZN1fIL_ +# d_operator_name was taking two characters in a row +--format=gnu-v3 +_Za +_Za +# d_prefix wasn't honouring NULL from d_substitution +--format=gnu-v3 +_ZNSA +_ZNSA +# d_prefix wasn't honouring NULL from d_template_param +--format=gnu-v3 +_ZNT +_ZNT +# Dereferencing NULL in d_pointer_to_member_type +--format=gnu-v3 +_Z1aMark +_Z1aMark +--format=gnu-v3 +_ZSA +_ZSA +# d_expr_primary wasn't honouring NULL from cplus_demangle_mangled_name +--format=gnu-v3 +_ZN1fIL_ +_ZN1fIL_ +# d_operator_name was taking two characters in a row +--format=gnu-v3 +_Za +_Za +# d_prefix wasn't honouring NULL from d_substitution +--format=gnu-v3 +_ZNSA +_ZNSA +# d_prefix wasn't honouring NULL from d_template_param +--format=gnu-v3 +_ZNT +_ZNT +# Dereferencing NULL in d_pointer_to_member_type +--format=gnu-v3 +_Z1aMark +_Z1aMark +# <local-source-name> test 1 +--format=gnu-v3 +_ZL3foo_2 +foo +# <local-source-name> test 2 +--format=gnu-v3 +_ZZL3foo_2vE4var1 +foo()::var1 +# <local-source-name> test 3 +--format=gnu-v3 +_ZZL3foo_2vE4var1_0 +foo()::var1 +# <local-source-name> test 4 +--format=gnu-v3 +_ZZN7myspaceL3foo_1EvEN11localstruct1fEZNS_3fooEvE16otherlocalstruct +myspace::foo()::localstruct::f(myspace::foo()::otherlocalstruct) diff --git a/contrib/gcclibs/libiberty/testsuite/test-demangle.c b/contrib/gcclibs/libiberty/testsuite/test-demangle.c index 9379399..12b07dd 100644 --- a/contrib/gcclibs/libiberty/testsuite/test-demangle.c +++ b/contrib/gcclibs/libiberty/testsuite/test-demangle.c @@ -86,6 +86,50 @@ getline(buf) buf->alloced = alloc; } +/* If we have mmap() and mprotect(), copy the string S just before a + protected page, so that if the demangler runs over the end of the + string we'll get a fault, and return the address of the new string. + If no mmap, or it fails, or it looks too hard, just return S. */ + +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif +#if defined(MAP_ANON) && ! defined (MAP_ANONYMOUS) +#define MAP_ANONYMOUS MAP_ANON +#endif + +static const char * +protect_end (const char * s) +{ +#if defined(HAVE_MMAP) && defined (MAP_ANONYMOUS) + size_t pagesize = getpagesize(); + static char * buf; + size_t s_len = strlen (s); + char * result; + + /* Don't try if S is too long. */ + if (s_len >= pagesize) + return s; + + /* Allocate one page of allocated space followed by an unmapped + page. */ + if (buf == NULL) + { + buf = mmap (NULL, pagesize * 2, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (! buf) + return s; + munmap (buf + pagesize, pagesize); + } + + result = buf + (pagesize - s_len - 1); + memcpy (result, s, s_len + 1); + return result; +#else + return s; +#endif +} + static void fail (lineno, opts, in, out, exp) int lineno; @@ -150,6 +194,8 @@ main(argc, argv) for (;;) { + const char *inp; + getline (&format); if (feof (stdin)) break; @@ -157,6 +203,8 @@ main(argc, argv) getline (&input); getline (&expect); + inp = protect_end (input.data); + tests++; no_params = 0; @@ -237,14 +285,14 @@ main(argc, argv) { enum gnu_v3_ctor_kinds kc; - kc = is_gnu_v3_mangled_ctor (input.data); + kc = is_gnu_v3_mangled_ctor (inp); sprintf (buf, "%d", (int) kc); } else { enum gnu_v3_dtor_kinds kd; - kd = is_gnu_v3_mangled_dtor (input.data); + kd = is_gnu_v3_mangled_dtor (inp); sprintf (buf, "%d", (int) kd); } @@ -259,7 +307,7 @@ main(argc, argv) cplus_demangle_set_style (style); - result = cplus_demangle (input.data, + result = cplus_demangle (inp, DMGL_PARAMS|DMGL_ANSI|DMGL_TYPES |(ret_postfix ? DMGL_RET_POSTFIX : 0)); @@ -275,7 +323,7 @@ main(argc, argv) if (no_params) { getline (&expect); - result = cplus_demangle (input.data, DMGL_ANSI|DMGL_TYPES); + result = cplus_demangle (inp, DMGL_ANSI|DMGL_TYPES); if (result ? strcmp (result, expect.data) diff --git a/contrib/libstdc++/include/bits/basic_string.h b/contrib/libstdc++/include/bits/basic_string.h index dba1f56..90d2e2d 100644 --- a/contrib/libstdc++/include/bits/basic_string.h +++ b/contrib/libstdc++/include/bits/basic_string.h @@ -390,6 +390,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std) _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) { _M_copy(__p, __k1, __k2 - __k1); } + static int + _S_compare(size_type __x, size_type __y) + { + if (__x > __y) + return 1; + if (__x < __y) + return -1; + return 0; + } + void _M_mutate(size_type __pos, size_type __len1, size_type __len2); @@ -1934,7 +1944,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) int __r = traits_type::compare(_M_data(), __str.data(), __len); if (!__r) - __r = __size - __osize; + __r = _S_compare(__size, __osize); return __r; } diff --git a/contrib/libstdc++/include/bits/basic_string.tcc b/contrib/libstdc++/include/bits/basic_string.tcc index c2798ef..78428c1 100644 --- a/contrib/libstdc++/include/bits/basic_string.tcc +++ b/contrib/libstdc++/include/bits/basic_string.tcc @@ -903,7 +903,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) const size_type __len = std::min(__n, __osize); int __r = traits_type::compare(_M_data() + __pos, __str.data(), __len); if (!__r) - __r = __n - __osize; + __r = _S_compare(__n, __osize); return __r; } @@ -921,7 +921,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) int __r = traits_type::compare(_M_data() + __pos1, __str.data() + __pos2, __len); if (!__r) - __r = __n1 - __n2; + __r = _S_compare(__n1, __n2); return __r; } @@ -936,7 +936,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) const size_type __len = std::min(__size, __osize); int __r = traits_type::compare(_M_data(), __s, __len); if (!__r) - __r = __size - __osize; + __r = _S_compare(__size, __osize); return __r; } @@ -952,7 +952,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) const size_type __len = std::min(__n1, __osize); int __r = traits_type::compare(_M_data() + __pos, __s, __len); if (!__r) - __r = __n1 - __osize; + __r = _S_compare(__n1, __osize); return __r; } @@ -968,7 +968,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) const size_type __len = std::min(__n1, __n2); int __r = traits_type::compare(_M_data() + __pos, __s, __len); if (!__r) - __r = __n1 - __n2; + __r = _S_compare(__n1, __n2); return __r; } diff --git a/contrib/libstdc++/include/bits/stl_algobase.h b/contrib/libstdc++/include/bits/stl_algobase.h index 6f19feb..2d89d03 100644 --- a/contrib/libstdc++/include/bits/stl_algobase.h +++ b/contrib/libstdc++/include/bits/stl_algobase.h @@ -373,7 +373,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) * @param first An input iterator. * @param last An input iterator. * @param result An output iterator. - * @return result + (first - last) + * @return result + (last - first) * * This inline function will boil down to a call to @c memmove whenever * possible. Failing that, if random access iterators are passed, then the diff --git a/contrib/libstdc++/include/bits/stl_tree.h b/contrib/libstdc++/include/bits/stl_tree.h index 80cf7c4..9e7a9ac 100644 --- a/contrib/libstdc++/include/bits/stl_tree.h +++ b/contrib/libstdc++/include/bits/stl_tree.h @@ -64,6 +64,8 @@ #ifndef _TREE_H #define _TREE_H 1 +#pragma GCC system_header + #include <bits/stl_algobase.h> #include <bits/allocator.h> #include <bits/stl_construct.h> diff --git a/contrib/libstdc++/include/bits/stl_vector.h b/contrib/libstdc++/include/bits/stl_vector.h index 1b794dc..60e352c 100644 --- a/contrib/libstdc++/include/bits/stl_vector.h +++ b/contrib/libstdc++/include/bits/stl_vector.h @@ -119,9 +119,12 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) _Vector_base(size_t __n, const allocator_type& __a) : _M_impl(__a) { - this->_M_impl._M_start = this->_M_allocate(__n); - this->_M_impl._M_finish = this->_M_impl._M_start; - this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + if (__n) + { + this->_M_impl._M_start = this->_M_allocate(__n); + this->_M_impl._M_finish = this->_M_impl._M_start; + this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; + } } ~_Vector_base() diff --git a/contrib/libstdc++/include/ext/mt_allocator.h b/contrib/libstdc++/include/ext/mt_allocator.h index bc2d61f..bfd9197 100644 --- a/contrib/libstdc++/include/ext/mt_allocator.h +++ b/contrib/libstdc++/include/ext/mt_allocator.h @@ -342,12 +342,12 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) { return _M_bin[__which]; } void - _M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block, + _M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block_record, size_t __thread_id) { if (__gthread_active_p()) { - __block->_M_thread_id = __thread_id; + __block_record->_M_thread_id = __thread_id; --__bin._M_free[__thread_id]; ++__bin._M_used[__thread_id]; } @@ -697,11 +697,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) { // Already reserved. typedef typename __pool_type::_Block_record _Block_record; - _Block_record* __block = __bin._M_first[__thread_id]; - __bin._M_first[__thread_id] = __block->_M_next; + _Block_record* __block_record = __bin._M_first[__thread_id]; + __bin._M_first[__thread_id] = __block_record->_M_next; - __pool._M_adjust_freelist(__bin, __block, __thread_id); - __c = reinterpret_cast<char*>(__block) + __pool._M_get_align(); + __pool._M_adjust_freelist(__bin, __block_record, __thread_id); + __c = reinterpret_cast<char*>(__block_record) + __pool._M_get_align(); } else { diff --git a/contrib/libstdc++/include/ext/throw_allocator.h b/contrib/libstdc++/include/ext/throw_allocator.h index 5886afc..8862153 100644 --- a/contrib/libstdc++/include/ext/throw_allocator.h +++ b/contrib/libstdc++/include/ext/throw_allocator.h @@ -423,11 +423,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) s += buf; s += tab; s += "label: "; - sprintf(buf, "%u", ref.second.first); + sprintf(buf, "%lu", ref.second.first); s += buf; s += tab; s += "size: "; - sprintf(buf, "%u", ref.second.second); + sprintf(buf, "%lu", ref.second.second); s += buf; s += '\n'; } diff --git a/contrib/libstdc++/libsupc++/eh_alloc.cc b/contrib/libstdc++/libsupc++/eh_alloc.cc index 217a8cd..4233502 100644 --- a/contrib/libstdc++/libsupc++/eh_alloc.cc +++ b/contrib/libstdc++/libsupc++/eh_alloc.cc @@ -78,6 +78,14 @@ using namespace __cxxabiv1; # define EMERGENCY_OBJ_COUNT 4 #endif +/* APPLE LOCAL begin reduce emergency buffer size */ +/* 256 bytes is more than large enough for an std::bad_alloc object */ +#undef EMERGENCY_OBJ_SIZE +#undef EMERGENCY_OBJ_COUNT +#define EMERGENCY_OBJ_SIZE 256 +#define EMERGENCY_OBJ_COUNT 2 +/* APPLE LOCAL end reduce emergency buffer size */ + #if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32 typedef unsigned int bitmask_type; #else diff --git a/contrib/libstdc++/src/mt_allocator.cc b/contrib/libstdc++/src/mt_allocator.cc index da0b09c..6738953 100644 --- a/contrib/libstdc++/src/mt_allocator.cc +++ b/contrib/libstdc++/src/mt_allocator.cc @@ -107,11 +107,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) _Bin_record& __bin = _M_bin[__which]; char* __c = __p - _M_get_align(); - _Block_record* __block = reinterpret_cast<_Block_record*>(__c); + _Block_record* __block_record = reinterpret_cast<_Block_record*>(__c); // Single threaded application - return to global pool. - __block->_M_next = __bin._M_first[0]; - __bin._M_first[0] = __block; + __block_record->_M_next = __bin._M_first[0]; + __bin._M_first[0] = __block_record; } char* @@ -134,22 +134,22 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) __bin._M_address = __address; char* __c = static_cast<char*>(__v) + sizeof(_Block_address); - _Block_record* __block = reinterpret_cast<_Block_record*>(__c); - __bin._M_first[__thread_id] = __block; + _Block_record* __block_record = reinterpret_cast<_Block_record*>(__c); + __bin._M_first[__thread_id] = __block_record; while (--__block_count > 0) { __c += __bin_size; - __block->_M_next = reinterpret_cast<_Block_record*>(__c); - __block = __block->_M_next; + __block_record->_M_next = reinterpret_cast<_Block_record*>(__c); + __block_record = __block_record->_M_next; } - __block->_M_next = NULL; + __block_record->_M_next = NULL; - __block = __bin._M_first[__thread_id]; - __bin._M_first[__thread_id] = __block->_M_next; + __block_record = __bin._M_first[__thread_id]; + __bin._M_first[__thread_id] = __block_record->_M_next; // NB: For alignment reasons, we can't use the first _M_align // bytes, even when sizeof(_Block_record) < _M_align. - return reinterpret_cast<char*>(__block) + __options._M_align; + return reinterpret_cast<char*>(__block_record) + __options._M_align; } void @@ -256,7 +256,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) // Know __p not null, assume valid block. char* __c = __p - _M_get_align(); - _Block_record* __block = reinterpret_cast<_Block_record*>(__c); + _Block_record* __block_record = reinterpret_cast<_Block_record*>(__c); if (__gthread_active_p()) { // Calculate the number of records to remove from our freelist: @@ -313,13 +313,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) // Return this block to our list and update counters and // owner id as needed. - if (__block->_M_thread_id == __thread_id) + if (__block_record->_M_thread_id == __thread_id) --__bin._M_used[__thread_id]; else - __atomic_add(&__reclaimed_base[__block->_M_thread_id], 1); + __atomic_add(&__reclaimed_base[__block_record->_M_thread_id], 1); - __block->_M_next = __bin._M_first[__thread_id]; - __bin._M_first[__thread_id] = __block; + __block_record->_M_next = __bin._M_first[__thread_id]; + __bin._M_first[__thread_id] = __block_record; ++__bin._M_free[__thread_id]; } @@ -327,8 +327,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) { // Not using threads, so single threaded application - return // to global pool. - __block->_M_next = __bin._M_first[0]; - __bin._M_first[0] = __block; + __block_record->_M_next = __bin._M_first[0]; + __bin._M_first[0] = __block_record; } } @@ -354,7 +354,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) // blocks on global list (and if not add new ones) and // get the first one. _Bin_record& __bin = _M_bin[__which]; - _Block_record* __block = NULL; + _Block_record* __block_record = NULL; if (__gthread_active_p()) { // Resync the _M_used counters. @@ -378,16 +378,16 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) // No need to hold the lock when we are adding a whole // chunk to our own list. char* __c = static_cast<char*>(__v) + sizeof(_Block_address); - __block = reinterpret_cast<_Block_record*>(__c); + __block_record = reinterpret_cast<_Block_record*>(__c); __bin._M_free[__thread_id] = __block_count; - __bin._M_first[__thread_id] = __block; + __bin._M_first[__thread_id] = __block_record; while (--__block_count > 0) { __c += __bin_size; - __block->_M_next = reinterpret_cast<_Block_record*>(__c); - __block = __block->_M_next; + __block_record->_M_next = reinterpret_cast<_Block_record*>(__c); + __block_record = __block_record->_M_next; } - __block->_M_next = NULL; + __block_record->_M_next = NULL; } else { @@ -405,11 +405,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) { __bin._M_free[__thread_id] = __block_count; __bin._M_free[0] -= __block_count; - __block = __bin._M_first[0]; + __block_record = __bin._M_first[0]; while (--__block_count > 0) - __block = __block->_M_next; - __bin._M_first[0] = __block->_M_next; - __block->_M_next = NULL; + __block_record = __block_record->_M_next; + __bin._M_first[0] = __block_record->_M_next; + __block_record->_M_next = NULL; } __gthread_mutex_unlock(__bin._M_mutex); } @@ -423,30 +423,30 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) __bin._M_address = __address; char* __c = static_cast<char*>(__v) + sizeof(_Block_address); - __block = reinterpret_cast<_Block_record*>(__c); - __bin._M_first[0] = __block; + __block_record = reinterpret_cast<_Block_record*>(__c); + __bin._M_first[0] = __block_record; while (--__block_count > 0) { __c += __bin_size; - __block->_M_next = reinterpret_cast<_Block_record*>(__c); - __block = __block->_M_next; + __block_record->_M_next = reinterpret_cast<_Block_record*>(__c); + __block_record = __block_record->_M_next; } - __block->_M_next = NULL; + __block_record->_M_next = NULL; } - __block = __bin._M_first[__thread_id]; - __bin._M_first[__thread_id] = __block->_M_next; + __block_record = __bin._M_first[__thread_id]; + __bin._M_first[__thread_id] = __block_record->_M_next; if (__gthread_active_p()) { - __block->_M_thread_id = __thread_id; + __block_record->_M_thread_id = __thread_id; --__bin._M_free[__thread_id]; ++__bin._M_used[__thread_id]; } // NB: For alignment reasons, we can't use the first _M_align // bytes, even when sizeof(_Block_record) < _M_align. - return reinterpret_cast<char*>(__block) + __options._M_align; + return reinterpret_cast<char*>(__block_record) + __options._M_align; } void |