summaryrefslogtreecommitdiffstats
path: root/contrib/gcc
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2013-12-12 18:15:32 +0000
committerpfg <pfg@FreeBSD.org>2013-12-12 18:15:32 +0000
commit4bda5ad442033e7431a147e520f5977706e24fa2 (patch)
tree7b6b120517c1009026b40fb07c5e9346ae61871f /contrib/gcc
parent465403a5cc91e82c71efd87f017455ae0609eb30 (diff)
downloadFreeBSD-src-4bda5ad442033e7431a147e520f5977706e24fa2.zip
FreeBSD-src-4bda5ad442033e7431a147e520f5977706e24fa2.tar.gz
MFC r258081, r258138, r258143, r258179, r258157, r258204, 258205,
r258206, r258207, r258321 This is a series of commits inspired on Google's gcc-4.2.1 for Android that were taken from the gcc pre-4.3 under the GPLv2. gcc: Backport fixes for -W parentheses in C++ This fixes GCC 19564. gcc: merge rs6000 change from FSF pre-gcc43 Don't set MASK_PPC_GFXOPT for 8540 or 8548. Merge vrp-tree fix from gcc-4.3 Fix missed conversion from / to >> (GCC PR32521) Merge in GCCr120505 to include definition of TREE_OVERFLOW_P gcc: warn about integer overflow in constant expressions in the C++ frontend. gcc: Add a new option -Wvla to warn variable length array. libcpp: preprocessor speedup patches from upstream gcc. gcc: add femit-struct-debug support to reduce Reduce dwarf debug size gcc: Fix postreload-gcse treatment of call-clobbered registers. gcc: Record some previous commits in the ChangeLog.gcc43 file.
Diffstat (limited to 'contrib/gcc')
-rw-r--r--contrib/gcc/ChangeLog.gcc43132
-rw-r--r--contrib/gcc/c-common.c92
-rw-r--r--contrib/gcc/c-common.h3
-rw-r--r--contrib/gcc/c-decl.c67
-rw-r--r--contrib/gcc/c-opts.c12
-rw-r--r--contrib/gcc/c-typeck.c68
-rw-r--r--contrib/gcc/c.opt16
-rw-r--r--contrib/gcc/config/rs6000/rs6000.c6
-rw-r--r--contrib/gcc/cp/cp-lang.c2
-rw-r--r--contrib/gcc/cp/cp-tree.h6
-rw-r--r--contrib/gcc/cp/decl.c15
-rw-r--r--contrib/gcc/cp/parser.c101
-rw-r--r--contrib/gcc/cp/pt.c15
-rw-r--r--contrib/gcc/cp/semantics.c10
-rw-r--r--contrib/gcc/cp/tree.c8
-rw-r--r--contrib/gcc/cp/typeck.c49
-rw-r--r--contrib/gcc/doc/invoke.texi105
-rw-r--r--contrib/gcc/dwarf2out.c44
-rw-r--r--contrib/gcc/flags.h20
-rw-r--r--contrib/gcc/langhooks-def.h2
-rw-r--r--contrib/gcc/langhooks.h4
-rw-r--r--contrib/gcc/opts.c254
-rw-r--r--contrib/gcc/postreload-gcse.c141
-rw-r--r--contrib/gcc/regs.h36
-rw-r--r--contrib/gcc/rtlanal.c4
-rw-r--r--contrib/gcc/tree-vrp.c2
-rw-r--r--contrib/gcc/tree.h5
27 files changed, 970 insertions, 249 deletions
diff --git a/contrib/gcc/ChangeLog.gcc43 b/contrib/gcc/ChangeLog.gcc43
index 05f0107..3b3b3db 100644
--- a/contrib/gcc/ChangeLog.gcc43
+++ b/contrib/gcc/ChangeLog.gcc43
@@ -1,9 +1,35 @@
-2007-06-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de> (r23479)
+2007-08-08 Andrew Haley <aph@redhat.com> (r128087)
+
+ * config/arm/libunwind.S (UNWIND_WRAPPER _Unwind_Backtrace): New.
+ * config/arm/unwind-arm.h (__gnu_Unwind_Backtrace): New.
+ * config/arm/unwind-arm.c (__gnu_Unwind_Backtrace): New.
+
+2007-06-05 Joerg Wunsch <j.gnu@uriah.heep.sax.de> (r125346)
PR preprocessor/23479
* doc/extend.texi: Document the 0b-prefixed binary integer
constant extension.
+2007-05-24 Richard Sandiford <rsandifo@nildram.co.uk> (r125037)
+
+ * postreload-gcse.c (reg_changed_after_insn_p): New function.
+ (oprs_unchanged_p): Use it to check all registers in a REG.
+ (record_opr_changes): Look for clobbers in CALL_INSN_FUNCTION_USAGE.
+ (reg_set_between_after_reload_p): Delete.
+ (reg_used_between_after_reload_p): Likewise.
+ (reg_set_or_used_since_bb_start): Likewise.
+ (eliminate_partially_redundant_load): Use reg_changed_after_insn_p
+ and reg_used_between_p instead of reg_set_or_used_since_bb_start.
+ Use reg_set_between_p instead of reg_set_between_after_reload_p.
+ * rtlanal.c (reg_set_p): Check whether REG overlaps
+ regs_invalidated_by_call, rather than just checking the
+ membership of REGNO (REG).
+
+2007-05-03 Ian Lance Taylor <iant@google.com> (r124381)
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Don't set
+ MASK_PPC_GFXOPT for 8540 or 8548.
+
2007-05-01 Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> (r124341)
* doc/invoke.texi: Fix typo, 'AMD Family 10h core' instead of
@@ -22,6 +48,57 @@
alignment for amdfam10 architecture. Increasing the max loop
alignment to 24 bytes.
+2007-04-16 Lawrence Crowl <crowl@google.com>
+
+ * doc/invoke.texi (Debugging Options): Add documentation for the
+ -femit-struct-debug options -femit-struct-debug-baseonly,
+ -femit-struct-debug-reduced, and
+ -femit-struct-debug-detailed[=...].
+
+ * c-opts.c (c_common_handle_option): Add
+ OPT_femit_struct_debug_baseonly, OPT_femit_struct_debug_reduced,
+ and OPT_femit_struct_debug_detailed_.
+ * c.opt: Add specifications for
+ -femit-struct-debug-baseonly, -femit-struct-debug-reduced,
+ and -femit-struct-debug-detailed[=...].
+ * opts.c (set_struct_debug_option): Parse the
+ -femit-struct-debug-... options.
+ * opts.c (matches_main_base, main_input_basename,
+ main_input_baselength, base_of_path, matches_main_base): Add
+ variables and functions to compare header base name to compilation
+ unit base name.
+ * opts.c (should_emit_struct_debug): Add to determine to emit a
+ structure based on the option.
+ (dump_struct_debug) Also disabled function to debug this
+ function.
+ * opts.c (handle_options): Save the base name of the
+ compilation unit.
+
+ * langhooks-def.h (LANG_HOOKS_GENERIC_TYPE_P): Define.
+ (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add.
+ This hook indicates if a type is generic. Set it by default
+ to "never generic".
+ * langhooks.h (struct lang_hooks_for_types): Add a new hook
+ to determine if a struct type is generic or not.
+ * cp/cp-tree.h (class_tmpl_impl_spec_p): Declare a C++ hook.
+ * cp/tree.c (class_tmpl_impl_spec_p): Implement the C++ hook.
+ * cp/cp-lang.c (LANG_HOOKS_GENERIC_TYPE_P): Override null C hook
+ with live C++ hook.
+
+ * flags.h (enum debug_info_usage): Add an enumeration to describe
+ a program's use of a structure type.
+ * dwarf2out.c (gen_struct_or_union_type_die): Add a new parameter
+ to indicate the program's usage of the type. Filter structs based
+ on the -femit-struct-debug-... specification.
+ (gen_type_die): Split into two routines, gen_type_die and
+ gen_type_die_with_usage. gen_type_die is now a wrapper
+ that assumes direct usage.
+ (gen_type_die_with_usage): Replace calls to gen_type_die
+ with gen_type_die_with_usage adding the program usage of
+ the referenced type.
+ (dwarf2out_imported_module_or_decl): Suppress struct debug
+ information using should_emit_struct_debug when appropriate.
+
2007-04-12 Richard Guenther <rguenther@suse.de> (r123736)
PR tree-optimization/24689
@@ -44,6 +121,19 @@
* config/i386/i386.c (override_options): Likewise.
* doc/invoke.texi: Likewise.
+2007-03-12 Seongbae Park <seongbae.park@gmail.com>
+
+ * c-decl.c (warn_variable_length_array): New function.
+ Refactored from grokdeclarator to handle warn_vla
+ and handle unnamed array case.
+ (grokdeclarator): Refactored VLA warning case.
+ * c.opt (Wvla): New flag.
+
+2007-03-11 Ian Lance Taylor <iant@google.com> (r122831 - partial)
+
+ * tree-vrp.c (vrp_int_const_binop): Handle PLUS_EXPR and
+ the *_DIV_EXPR codes correctly with overflow infinities.
+
2007-02-09 Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> (r121763)
* config/i386/driver-i386.c: Turn on -mtune=native for AMDFAM10.
@@ -232,6 +322,17 @@
* config.gcc: Support core2 processor.
+2006-12-13 Ian Lance Taylor <iant@google.com> (r119855)
+
+ PR c++/19564
+ PR c++/19756
+ * c-typeck.c (parser_build_binary_op): Move parentheses warnings
+ to warn_about_parentheses in c-common.c.
+ * c-common.c (warn_about_parentheses): New function.
+ * c-common.h (warn_about_parentheses): Declare.
+ * doc/invoke.texi (Warning Options): Update -Wparentheses
+ description.
+
2006-12-02 H.J. Lu <hongjiu.lu@intel.com> (r119454 - partial)
PR target/30040
@@ -270,6 +371,35 @@
(override_options): Add entries for Core2.
(ix86_issue_rate): Add case for Core2.
+2006-10-31 Geoffrey Keating <geoffk@apple.com> (r118356)
+
+ * c-decl.c (grokdeclarator): Don't set DECL_EXTERNAL on
+ inline static functions in c99 mode.
+
+ PR 16622
+ * doc/extend.texi (Inline): Update.
+ * c-tree.h (struct language_function): Remove field 'extern_inline'.
+ * c-decl.c (current_extern_inline): Delete.
+ (pop_scope): Adjust test for an undefined nested function.
+ Add warning about undeclared inline function.
+ (diagnose_mismatched_decls): Update comments. Disallow overriding
+ of inline functions in a translation unit in C99. Allow inline
+ declarations in C99 at any time.
+ (merge_decls): Boolize variables. Handle C99 'extern inline'
+ semantics.
+ (grokdeclarator): Set DECL_EXTERNAL here for functions. Handle
+ C99 inline semantics.
+ (start_function): Don't clear current_extern_inline. Don't set
+ DECL_EXTERNAL.
+ (c_push_function_context): Don't push current_extern_inline.
+ (c_pop_function_context): Don't restore current_extern_inline.
+
+ PR 11377
+ * c-typeck.c (build_external_ref): Warn about static variables
+ used in extern inline functions.
+ * c-decl.c (start_decl): Warn about static variables declared
+ in extern inline functions.
+
2006-10-27 Vladimir Makarov <vmakarov@redhat.com> (r118090)
* config/i386/i386.h (TARGET_GEODE):
diff --git a/contrib/gcc/c-common.c b/contrib/gcc/c-common.c
index b5ea608..9a04130 100644
--- a/contrib/gcc/c-common.c
+++ b/contrib/gcc/c-common.c
@@ -2585,9 +2585,13 @@ c_common_truthvalue_conversion (tree expr)
break;
case MODIFY_EXPR:
- if (!TREE_NO_WARNING (expr))
- warning (OPT_Wparentheses,
- "suggest parentheses around assignment used as truth value");
+ if (!TREE_NO_WARNING (expr)
+ && warn_parentheses)
+ {
+ warning (OPT_Wparentheses,
+ "suggest parentheses around assignment used as truth value");
+ TREE_NO_WARNING (expr) = 1;
+ }
break;
default:
@@ -6471,5 +6475,87 @@ warn_array_subscript_with_type_char (tree index)
warning (OPT_Wchar_subscripts, "array subscript has type %<char%>");
}
+/* Implement -Wparentheses for the unexpected C precedence rules, to
+ cover cases like x + y << z which readers are likely to
+ misinterpret. We have seen an expression in which CODE is a binary
+ operator used to combine expressions headed by CODE_LEFT and
+ CODE_RIGHT. CODE_LEFT and CODE_RIGHT may be ERROR_MARK, which
+ means that that side of the expression was not formed using a
+ binary operator, or it was enclosed in parentheses. */
+
+void
+warn_about_parentheses (enum tree_code code, enum tree_code code_left,
+ enum tree_code code_right)
+{
+ if (!warn_parentheses)
+ return;
+
+ if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
+ {
+ if (code_left == PLUS_EXPR || code_left == MINUS_EXPR
+ || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
+ warning (OPT_Wparentheses,
+ "suggest parentheses around + or - inside shift");
+ }
+
+ if (code == TRUTH_ORIF_EXPR)
+ {
+ if (code_left == TRUTH_ANDIF_EXPR
+ || code_right == TRUTH_ANDIF_EXPR)
+ warning (OPT_Wparentheses,
+ "suggest parentheses around && within ||");
+ }
+
+ if (code == BIT_IOR_EXPR)
+ {
+ if (code_left == BIT_AND_EXPR || code_left == BIT_XOR_EXPR
+ || code_left == PLUS_EXPR || code_left == MINUS_EXPR
+ || code_right == BIT_AND_EXPR || code_right == BIT_XOR_EXPR
+ || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
+ warning (OPT_Wparentheses,
+ "suggest parentheses around arithmetic in operand of |");
+ /* Check cases like x|y==z */
+ if (TREE_CODE_CLASS (code_left) == tcc_comparison
+ || TREE_CODE_CLASS (code_right) == tcc_comparison)
+ warning (OPT_Wparentheses,
+ "suggest parentheses around comparison in operand of |");
+ }
+
+ if (code == BIT_XOR_EXPR)
+ {
+ if (code_left == BIT_AND_EXPR
+ || code_left == PLUS_EXPR || code_left == MINUS_EXPR
+ || code_right == BIT_AND_EXPR
+ || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
+ warning (OPT_Wparentheses,
+ "suggest parentheses around arithmetic in operand of ^");
+ /* Check cases like x^y==z */
+ if (TREE_CODE_CLASS (code_left) == tcc_comparison
+ || TREE_CODE_CLASS (code_right) == tcc_comparison)
+ warning (OPT_Wparentheses,
+ "suggest parentheses around comparison in operand of ^");
+ }
+
+ if (code == BIT_AND_EXPR)
+ {
+ if (code_left == PLUS_EXPR || code_left == MINUS_EXPR
+ || code_right == PLUS_EXPR || code_right == MINUS_EXPR)
+ warning (OPT_Wparentheses,
+ "suggest parentheses around + or - in operand of &");
+ /* Check cases like x&y==z */
+ if (TREE_CODE_CLASS (code_left) == tcc_comparison
+ || TREE_CODE_CLASS (code_right) == tcc_comparison)
+ warning (OPT_Wparentheses,
+ "suggest parentheses around comparison in operand of &");
+ }
+
+ /* Similarly, check for cases like 1<=i<=10 that are probably errors. */
+ if (TREE_CODE_CLASS (code) == tcc_comparison
+ && (TREE_CODE_CLASS (code_left) == tcc_comparison
+ || TREE_CODE_CLASS (code_right) == tcc_comparison))
+ warning (OPT_Wparentheses, "comparisons like X<=Y<=Z do not "
+ "have their mathematical meaning");
+}
+
#include "gt-c-common.h"
diff --git a/contrib/gcc/c-common.h b/contrib/gcc/c-common.h
index 633990a..eea0f35 100644
--- a/contrib/gcc/c-common.h
+++ b/contrib/gcc/c-common.h
@@ -850,6 +850,9 @@ extern int complete_array_type (tree *, tree, bool);
extern tree builtin_type_for_size (int, bool);
extern void warn_array_subscript_with_type_char (tree);
+extern void warn_about_parentheses (enum tree_code, enum tree_code,
+ enum tree_code);
+
/* In c-gimplify.c */
extern void c_genericize (tree);
diff --git a/contrib/gcc/c-decl.c b/contrib/gcc/c-decl.c
index fbafc0d..68ee23b 100644
--- a/contrib/gcc/c-decl.c
+++ b/contrib/gcc/c-decl.c
@@ -3931,6 +3931,61 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
}
+
+/* Print warning about variable length array if necessary. */
+
+static void
+warn_variable_length_array (const char *name, tree size)
+{
+ int ped = !flag_isoc99 && pedantic && warn_vla != 0;
+ int const_size = TREE_CONSTANT (size);
+
+ if (ped)
+ {
+ if (const_size)
+ {
+ if (name)
+ pedwarn ("ISO C90 forbids array %qs whose size "
+ "can%'t be evaluated",
+ name);
+ else
+ pedwarn ("ISO C90 forbids array whose size "
+ "can%'t be evaluated");
+ }
+ else
+ {
+ if (name)
+ pedwarn ("ISO C90 forbids variable length array %qs",
+ name);
+ else
+ pedwarn ("ISO C90 forbids variable length array");
+ }
+ }
+ else if (warn_vla > 0)
+ {
+ if (const_size)
+ {
+ if (name)
+ warning (OPT_Wvla,
+ "the size of array %qs can"
+ "%'t be evaluated", name);
+ else
+ warning (OPT_Wvla,
+ "the size of array can %'t be evaluated");
+ }
+ else
+ {
+ if (name)
+ warning (OPT_Wvla,
+ "variable length array %qs is used",
+ name);
+ else
+ warning (OPT_Wvla,
+ "variable length array is used");
+ }
+ }
+}
+
/* Given declspecs and a declarator,
determine the name and type of the object declared
and construct a ..._DECL node for it.
@@ -4329,17 +4384,7 @@ grokdeclarator (const struct c_declarator *declarator,
nonconstant even if it is (eg) a const variable
with known value. */
size_varies = 1;
-
- if (!flag_isoc99 && pedantic)
- {
- if (TREE_CONSTANT (size))
- pedwarn ("ISO C90 forbids array %qs whose size "
- "can%'t be evaluated",
- name);
- else
- pedwarn ("ISO C90 forbids variable-size array %qs",
- name);
- }
+ warn_variable_length_array (orig_name, size);
if (warn_variable_decl)
warning (0, "variable-sized array %qs", name);
}
diff --git a/contrib/gcc/c-opts.c b/contrib/gcc/c-opts.c
index 3e89ec2..7f19374 100644
--- a/contrib/gcc/c-opts.c
+++ b/contrib/gcc/c-opts.c
@@ -818,6 +818,18 @@ c_common_handle_option (size_t scode, const char *arg, int value)
flag_gen_declaration = 1;
break;
+ case OPT_femit_struct_debug_baseonly:
+ set_struct_debug_option ("base");
+ break;
+
+ case OPT_femit_struct_debug_reduced:
+ set_struct_debug_option ("dir:ord:sys,dir:gen:any,ind:base");
+ break;
+
+ case OPT_femit_struct_debug_detailed_:
+ set_struct_debug_option (arg);
+ break;
+
case OPT_idirafter:
add_path (xstrdup (arg), AFTER, 0, true);
break;
diff --git a/contrib/gcc/c-typeck.c b/contrib/gcc/c-typeck.c
index b2906ee..e10a222 100644
--- a/contrib/gcc/c-typeck.c
+++ b/contrib/gcc/c-typeck.c
@@ -2631,73 +2631,7 @@ parser_build_binary_op (enum tree_code code, struct c_expr arg1,
/* Check for cases such as x+y<<z which users are likely
to misinterpret. */
if (warn_parentheses)
- {
- if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
- {
- if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
- || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
- warning (OPT_Wparentheses,
- "suggest parentheses around + or - inside shift");
- }
-
- if (code == TRUTH_ORIF_EXPR)
- {
- if (code1 == TRUTH_ANDIF_EXPR
- || code2 == TRUTH_ANDIF_EXPR)
- warning (OPT_Wparentheses,
- "suggest parentheses around && within ||");
- }
-
- if (code == BIT_IOR_EXPR)
- {
- if (code1 == BIT_AND_EXPR || code1 == BIT_XOR_EXPR
- || code1 == PLUS_EXPR || code1 == MINUS_EXPR
- || code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR
- || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
- warning (OPT_Wparentheses,
- "suggest parentheses around arithmetic in operand of |");
- /* Check cases like x|y==z */
- if (TREE_CODE_CLASS (code1) == tcc_comparison
- || TREE_CODE_CLASS (code2) == tcc_comparison)
- warning (OPT_Wparentheses,
- "suggest parentheses around comparison in operand of |");
- }
-
- if (code == BIT_XOR_EXPR)
- {
- if (code1 == BIT_AND_EXPR
- || code1 == PLUS_EXPR || code1 == MINUS_EXPR
- || code2 == BIT_AND_EXPR
- || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
- warning (OPT_Wparentheses,
- "suggest parentheses around arithmetic in operand of ^");
- /* Check cases like x^y==z */
- if (TREE_CODE_CLASS (code1) == tcc_comparison
- || TREE_CODE_CLASS (code2) == tcc_comparison)
- warning (OPT_Wparentheses,
- "suggest parentheses around comparison in operand of ^");
- }
-
- if (code == BIT_AND_EXPR)
- {
- if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
- || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
- warning (OPT_Wparentheses,
- "suggest parentheses around + or - in operand of &");
- /* Check cases like x&y==z */
- if (TREE_CODE_CLASS (code1) == tcc_comparison
- || TREE_CODE_CLASS (code2) == tcc_comparison)
- warning (OPT_Wparentheses,
- "suggest parentheses around comparison in operand of &");
- }
- /* Similarly, check for cases like 1<=i<=10 that are probably errors. */
- if (TREE_CODE_CLASS (code) == tcc_comparison
- && (TREE_CODE_CLASS (code1) == tcc_comparison
- || TREE_CODE_CLASS (code2) == tcc_comparison))
- warning (OPT_Wparentheses, "comparisons like X<=Y<=Z do not "
- "have their mathematical meaning");
-
- }
+ warn_about_parentheses (code, code1, code2);
/* Warn about comparisons against string literals, with the exception
of testing for equality or inequality of a string literal with NULL. */
diff --git a/contrib/gcc/c.opt b/contrib/gcc/c.opt
index 038fc51..820e5c9 100644
--- a/contrib/gcc/c.opt
+++ b/contrib/gcc/c.opt
@@ -432,6 +432,10 @@ Wvariadic-macros
C ObjC C++ ObjC++
Do not warn about using variadic macros when -pedantic
+Wvla
+C ObjC C++ ObjC++ Var(warn_vla) Init(-1) Warning
+Warn if a variable length array is used
+
Wwrite-strings
C ObjC C++ ObjC++ Var(warn_write_strings)
In C++, nonzero means warn about deprecated conversion from string literals to `char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard.
@@ -761,6 +765,18 @@ gen-decls
ObjC ObjC++
Dump declarations to a .decl file
+femit-struct-debug-baseonly
+C ObjC C++ ObjC++
+-femit-struct-debug-baseonly Aggressive reduced debug info for structs
+
+femit-struct-debug-reduced
+C ObjC C++ ObjC++
+-femit-struct-debug-reduced Conservative reduced debug info for structs
+
+femit-struct-debug-detailed=
+C ObjC C++ ObjC++ Joined
+-femit-struct-debug-detailed=<spec-list> Detailed reduced debug info for structs
+
idirafter
C ObjC C++ ObjC++ Joined Separate
-idirafter <dir> Add <dir> to the end of the system include path
diff --git a/contrib/gcc/config/rs6000/rs6000.c b/contrib/gcc/config/rs6000/rs6000.c
index c7efad5..350ecfa 100644
--- a/contrib/gcc/config/rs6000/rs6000.c
+++ b/contrib/gcc/config/rs6000/rs6000.c
@@ -1171,11 +1171,9 @@ rs6000_override_options (const char *default_cpu)
{"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
{"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
{"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
- {"8540", PROCESSOR_PPC8540,
- POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_STRICT_ALIGN},
+ {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN},
/* 8548 has a dummy entry for now. */
- {"8548", PROCESSOR_PPC8540,
- POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_STRICT_ALIGN},
+ {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN},
{"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
{"970", PROCESSOR_POWER4,
POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
diff --git a/contrib/gcc/cp/cp-lang.c b/contrib/gcc/cp/cp-lang.c
index 6050327..c33d488 100644
--- a/contrib/gcc/cp/cp-lang.c
+++ b/contrib/gcc/cp/cp-lang.c
@@ -44,6 +44,8 @@ static void cp_init_ts (void);
#define LANG_HOOKS_NAME "GNU C++"
#undef LANG_HOOKS_INIT
#define LANG_HOOKS_INIT cxx_init
+#undef LANG_HOOKS_GENERIC_TYPE_P
+#define LANG_HOOKS_GENERIC_TYPE_P class_tmpl_impl_spec_p
#undef LANG_HOOKS_DECL_PRINTABLE_NAME
#define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name
#undef LANG_HOOKS_FOLD_OBJ_TYPE_REF
diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h
index deea897..0b30f38 100644
--- a/contrib/gcc/cp/cp-tree.h
+++ b/contrib/gcc/cp/cp-tree.h
@@ -4373,6 +4373,7 @@ extern tree add_stmt_to_compound (tree, tree);
extern tree cxx_maybe_build_cleanup (tree);
extern void init_tree (void);
extern int pod_type_p (tree);
+extern bool class_tmpl_impl_spec_p (tree);
extern int zero_init_p (tree);
extern tree canonical_type_variant (tree);
extern tree copy_binfo (tree, tree, tree,
@@ -4460,8 +4461,9 @@ extern tree build_x_indirect_ref (tree, const char *);
extern tree build_indirect_ref (tree, const char *);
extern tree build_array_ref (tree, tree);
extern tree get_member_function_from_ptrfunc (tree *, tree);
-extern tree build_x_binary_op (enum tree_code, tree, tree,
- bool *);
+extern tree build_x_binary_op (enum tree_code, tree,
+ enum tree_code, tree,
+ enum tree_code, bool *);
extern tree build_x_unary_op (enum tree_code, tree);
extern tree unary_complex_lvalue (enum tree_code, tree);
extern tree build_x_conditional_expr (tree, tree, tree);
diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c
index 4e3c6e9..8b7a488 100644
--- a/contrib/gcc/cp/decl.c
+++ b/contrib/gcc/cp/decl.c
@@ -6702,12 +6702,21 @@ compute_array_index_type (tree name, tree size)
error ("size of array is not an integral constant-expression");
size = integer_one_node;
}
- else if (pedantic)
+ else if (pedantic && warn_vla != 0)
{
if (name)
- pedwarn ("ISO C++ forbids variable-size array %qD", name);
+ pedwarn ("ISO C++ forbids variable length array %qD", name);
else
- pedwarn ("ISO C++ forbids variable-size array");
+ pedwarn ("ISO C++ forbids variable length array");
+ }
+ else if (warn_vla > 0)
+ {
+ if (name)
+ warning (OPT_Wvla,
+ "variable length array %qD is used", name);
+ else
+ warning (OPT_Wvla,
+ "variable length array is used");
}
if (processing_template_decl && !TREE_CONSTANT (size))
diff --git a/contrib/gcc/cp/parser.c b/contrib/gcc/cp/parser.c
index e060d49..edbd37a 100644
--- a/contrib/gcc/cp/parser.c
+++ b/contrib/gcc/cp/parser.c
@@ -1177,8 +1177,15 @@ typedef enum cp_parser_status_kind
typedef struct cp_parser_expression_stack_entry
{
+ /* Left hand side of the binary operation we are currently
+ parsing. */
tree lhs;
+ /* Original tree code for left hand side, if it was a binary
+ expression itself (used for -Wparentheses). */
+ enum tree_code lhs_type;
+ /* Tree code for the binary operation we are parsing. */
enum tree_code tree_type;
+ /* Precedence of the binary operation we are parsing. */
int prec;
} cp_parser_expression_stack_entry;
@@ -1536,7 +1543,7 @@ static tree cp_parser_builtin_offsetof
/* Statements [gram.stmt.stmt] */
static void cp_parser_statement
- (cp_parser *, tree, bool);
+ (cp_parser *, tree, bool, bool *);
static void cp_parser_label_for_labeled_statement
(cp_parser *);
static tree cp_parser_expression_statement
@@ -1546,7 +1553,7 @@ static tree cp_parser_compound_statement
static void cp_parser_statement_seq_opt
(cp_parser *, tree);
static tree cp_parser_selection_statement
- (cp_parser *);
+ (cp_parser *, bool *);
static tree cp_parser_condition
(cp_parser *);
static tree cp_parser_iteration_statement
@@ -1559,7 +1566,7 @@ static void cp_parser_declaration_statement
(cp_parser *);
static tree cp_parser_implicitly_scoped_statement
- (cp_parser *);
+ (cp_parser *, bool *);
static void cp_parser_already_scoped_statement
(cp_parser *);
@@ -5730,12 +5737,13 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p)
cp_parser_expression_stack_entry *sp = &stack[0];
tree lhs, rhs;
cp_token *token;
- enum tree_code tree_type;
+ enum tree_code tree_type, lhs_type, rhs_type;
enum cp_parser_prec prec = PREC_NOT_OPERATOR, new_prec, lookahead_prec;
bool overloaded_p;
/* Parse the first expression. */
lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p);
+ lhs_type = ERROR_MARK;
for (;;)
{
@@ -5768,6 +5776,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p)
/* Extract another operand. It may be the RHS of this expression
or the LHS of a new, higher priority expression. */
rhs = cp_parser_simple_cast_expression (parser);
+ rhs_type = ERROR_MARK;
/* Get another operator token. Look up its precedence to avoid
building a useless (immediately popped) stack entry for common
@@ -5783,8 +5792,10 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p)
sp->prec = prec;
sp->tree_type = tree_type;
sp->lhs = lhs;
+ sp->lhs_type = lhs_type;
sp++;
lhs = rhs;
+ lhs_type = rhs_type;
prec = new_prec;
new_prec = lookahead_prec;
goto get_rhs;
@@ -5801,11 +5812,15 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p)
prec = sp->prec;
tree_type = sp->tree_type;
rhs = lhs;
+ rhs_type = lhs_type;
lhs = sp->lhs;
+ lhs_type = sp->lhs_type;
}
overloaded_p = false;
- lhs = build_x_binary_op (tree_type, lhs, rhs, &overloaded_p);
+ lhs = build_x_binary_op (tree_type, lhs, lhs_type, rhs, rhs_type,
+ &overloaded_p);
+ lhs_type = tree_type;
/* If the binary operator required the use of an overloaded operator,
then this expression cannot be an integral constant-expression.
@@ -6222,17 +6237,23 @@ cp_parser_builtin_offsetof (cp_parser *parser)
try-block
IN_COMPOUND is true when the statement is nested inside a
- cp_parser_compound_statement; this matters for certain pragmas. */
+ cp_parser_compound_statement; this matters for certain pragmas.
+
+ If IF_P is not NULL, *IF_P is set to indicate whether the statement
+ is a (possibly labeled) if statement which is not enclosed in braces
+ and has an else clause. This is used to implement -Wparentheses. */
static void
cp_parser_statement (cp_parser* parser, tree in_statement_expr,
- bool in_compound)
+ bool in_compound, bool *if_p)
{
tree statement;
cp_token *token;
location_t statement_location;
restart:
+ if (if_p != NULL)
+ *if_p = false;
/* There is no statement yet. */
statement = NULL_TREE;
/* Peek at the next token. */
@@ -6257,7 +6278,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
case RID_IF:
case RID_SWITCH:
- statement = cp_parser_selection_statement (parser);
+ statement = cp_parser_selection_statement (parser, if_p);
break;
case RID_WHILE:
@@ -6522,7 +6543,7 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
break;
/* Parse the statement. */
- cp_parser_statement (parser, in_statement_expr, true);
+ cp_parser_statement (parser, in_statement_expr, true, NULL);
}
}
@@ -6533,14 +6554,22 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
if ( condition ) statement else statement
switch ( condition ) statement
- Returns the new IF_STMT or SWITCH_STMT. */
+ Returns the new IF_STMT or SWITCH_STMT.
+
+ If IF_P is not NULL, *IF_P is set to indicate whether the statement
+ is a (possibly labeled) if statement which is not enclosed in
+ braces and has an else clause. This is used to implement
+ -Wparentheses. */
static tree
-cp_parser_selection_statement (cp_parser* parser)
+cp_parser_selection_statement (cp_parser* parser, bool *if_p)
{
cp_token *token;
enum rid keyword;
+ if (if_p != NULL)
+ *if_p = false;
+
/* Peek at the next token. */
token = cp_parser_require (parser, CPP_KEYWORD, "selection-statement");
@@ -6576,11 +6605,13 @@ cp_parser_selection_statement (cp_parser* parser)
if (keyword == RID_IF)
{
+ bool nested_if;
+
/* Add the condition. */
finish_if_stmt_cond (condition, statement);
/* Parse the then-clause. */
- cp_parser_implicitly_scoped_statement (parser);
+ cp_parser_implicitly_scoped_statement (parser, &nested_if);
finish_then_clause (statement);
/* If the next token is `else', parse the else-clause. */
@@ -6591,8 +6622,28 @@ cp_parser_selection_statement (cp_parser* parser)
cp_lexer_consume_token (parser->lexer);
begin_else_clause (statement);
/* Parse the else-clause. */
- cp_parser_implicitly_scoped_statement (parser);
+ cp_parser_implicitly_scoped_statement (parser, NULL);
finish_else_clause (statement);
+
+ /* If we are currently parsing a then-clause, then
+ IF_P will not be NULL. We set it to true to
+ indicate that this if statement has an else clause.
+ This may trigger the Wparentheses warning below
+ when we get back up to the parent if statement. */
+ if (if_p != NULL)
+ *if_p = true;
+ }
+ else
+ {
+ /* This if statement does not have an else clause. If
+ NESTED_IF is true, then the then-clause is an if
+ statement which does have an else clause. We warn
+ about the potential ambiguity. */
+ if (nested_if)
+ warning (OPT_Wparentheses,
+ ("%Hsuggest explicit braces "
+ "to avoid ambiguous %<else%>"),
+ EXPR_LOCUS (statement));
}
/* Now we're all done with the if-statement. */
@@ -6611,7 +6662,7 @@ cp_parser_selection_statement (cp_parser* parser)
in_statement = parser->in_statement;
parser->in_switch_statement_p = true;
parser->in_statement |= IN_SWITCH_STMT;
- cp_parser_implicitly_scoped_statement (parser);
+ cp_parser_implicitly_scoped_statement (parser, NULL);
parser->in_switch_statement_p = in_switch_statement_p;
parser->in_statement = in_statement;
@@ -6789,7 +6840,7 @@ cp_parser_iteration_statement (cp_parser* parser)
statement = begin_do_stmt ();
/* Parse the body of the do-statement. */
parser->in_statement = IN_ITERATION_STMT;
- cp_parser_implicitly_scoped_statement (parser);
+ cp_parser_implicitly_scoped_statement (parser, NULL);
parser->in_statement = in_statement;
finish_do_body (statement);
/* Look for the `while' keyword. */
@@ -7031,13 +7082,21 @@ cp_parser_declaration_statement (cp_parser* parser)
but ensures that is in its own scope, even if it is not a
compound-statement.
+ If IF_P is not NULL, *IF_P is set to indicate whether the statement
+ is a (possibly labeled) if statement which is not enclosed in
+ braces and has an else clause. This is used to implement
+ -Wparentheses.
+
Returns the new statement. */
static tree
-cp_parser_implicitly_scoped_statement (cp_parser* parser)
+cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p)
{
tree statement;
+ if (if_p != NULL)
+ *if_p = false;
+
/* Mark if () ; with a special NOP_EXPR. */
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
{
@@ -7053,7 +7112,7 @@ cp_parser_implicitly_scoped_statement (cp_parser* parser)
/* Create a compound-statement. */
statement = begin_compound_stmt (0);
/* Parse the dependent-statement. */
- cp_parser_statement (parser, NULL_TREE, false);
+ cp_parser_statement (parser, NULL_TREE, false, if_p);
/* Finish the dummy compound-statement. */
finish_compound_stmt (statement);
}
@@ -7072,7 +7131,7 @@ cp_parser_already_scoped_statement (cp_parser* parser)
{
/* If the token is a `{', then we must take special action. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
- cp_parser_statement (parser, NULL_TREE, false);
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
else
{
/* Avoid calling cp_parser_compound_statement, so that we
@@ -18645,7 +18704,7 @@ cp_parser_omp_structured_block (cp_parser *parser)
tree stmt = begin_omp_structured_block ();
unsigned int save = cp_parser_begin_omp_structured_block (parser);
- cp_parser_statement (parser, NULL_TREE, false);
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
cp_parser_end_omp_structured_block (parser, save);
return finish_omp_structured_block (stmt);
@@ -18890,7 +18949,7 @@ cp_parser_omp_for_loop (cp_parser *parser)
/* Note that the grammar doesn't call for a structured block here,
though the loop as a whole is a structured block. */
body = push_stmt_list ();
- cp_parser_statement (parser, NULL_TREE, false);
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
body = pop_stmt_list (body);
return finish_omp_for (loc, decl, init, cond, incr, body, pre_body);
@@ -18983,7 +19042,7 @@ cp_parser_omp_sections_scope (cp_parser *parser)
while (1)
{
- cp_parser_statement (parser, NULL_TREE, false);
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
tok = cp_lexer_peek_token (parser->lexer);
if (tok->pragma_kind == PRAGMA_OMP_SECTION)
diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c
index ac28afa..f12fc7b 100644
--- a/contrib/gcc/cp/pt.c
+++ b/contrib/gcc/cp/pt.c
@@ -9078,7 +9078,13 @@ tsubst_copy_and_build (tree t,
return build_x_binary_op
(TREE_CODE (t),
RECUR (TREE_OPERAND (t, 0)),
+ (TREE_NO_WARNING (TREE_OPERAND (t, 0))
+ ? ERROR_MARK
+ : TREE_CODE (TREE_OPERAND (t, 0))),
RECUR (TREE_OPERAND (t, 1)),
+ (TREE_NO_WARNING (TREE_OPERAND (t, 1))
+ ? ERROR_MARK
+ : TREE_CODE (TREE_OPERAND (t, 1))),
/*overloaded_p=*/NULL);
case SCOPE_REF:
@@ -9087,7 +9093,14 @@ tsubst_copy_and_build (tree t,
case ARRAY_REF:
op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
args, complain, in_decl);
- return build_x_binary_op (ARRAY_REF, op1, RECUR (TREE_OPERAND (t, 1)),
+ return build_x_binary_op (ARRAY_REF, op1,
+ (TREE_NO_WARNING (TREE_OPERAND (t, 0))
+ ? ERROR_MARK
+ : TREE_CODE (TREE_OPERAND (t, 0))),
+ RECUR (TREE_OPERAND (t, 1)),
+ (TREE_NO_WARNING (TREE_OPERAND (t, 1))
+ ? ERROR_MARK
+ : TREE_CODE (TREE_OPERAND (t, 1))),
/*overloaded_p=*/NULL);
case SIZEOF_EXPR:
diff --git a/contrib/gcc/cp/semantics.c b/contrib/gcc/cp/semantics.c
index 9c37b36..ee16e75 100644
--- a/contrib/gcc/cp/semantics.c
+++ b/contrib/gcc/cp/semantics.c
@@ -587,6 +587,16 @@ maybe_convert_cond (tree cond)
/* Do the conversion. */
cond = convert_from_reference (cond);
+
+ if (TREE_CODE (cond) == MODIFY_EXPR
+ && !TREE_NO_WARNING (cond)
+ && warn_parentheses)
+ {
+ warning (OPT_Wparentheses,
+ "suggest parentheses around assignment used as truth value");
+ TREE_NO_WARNING (cond) = 1;
+ }
+
return condition_conversion (cond);
}
diff --git a/contrib/gcc/cp/tree.c b/contrib/gcc/cp/tree.c
index e3391a5..eee9151 100644
--- a/contrib/gcc/cp/tree.c
+++ b/contrib/gcc/cp/tree.c
@@ -1762,6 +1762,14 @@ pod_type_p (tree t)
return 1;
}
+/* Nonzero iff type T is a class template implicit specialization. */
+
+bool
+class_tmpl_impl_spec_p (tree t)
+{
+ return CLASS_TYPE_P (t) && CLASSTYPE_TEMPLATE_INSTANTIATION (t);
+}
+
/* Returns 1 iff zero initialization of type T means actually storing
zeros in it. */
diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c
index 6f07772..dd92b22 100644
--- a/contrib/gcc/cp/typeck.c
+++ b/contrib/gcc/cp/typeck.c
@@ -1690,17 +1690,20 @@ rationalize_conditional_expr (enum tree_code code, tree t)
are equal, so we know what conditional expression this used to be. */
if (TREE_CODE (t) == MIN_EXPR || TREE_CODE (t) == MAX_EXPR)
{
+ tree op0 = TREE_OPERAND (t, 0);
+ tree op1 = TREE_OPERAND (t, 1);
+
/* The following code is incorrect if either operand side-effects. */
- gcc_assert (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 0))
- && !TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)));
+ gcc_assert (!TREE_SIDE_EFFECTS (op0)
+ && !TREE_SIDE_EFFECTS (op1));
return
build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR
? LE_EXPR : GE_EXPR),
- TREE_OPERAND (t, 0),
- TREE_OPERAND (t, 1),
+ op0, TREE_CODE (op0),
+ op1, TREE_CODE (op1),
/*overloaded_p=*/NULL),
- build_unary_op (code, TREE_OPERAND (t, 0), 0),
- build_unary_op (code, TREE_OPERAND (t, 1), 0));
+ build_unary_op (code, op0, 0),
+ build_unary_op (code, op1, 0));
}
return
@@ -2908,8 +2911,8 @@ convert_arguments (tree typelist, tree values, tree fndecl, int flags)
conversions on the operands. CODE is the kind of expression to build. */
tree
-build_x_binary_op (enum tree_code code, tree arg1, tree arg2,
- bool *overloaded_p)
+build_x_binary_op (enum tree_code code, tree arg1, enum tree_code arg1_code,
+ tree arg2, enum tree_code arg2_code, bool *overloaded_p)
{
tree orig_arg1;
tree orig_arg2;
@@ -2933,6 +2936,17 @@ build_x_binary_op (enum tree_code code, tree arg1, tree arg2,
expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
overloaded_p);
+ /* Check for cases such as x+y<<z which users are likely to
+ misinterpret. But don't warn about obj << x + y, since that is a
+ common idiom for I/O. */
+ if (warn_parentheses
+ && !processing_template_decl
+ && !error_operand_p (arg1)
+ && !error_operand_p (arg2)
+ && (code != LSHIFT_EXPR
+ || !IS_AGGR_TYPE (TREE_TYPE (arg1))))
+ warn_about_parentheses (code, arg1_code, arg2_code);
+
if (processing_template_decl && expr != error_mark_node)
return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
@@ -3759,6 +3773,12 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
result = fold_if_not_in_template (result);
if (final_type != 0)
result = cp_convert (final_type, result);
+
+ if (TREE_OVERFLOW_P (result)
+ && !TREE_OVERFLOW_P (op0)
+ && !TREE_OVERFLOW_P (op1))
+ overflow_warning (result);
+
return result;
}
@@ -6280,6 +6300,19 @@ convert_for_assignment (tree type, tree rhs,
errtype);
}
+ /* If -Wparentheses, warn about a = b = c when a has type bool and b
+ does not. */
+ if (warn_parentheses
+ && type == boolean_type_node
+ && TREE_CODE (rhs) == MODIFY_EXPR
+ && !TREE_NO_WARNING (rhs)
+ && TREE_TYPE (rhs) != boolean_type_node)
+ {
+ warning (OPT_Wparentheses,
+ "suggest parentheses around assignment used as truth value");
+ TREE_NO_WARNING (rhs) = 1;
+ }
+
return perform_implicit_conversion (strip_top_quals (type), rhs);
}
diff --git a/contrib/gcc/doc/invoke.texi b/contrib/gcc/doc/invoke.texi
index 13b9ae9..ce6f071 100644
--- a/contrib/gcc/doc/invoke.texi
+++ b/contrib/gcc/doc/invoke.texi
@@ -230,7 +230,8 @@ in the following sections.
-Wsystem-headers -Wtrigraphs -Wundef -Wuninitialized @gol
-Wunknown-pragmas -Wno-pragmas -Wunreachable-code @gol
-Wunused -Wunused-function -Wunused-label -Wunused-parameter @gol
--Wunused-value -Wunused-variable -Wvariadic-macros @gol
+-Wunused-value -Wunused-variable @gol
+-Wvariadic-macros -Wvla @gol
-Wvolatile-register-var -Wwrite-strings}
@item C-only Warning Options
@@ -274,6 +275,8 @@ in the following sections.
-ftest-coverage -ftime-report -fvar-tracking @gol
-g -g@var{level} -gcoff -gdwarf-2 @gol
-ggdb -gstabs -gstabs+ -gvms -gxcoff -gxcoff+ @gol
+-femit-struct-debug-baseonly -femit-struct-debug-reduced @gol
+-femit-struct-debug-detailed@r{[}=@var{spec-list}@r{]} @gol
-p -pg -print-file-name=@var{library} -print-libgcc-file-name @gol
-print-multi-directory -print-multi-lib @gol
-print-prog-name=@var{program} -print-search-dirs -Q @gol
@@ -2212,9 +2215,7 @@ Warn if a user-supplied include directory does not exist.
Warn if parentheses are omitted in certain contexts, such
as when there is an assignment in a context where a truth value
is expected, or when operators are nested whose precedence people
-often get confused about. Only the warning for an assignment used as
-a truth value is supported when compiling C++; the other warnings are
-only supported when compiling C@.
+often get confused about.
Also warn if a comparison like @samp{x<=y<=z} appears; this is
equivalent to @samp{(x<=y ? 1 : 0) <= z}, which is a different
@@ -2236,14 +2237,15 @@ such a case:
@end group
@end smallexample
-In C, every @code{else} branch belongs to the innermost possible @code{if}
-statement, which in this example is @code{if (b)}. This is often not
-what the programmer expected, as illustrated in the above example by
-indentation the programmer chose. When there is the potential for this
-confusion, GCC will issue a warning when this flag is specified.
-To eliminate the warning, add explicit braces around the innermost
-@code{if} statement so there is no way the @code{else} could belong to
-the enclosing @code{if}. The resulting code would look like this:
+In C/C++, every @code{else} branch belongs to the innermost possible
+@code{if} statement, which in this example is @code{if (b)}. This is
+often not what the programmer expected, as illustrated in the above
+example by indentation the programmer chose. When there is the
+potential for this confusion, GCC will issue a warning when this flag
+is specified. To eliminate the warning, add explicit braces around
+the innermost @code{if} statement so there is no way the @code{else}
+could belong to the enclosing @code{if}. The resulting code would
+look like this:
@smallexample
@group
@@ -3202,6 +3204,13 @@ Warn if variadic macros are used in pedantic ISO C90 mode, or the GNU
alternate syntax when in pedantic ISO C99 mode. This is default.
To inhibit the warning messages, use @option{-Wno-variadic-macros}.
+@item -Wvla
+@opindex Wvla
+@opindex Wno-vla
+Warn if variable length array is used in the code.
+@option{-Wno-vla} will prevent the @option{-pedantic} warning of
+the variable length array.
+
@item -Wvolatile-register-var
@opindex Wvolatile-register-var
@opindex Wno-volatile-register-var
@@ -3404,6 +3413,78 @@ Compress DWARF2 debugging information by eliminating duplicated
information about each symbol. This option only makes sense when
generating DWARF2 debugging information with @option{-gdwarf-2}.
+@item -femit-struct-debug-baseonly
+Emit debug information for struct-like types
+only when the base name of the compilation source file
+matches the base name of file in which the struct was defined.
+
+This option substantially reduces the size of debugging information,
+but at significant potential loss in type information to the debugger.
+See @option{-femit-struct-debug-reduced} for a less aggressive option.
+See @option{-femit-struct-debug-detailed} for more detailed control.
+
+This option works only with DWARF 2.
+
+@item -femit-struct-debug-reduced
+Emit debug information for struct-like types
+only when the base name of the compilation source file
+matches the base name of file in which the type was defined,
+unless the struct is a template or defined in a system header.
+
+This option significantly reduces the size of debugging information,
+with some potential loss in type information to the debugger.
+See @option{-femit-struct-debug-baseonly} for a more aggressive option.
+See @option{-femit-struct-debug-detailed} for more detailed control.
+
+This option works only with DWARF 2.
+
+@item -femit-struct-debug-detailed@r{[}=@var{spec-list}@r{]}
+Specify the struct-like types
+for which the compiler will generate debug information.
+The intent is to reduce duplicate struct debug information
+between different object files within the same program.
+
+This option is a detailed version of
+@option{-femit-struct-debug-reduced} and @option{-femit-struct-debug-baseonly},
+which will serve for most needs.
+
+A specification has the syntax
+[@samp{dir:}|@samp{ind:}][@samp{ord:}|@samp{gen:}](@samp{any}|@samp{sys}|@samp{base}|@samp{none})
+
+The optional first word limits the specification to
+structs that are used directly (@samp{dir:}) or used indirectly (@samp{ind:}).
+A struct type is used directly when it is the type of a variable, member.
+Indirect uses arise through pointers to structs.
+That is, when use of an incomplete struct would be legal, the use is indirect.
+An example is
+@samp{struct one direct; struct two * indirect;}.
+
+The optional second word limits the specification to
+ordinary structs (@samp{ord:}) or generic structs (@samp{gen:}).
+Generic structs are a bit complicated to explain.
+For C++, these are non-explicit specializations of template classes,
+or non-template classes within the above.
+Other programming languages have generics,
+but @samp{-femit-struct-debug-detailed} does not yet implement them.
+
+The third word specifies the source files for those
+structs for which the compiler will emit debug information.
+The values @samp{none} and @samp{any} have the normal meaning.
+The value @samp{base} means that
+the base of name of the file in which the type declaration appears
+must match the base of the name of the main compilation file.
+In practice, this means that
+types declared in @file{foo.c} and @file{foo.h} will have debug information,
+but types declared in other header will not.
+The value @samp{sys} means those types satisfying @samp{base}
+or declared in system or compiler headers.
+
+You may need to experiment to determine the best settings for your application.
+
+The default is @samp{-femit-struct-debug-detailed=all}.
+
+This option works only with DWARF 2.
+
@cindex @command{prof}
@item -p
@opindex p
diff --git a/contrib/gcc/dwarf2out.c b/contrib/gcc/dwarf2out.c
index 5e4354a..461990b 100644
--- a/contrib/gcc/dwarf2out.c
+++ b/contrib/gcc/dwarf2out.c
@@ -4215,7 +4215,8 @@ static void gen_ptr_to_mbr_type_die (tree, dw_die_ref);
static dw_die_ref gen_compile_unit_die (const char *);
static void gen_inheritance_die (tree, tree, dw_die_ref);
static void gen_member_die (tree, dw_die_ref);
-static void gen_struct_or_union_type_die (tree, dw_die_ref);
+static void gen_struct_or_union_type_die (tree, dw_die_ref,
+ enum debug_info_usage);
static void gen_subroutine_type_die (tree, dw_die_ref);
static void gen_typedef_die (tree, dw_die_ref);
static void gen_type_die (tree, dw_die_ref);
@@ -12473,7 +12474,8 @@ gen_member_die (tree type, dw_die_ref context_die)
member DIEs needed by later specification DIEs. */
static void
-gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
+gen_struct_or_union_type_die (tree type, dw_die_ref context_die,
+ enum debug_info_usage usage)
{
dw_die_ref type_die = lookup_type_die (type);
dw_die_ref scope_die = 0;
@@ -12482,6 +12484,7 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
&& (! TYPE_STUB_DECL (type)
|| ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))));
int ns_decl = (context_die && context_die->die_tag == DW_TAG_namespace);
+ complete = complete && should_emit_struct_debug (type, usage);
if (type_die && ! complete)
return;
@@ -12609,7 +12612,8 @@ gen_typedef_die (tree decl, dw_die_ref context_die)
/* Generate a type description DIE. */
static void
-gen_type_die (tree type, dw_die_ref context_die)
+gen_type_die_with_usage (tree type, dw_die_ref context_die,
+ enum debug_info_usage usage)
{
int need_pop;
@@ -12657,16 +12661,19 @@ gen_type_die (tree type, dw_die_ref context_die)
/* For these types, all that is required is that we output a DIE (or a
set of DIEs) to represent the "basis" type. */
- gen_type_die (TREE_TYPE (type), context_die);
+ gen_type_die_with_usage (TREE_TYPE (type), context_die,
+ DINFO_USAGE_IND_USE);
break;
case OFFSET_TYPE:
/* This code is used for C++ pointer-to-data-member types.
Output a description of the relevant class type. */
- gen_type_die (TYPE_OFFSET_BASETYPE (type), context_die);
+ gen_type_die_with_usage (TYPE_OFFSET_BASETYPE (type), context_die,
+ DINFO_USAGE_IND_USE);
/* Output a description of the type of the object pointed to. */
- gen_type_die (TREE_TYPE (type), context_die);
+ gen_type_die_with_usage (TREE_TYPE (type), context_die,
+ DINFO_USAGE_IND_USE);
/* Now output a DIE to represent this pointer-to-data-member type
itself. */
@@ -12675,13 +12682,15 @@ gen_type_die (tree type, dw_die_ref context_die)
case FUNCTION_TYPE:
/* Force out return type (in case it wasn't forced out already). */
- gen_type_die (TREE_TYPE (type), context_die);
+ gen_type_die_with_usage (TREE_TYPE (type), context_die,
+ DINFO_USAGE_DIR_USE);
gen_subroutine_type_die (type, context_die);
break;
case METHOD_TYPE:
/* Force out return type (in case it wasn't forced out already). */
- gen_type_die (TREE_TYPE (type), context_die);
+ gen_type_die_with_usage (TREE_TYPE (type), context_die,
+ DINFO_USAGE_DIR_USE);
gen_subroutine_type_die (type, context_die);
break;
@@ -12707,7 +12716,7 @@ gen_type_die (tree type, dw_die_ref context_die)
&& AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
&& ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))
{
- gen_type_die (TYPE_CONTEXT (type), context_die);
+ gen_type_die_with_usage (TYPE_CONTEXT (type), context_die, usage);
if (TREE_ASM_WRITTEN (type))
return;
@@ -12731,7 +12740,7 @@ gen_type_die (tree type, dw_die_ref context_die)
gen_enumeration_type_die (type, context_die);
}
else
- gen_struct_or_union_type_die (type, context_die);
+ gen_struct_or_union_type_die (type, context_die, usage);
if (need_pop)
pop_decl_scope ();
@@ -12760,6 +12769,12 @@ gen_type_die (tree type, dw_die_ref context_die)
TREE_ASM_WRITTEN (type) = 1;
}
+static void
+gen_type_die (tree type, dw_die_ref context_die)
+{
+ gen_type_die_with_usage (type, context_die, DINFO_USAGE_DIR_USE);
+}
+
/* Generate a DIE for a tagged type instantiation. */
static void
@@ -13357,7 +13372,11 @@ dwarf2out_imported_module_or_decl (tree decl, tree context)
if (!context)
scope_die = comp_unit_die;
else if (TYPE_P (context))
+ {
+ if (!should_emit_struct_debug (context, DINFO_USAGE_DIR_USE))
+ return;
scope_die = force_type_die (context);
+ }
else
scope_die = force_decl_die (context);
@@ -13383,7 +13402,12 @@ dwarf2out_imported_module_or_decl (tree decl, tree context)
if (TYPE_CONTEXT (type))
if (TYPE_P (TYPE_CONTEXT (type)))
+ {
+ if (!should_emit_struct_debug (TYPE_CONTEXT (type),
+ DINFO_USAGE_DIR_USE))
+ return;
type_context_die = force_type_die (TYPE_CONTEXT (type));
+ }
else
type_context_die = force_decl_die (TYPE_CONTEXT (type));
else
diff --git a/contrib/gcc/flags.h b/contrib/gcc/flags.h
index 226fb60..d94c76c 100644
--- a/contrib/gcc/flags.h
+++ b/contrib/gcc/flags.h
@@ -23,6 +23,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#ifndef GCC_FLAGS_H
#define GCC_FLAGS_H
+#include "coretypes.h"
#include "options.h"
enum debug_info_type
@@ -54,6 +55,25 @@ enum debug_info_level
/* Specify how much debugging info to generate. */
extern enum debug_info_level debug_info_level;
+/* A major contribution to object and executable size is debug
+ information size. A major contribution to debug information
+ size is struct descriptions replicated in several object files.
+ The following function determines whether or not debug information
+ should be generated for a given struct. The indirect parameter
+ indicates that the struct is being handled indirectly, via
+ a pointer. See opts.c for the implementation. */
+
+enum debug_info_usage
+{
+ DINFO_USAGE_DFN, /* A struct definition. */
+ DINFO_USAGE_DIR_USE, /* A direct use, such as the type of a variable. */
+ DINFO_USAGE_IND_USE, /* An indirect use, such as through a pointer. */
+ DINFO_USAGE_NUM_ENUMS /* The number of enumerators. */
+};
+
+extern bool should_emit_struct_debug (tree type_decl, enum debug_info_usage);
+extern void set_struct_debug_option (const char *value);
+
/* Nonzero means use GNU-only extensions in the generated symbolic
debugging information. */
extern bool use_gnu_debug_info_extensions;
diff --git a/contrib/gcc/langhooks-def.h b/contrib/gcc/langhooks-def.h
index eae7c92..633642c 100644
--- a/contrib/gcc/langhooks-def.h
+++ b/contrib/gcc/langhooks-def.h
@@ -217,6 +217,7 @@ extern tree lhd_make_node (enum tree_code);
so we create a compile-time error instead. */
#define LANG_HOOKS_MAKE_TYPE lhd_make_node
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error
+#define LANG_HOOKS_GENERIC_TYPE_P hook_bool_tree_false
#define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
#define LANG_HOOKS_TYPE_MAX_SIZE lhd_return_null_tree
@@ -231,6 +232,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_UNSIGNED_TYPE, \
LANG_HOOKS_SIGNED_TYPE, \
LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE, \
+ LANG_HOOKS_GENERIC_TYPE_P, \
LANG_HOOKS_TYPE_PROMOTES_TO, \
LANG_HOOKS_REGISTER_BUILTIN_TYPE, \
LANG_HOOKS_INCOMPLETE_TYPE_ERROR, \
diff --git a/contrib/gcc/langhooks.h b/contrib/gcc/langhooks.h
index e614893..1254c63 100644
--- a/contrib/gcc/langhooks.h
+++ b/contrib/gcc/langhooks.h
@@ -119,6 +119,10 @@ struct lang_hooks_for_types
according to UNSIGNEDP. */
tree (*signed_or_unsigned_type) (int, tree);
+ /* True if the type is an instantiation of a generic type,
+ e.g. C++ template implicit specializations. */
+ bool (*generic_p) (tree);
+
/* Given a type, apply default promotions to unnamed function
arguments and return the new type. Return the same type if no
change. Required by any language that supports variadic
diff --git a/contrib/gcc/opts.c b/contrib/gcc/opts.c
index fb122ba..1ded3c7 100644
--- a/contrib/gcc/opts.c
+++ b/contrib/gcc/opts.c
@@ -79,6 +79,256 @@ enum debug_info_type write_symbols = NO_DEBUG;
the definitions of the different possible levels. */
enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
+/* A major contribution to object and executable size is debug
+ information size. A major contribution to debug information size
+ is struct descriptions replicated in several object files. The
+ following flags attempt to reduce this information. The basic
+ idea is to not emit struct debugging information in the current
+ compilation unit when that information will be generated by
+ another compilation unit.
+
+ Debug information for a struct defined in the current source
+ file should be generated in the object file. Likewise the
+ debug information for a struct defined in a header should be
+ generated in the object file of the corresponding source file.
+ Both of these case are handled when the base name of the file of
+ the struct definition matches the base name of the source file
+ of thet current compilation unit. This matching emits minimal
+ struct debugging information.
+
+ The base file name matching rule above will fail to emit debug
+ information for structs defined in system headers. So a second
+ category of files includes system headers in addition to files
+ with matching bases.
+
+ The remaining types of files are library headers and application
+ headers. We cannot currently distinguish these two types. */
+
+enum debug_struct_file
+{
+ DINFO_STRUCT_FILE_NONE, /* Debug no structs. */
+ DINFO_STRUCT_FILE_BASE, /* Debug structs defined in files with the
+ same base name as the compilation unit. */
+ DINFO_STRUCT_FILE_SYS, /* Also debug structs defined in system
+ header files. */
+ DINFO_STRUCT_FILE_ANY /* Debug structs defined in all files. */
+};
+
+/* Generic structs (e.g. templates not explicitly specialized)
+ may not have a compilation unit associated with them, and so
+ may need to be treated differently from ordinary structs.
+
+ Structs only handled by reference (indirectly), will also usually
+ not need as much debugging information. */
+
+static enum debug_struct_file debug_struct_ordinary[DINFO_USAGE_NUM_ENUMS]
+ = { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY };
+static enum debug_struct_file debug_struct_generic[DINFO_USAGE_NUM_ENUMS]
+ = { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY };
+
+/* Parse the -femit-struct-debug-detailed option value
+ and set the flag variables. */
+
+#define MATCH( prefix, string ) \
+ ((strncmp (prefix, string, sizeof prefix - 1) == 0) \
+ ? ((string += sizeof prefix - 1), 1) : 0)
+
+void
+set_struct_debug_option (const char *spec)
+{
+ /* various labels for comparison */
+ static char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
+ static char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
+ static char none_lbl[] = "none", any_lbl[] = "any";
+ static char base_lbl[] = "base", sys_lbl[] = "sys";
+
+ enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
+ /* Default is to apply to as much as possible. */
+ enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
+ int ord = 1, gen = 1;
+
+ /* What usage? */
+ if (MATCH (dfn_lbl, spec))
+ usage = DINFO_USAGE_DFN;
+ else if (MATCH (dir_lbl, spec))
+ usage = DINFO_USAGE_DIR_USE;
+ else if (MATCH (ind_lbl, spec))
+ usage = DINFO_USAGE_IND_USE;
+
+ /* Generics or not? */
+ if (MATCH (ord_lbl, spec))
+ gen = 0;
+ else if (MATCH (gen_lbl, spec))
+ ord = 0;
+
+ /* What allowable environment? */
+ if (MATCH (none_lbl, spec))
+ files = DINFO_STRUCT_FILE_NONE;
+ else if (MATCH (any_lbl, spec))
+ files = DINFO_STRUCT_FILE_ANY;
+ else if (MATCH (sys_lbl, spec))
+ files = DINFO_STRUCT_FILE_SYS;
+ else if (MATCH (base_lbl, spec))
+ files = DINFO_STRUCT_FILE_BASE;
+ else
+ error ("argument %qs to %<-femit-struct-debug-detailed%> not recognized",
+ spec);
+
+ /* Effect the specification. */
+ if (usage == DINFO_USAGE_NUM_ENUMS)
+ {
+ if (ord)
+ {
+ debug_struct_ordinary[DINFO_USAGE_DFN] = files;
+ debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
+ debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
+ }
+ if (gen)
+ {
+ debug_struct_generic[DINFO_USAGE_DFN] = files;
+ debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
+ debug_struct_generic[DINFO_USAGE_IND_USE] = files;
+ }
+ }
+ else
+ {
+ if (ord)
+ debug_struct_ordinary[usage] = files;
+ if (gen)
+ debug_struct_generic[usage] = files;
+ }
+
+ if (*spec == ',')
+ set_struct_debug_option (spec+1);
+ else
+ {
+ /* No more -femit-struct-debug-detailed specifications.
+ Do final checks. */
+ if (*spec != '\0')
+ error ("argument %qs to %<-femit-struct-debug-detailed%> unknown",
+ spec);
+ if (debug_struct_ordinary[DINFO_USAGE_DIR_USE]
+ < debug_struct_ordinary[DINFO_USAGE_IND_USE]
+ || debug_struct_generic[DINFO_USAGE_DIR_USE]
+ < debug_struct_generic[DINFO_USAGE_IND_USE])
+ error ("%<-femit-struct-debug-detailed=dir:...%> must allow at least"
+ " as much as %<-femit-struct-debug-detailed=ind:...%>");
+ }
+}
+
+/* Find the base name of a path, stripping off both directories and
+ a single final extension. */
+static int
+base_of_path (const char *path, const char **base_out)
+{
+ const char *base = path;
+ const char *dot = 0;
+ const char *p = path;
+ char c = *p;
+ while (c)
+ {
+ if (IS_DIR_SEPARATOR(c))
+ {
+ base = p + 1;
+ dot = 0;
+ }
+ else if (c == '.')
+ dot = p;
+ c = *++p;
+ }
+ if (!dot)
+ dot = p;
+ *base_out = base;
+ return dot - base;
+}
+
+/* Match the base name of a file to the base name of a compilation unit. */
+
+static const char *main_input_basename;
+static int main_input_baselength;
+
+static int
+matches_main_base (const char *path)
+{
+ /* Cache the last query. */
+ static const char *last_path = NULL;
+ static int last_match = 0;
+ if (path != last_path)
+ {
+ const char *base;
+ int length = base_of_path (path, &base);
+ last_path = path;
+ last_match = (length == main_input_baselength
+ && memcmp (base, main_input_basename, length) == 0);
+ }
+ return last_match;
+}
+
+#ifdef DEBUG_DEBUG_STRUCT
+
+static int
+dump_struct_debug (tree type, enum debug_info_usage usage,
+ enum debug_struct_file criterion, int generic,
+ int matches, int result)
+{
+ /* Find the type name. */
+ tree type_decl = TYPE_STUB_DECL (type);
+ tree t = type_decl;
+ const char *name = 0;
+ if (TREE_CODE (t) == TYPE_DECL)
+ t = DECL_NAME (t);
+ if (t)
+ name = IDENTIFIER_POINTER (t);
+
+ fprintf (stderr, " struct %d %s %s %s %s %d %p %s\n",
+ criterion,
+ DECL_IN_SYSTEM_HEADER (type_decl) ? "sys" : "usr",
+ matches ? "bas" : "hdr",
+ generic ? "gen" : "ord",
+ usage == DINFO_USAGE_DFN ? ";" :
+ usage == DINFO_USAGE_DIR_USE ? "." : "*",
+ result,
+ (void*) type_decl, name);
+ return result;
+}
+#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \
+ dump_struct_debug (type, usage, criterion, generic, matches, result)
+
+#else
+
+#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \
+ (result)
+
+#endif
+
+
+bool
+should_emit_struct_debug (tree type, enum debug_info_usage usage)
+{
+ enum debug_struct_file criterion;
+ tree type_decl;
+ bool generic = lang_hooks.types.generic_p (type);
+
+ if (generic)
+ criterion = debug_struct_generic[usage];
+ else
+ criterion = debug_struct_ordinary[usage];
+
+ if (criterion == DINFO_STRUCT_FILE_NONE)
+ return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
+ if (criterion == DINFO_STRUCT_FILE_ANY)
+ return DUMP_GSTRUCT (type, usage, criterion, generic, false, true);
+
+ type_decl = TYPE_STUB_DECL (type);
+
+ if (criterion == DINFO_STRUCT_FILE_SYS && DECL_IN_SYSTEM_HEADER (type_decl))
+ return DUMP_GSTRUCT (type, usage, criterion, generic, false, true);
+
+ if (matches_main_base (DECL_SOURCE_FILE (type_decl)))
+ return DUMP_GSTRUCT (type, usage, criterion, generic, true, true);
+ return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
+}
+
/* Nonzero means use GNU-only extensions in the generated symbolic
debugging information. Currently, this only has an effect when
write_symbols is set to DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */
@@ -370,7 +620,11 @@ handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
if (opt[0] != '-' || opt[1] == '\0')
{
if (main_input_filename == NULL)
+ {
main_input_filename = opt;
+ main_input_baselength
+ = base_of_path (main_input_filename, &main_input_basename);
+ }
add_input_filename (opt);
n = 1;
continue;
diff --git a/contrib/gcc/postreload-gcse.c b/contrib/gcc/postreload-gcse.c
index 76b7b8c..3e3f805 100644
--- a/contrib/gcc/postreload-gcse.c
+++ b/contrib/gcc/postreload-gcse.c
@@ -197,8 +197,6 @@ static void dump_hash_table (FILE *);
static bool reg_killed_on_edge (rtx, edge);
static bool reg_used_on_edge (rtx, edge);
-static rtx reg_set_between_after_reload_p (rtx, rtx, rtx);
-static rtx reg_used_between_after_reload_p (rtx, rtx, rtx);
static rtx get_avail_load_store_reg (rtx);
static bool bb_has_well_behaved_predecessors (basic_block);
@@ -470,6 +468,22 @@ dump_hash_table (FILE *file)
fprintf (file, "\n");
}
+/* Return true if register X is recorded as being set by an instruction
+ whose CUID is greater than the one given. */
+
+static bool
+reg_changed_after_insn_p (rtx x, int cuid)
+{
+ unsigned int regno, end_regno;
+
+ regno = REGNO (x);
+ end_regno = END_HARD_REGNO (x);
+ do
+ if (reg_avail_info[regno] > cuid)
+ return true;
+ while (++regno < end_regno);
+ return false;
+}
/* Return nonzero if the operands of expression X are unchanged
1) from the start of INSN's basic block up to but not including INSN
@@ -493,14 +507,9 @@ oprs_unchanged_p (rtx x, rtx insn, bool after_insn)
/* We are called after register allocation. */
gcc_assert (REGNO (x) < FIRST_PSEUDO_REGISTER);
if (after_insn)
- /* If the last CUID setting the insn is less than the CUID of
- INSN, then reg X is not changed in or after INSN. */
- return reg_avail_info[REGNO (x)] < INSN_CUID (insn);
+ return !reg_changed_after_insn_p (x, INSN_CUID (insn) - 1);
else
- /* Reg X is not set before INSN in the current basic block if
- we have not yet recorded the CUID of an insn that touches
- the reg. */
- return reg_avail_info[REGNO (x)] == 0;
+ return !reg_changed_after_insn_p (x, 0);
case MEM:
if (load_killed_in_block_p (INSN_CUID (insn), x, after_insn))
@@ -717,12 +726,28 @@ record_opr_changes (rtx insn)
/* Finally, if this is a call, record all call clobbers. */
if (CALL_P (insn))
{
- unsigned int regno;
+ unsigned int regno, end_regno;
+ rtx link, x;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
record_last_reg_set_info (insn, regno);
+ for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
+ if (GET_CODE (XEXP (link, 0)) == CLOBBER)
+ {
+ x = XEXP (XEXP (link, 0), 0);
+ if (REG_P (x))
+ {
+ gcc_assert (HARD_REGISTER_P (x));
+ regno = REGNO (x);
+ end_regno = END_HARD_REGNO (x);
+ do
+ record_last_reg_set_info (insn, regno);
+ while (++regno < end_regno);
+ }
+ }
+
if (! CONST_OR_PURE_CALL_P (insn))
record_last_mem_set_info (insn);
}
@@ -856,96 +881,6 @@ reg_used_on_edge (rtx reg, edge e)
return false;
}
-
-/* Return the insn that sets register REG or clobbers it in between
- FROM_INSN and TO_INSN (exclusive of those two).
- Just like reg_set_between but for hard registers and not pseudos. */
-
-static rtx
-reg_set_between_after_reload_p (rtx reg, rtx from_insn, rtx to_insn)
-{
- rtx insn;
-
- /* We are called after register allocation. */
- gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
-
- if (from_insn == to_insn)
- return NULL_RTX;
-
- for (insn = NEXT_INSN (from_insn);
- insn != to_insn;
- insn = NEXT_INSN (insn))
- if (INSN_P (insn))
- {
- if (set_of (reg, insn) != NULL_RTX)
- return insn;
- if ((CALL_P (insn)
- && call_used_regs[REGNO (reg)])
- || find_reg_fusage (insn, CLOBBER, reg))
- return insn;
-
- if (FIND_REG_INC_NOTE (insn, reg))
- return insn;
- }
-
- return NULL_RTX;
-}
-
-/* Return the insn that uses register REG in between FROM_INSN and TO_INSN
- (exclusive of those two). Similar to reg_used_between but for hard
- registers and not pseudos. */
-
-static rtx
-reg_used_between_after_reload_p (rtx reg, rtx from_insn, rtx to_insn)
-{
- rtx insn;
-
- /* We are called after register allocation. */
- gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
-
- if (from_insn == to_insn)
- return NULL_RTX;
-
- for (insn = NEXT_INSN (from_insn);
- insn != to_insn;
- insn = NEXT_INSN (insn))
- if (INSN_P (insn))
- {
- if (reg_overlap_mentioned_p (reg, PATTERN (insn))
- || (CALL_P (insn)
- && call_used_regs[REGNO (reg)])
- || find_reg_fusage (insn, USE, reg)
- || find_reg_fusage (insn, CLOBBER, reg))
- return insn;
-
- if (FIND_REG_INC_NOTE (insn, reg))
- return insn;
- }
-
- return NULL_RTX;
-}
-
-/* Return true if REG is used, set, or killed between the beginning of
- basic block BB and UP_TO_INSN. Caches the result in reg_avail_info. */
-
-static bool
-reg_set_or_used_since_bb_start (rtx reg, basic_block bb, rtx up_to_insn)
-{
- rtx insn, start = PREV_INSN (BB_HEAD (bb));
-
- if (reg_avail_info[REGNO (reg)] != 0)
- return true;
-
- insn = reg_used_between_after_reload_p (reg, start, up_to_insn);
- if (! insn)
- insn = reg_set_between_after_reload_p (reg, start, up_to_insn);
-
- if (insn)
- reg_avail_info[REGNO (reg)] = INSN_CUID (insn);
-
- return insn != NULL_RTX;
-}
-
/* Return the loaded/stored register of a load/store instruction. */
static rtx
@@ -1037,7 +972,8 @@ eliminate_partially_redundant_load (basic_block bb, rtx insn,
/* Check that the loaded register is not used, set, or killed from the
beginning of the block. */
- if (reg_set_or_used_since_bb_start (dest, bb, insn))
+ if (reg_changed_after_insn_p (dest, 0)
+ || reg_used_between_p (dest, PREV_INSN (BB_HEAD (bb)), insn))
return;
/* Check potential for replacing load with copy for predecessors. */
@@ -1068,8 +1004,7 @@ eliminate_partially_redundant_load (basic_block bb, rtx insn,
avail_insn = NULL;
continue;
}
- if (! reg_set_between_after_reload_p (avail_reg, avail_insn,
- next_pred_bb_end))
+ if (!reg_set_between_p (avail_reg, avail_insn, next_pred_bb_end))
/* AVAIL_INSN remains non-null. */
break;
else
diff --git a/contrib/gcc/regs.h b/contrib/gcc/regs.h
index ee074b9..ed0725a 100644
--- a/contrib/gcc/regs.h
+++ b/contrib/gcc/regs.h
@@ -239,5 +239,41 @@ extern void allocate_reg_info (size_t, int, int);
/* Specify number of hard registers given machine mode occupy. */
extern unsigned char hard_regno_nregs[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
+/* Return an exclusive upper bound on the registers occupied by hard
+ register (reg:MODE REGNO). */
+
+static inline unsigned int
+end_hard_regno (enum machine_mode mode, unsigned int regno)
+{
+ return regno + hard_regno_nregs[regno][(int) mode];
+}
+
+/* Likewise for hard register X. */
+
+#define END_HARD_REGNO(X) end_hard_regno (GET_MODE (X), REGNO (X))
+
+/* Likewise for hard or pseudo register X. */
+
+#define END_REGNO(X) (HARD_REGISTER_P (X) ? END_HARD_REGNO (X) : REGNO (X) + 1)
+
+
+/* Return true if (reg:MODE REGNO) includes an element of REGS. */
+
+static inline bool
+overlaps_hard_reg_set_p (const HARD_REG_SET regs, enum machine_mode mode,
+ unsigned int regno)
+{
+ unsigned int end_regno;
+
+ if (TEST_HARD_REG_BIT (regs, regno))
+ return true;
+
+ end_regno = end_hard_regno (mode, regno);
+ while (++regno < end_regno)
+ if (TEST_HARD_REG_BIT (regs, regno))
+ return true;
+
+ return false;
+}
#endif /* GCC_REGS_H */
diff --git a/contrib/gcc/rtlanal.c b/contrib/gcc/rtlanal.c
index 54f2f72..4e513e8 100644
--- a/contrib/gcc/rtlanal.c
+++ b/contrib/gcc/rtlanal.c
@@ -748,8 +748,8 @@ reg_set_p (rtx reg, rtx insn)
|| (CALL_P (insn)
&& ((REG_P (reg)
&& REGNO (reg) < FIRST_PSEUDO_REGISTER
- && TEST_HARD_REG_BIT (regs_invalidated_by_call,
- REGNO (reg)))
+ && overlaps_hard_reg_set_p (regs_invalidated_by_call,
+ GET_MODE (reg), REGNO (reg)))
|| MEM_P (reg)
|| find_reg_fusage (insn, CLOBBER, reg)))))
return 1;
diff --git a/contrib/gcc/tree-vrp.c b/contrib/gcc/tree-vrp.c
index 4626485..0c9824d 100644
--- a/contrib/gcc/tree-vrp.c
+++ b/contrib/gcc/tree-vrp.c
@@ -4914,7 +4914,7 @@ simplify_div_or_mod_using_ranges (tree stmt, tree rhs, enum tree_code rhs_code)
{
bool sop = false;
- val = compare_range_with_value (GT_EXPR, vr, integer_zero_node, &sop);
+ val = compare_range_with_value (GE_EXPR, vr, integer_zero_node, &sop);
if (val
&& sop
diff --git a/contrib/gcc/tree.h b/contrib/gcc/tree.h
index 97090be..4075ab0 100644
--- a/contrib/gcc/tree.h
+++ b/contrib/gcc/tree.h
@@ -1084,6 +1084,11 @@ extern void omp_clause_range_check_failed (const tree, const char *, int,
#define TREE_OVERFLOW(NODE) (CST_CHECK (NODE)->common.public_flag)
+/* TREE_OVERFLOW can only be true for EXPR of CONSTANT_CLASS_P. */
+
+#define TREE_OVERFLOW_P(EXPR) \
+ (CONSTANT_CLASS_P (EXPR) && TREE_OVERFLOW (EXPR))
+
/* In a VAR_DECL, FUNCTION_DECL, NAMESPACE_DECL or TYPE_DECL,
nonzero means name is to be accessible from outside this module.
In an IDENTIFIER_NODE, nonzero means an external declaration
OpenPOWER on IntegriCloud