1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-29 08:08:37 +00:00

gcc: Bring updates from Google's enhanced gcc-4.2.1.

Google released and enhanced version of gcc-4.2.1 plus their local
patches for Android[1].

The patches are owned by Google and the license hasn't been changed
from  the original GPLv2. We are only bringing a subset of the
available patches that may be helpful in FreeBSD. Changes specific
to android are not included.

From the README.google file[1].

Patches applied to google_vendor_src_branch/gcc/gcc-4.2.1:

gcc/Makefile.in
gcc/c-common.c
gcc/c-common.h
gcc/c-opts.c
gcc/c-typeck.c
gcc/cp/typeck.c
gcc/doc/invoke.texi
gcc/flags.h
gcc/opts.c
gcc/tree-flow.h
gcc/tree-ssa-alias-warnings.c
gcc/tree-ssa-alias.c

 Backport of -Wstrict-aliasing from mainline.
  Silvius Rus <rus@google.com>

gcc/coverage.c:
  Patch coverage_checksum_string for PR 25351.
  Seongbae Park <spark@google.com>
  Not yet submitted to FSF.

gcc/c-opts.c
gcc/c-ppoutput.c
gcc/c.opt
gcc/doc/cppopts.texi
libcpp/Makefile.in
libcpp/directives-only.c
libcpp/directives.c
libcpp/files.c
libcpp/include/cpplib.h
libcpp/init.c
libcpp/internal.h
libcpp/macro.c
  Support for -fdirectives-only.
  Ollie Wild <aaw@google.com>.
  Submitted to FSF but not yet approved.

libstdc++-v3/include/ext/hashtable.h
  http://b/742065
  http://b/629994
  Reduce min size of hashtable for hash_map, hash_set from 53 to 5

libstdc++-v3/include/ext/hashtable.h
  http://b/629994
  Do not iterate over buckets if hashtable is empty.

gcc/common.opt
gcc/doc/invoke.texi
gcc/flags.h
gcc/gimplify.c
gcc/opts.c
  Add Saito's patch for -finstrument-functions-exclude-* options.

gcc/common.opt
gcc/doc/invoke.texi
gcc/final.c
gcc/flags.h
gcc/opts.c
gcc/testsuite/gcc.dg/Wframe-larger-than.c
  Add a new flag -Wframe-larger-than- which enables a new warning
  when a frame size of a function is larger than specified.
  This patch hasn't been integrated into gcc mainline yet.

gcc/tree-vrp.c
  Add a hack to avoid using ivopts information for pointers starting
  at constant values.

Reference:

[1]
https://android.googlesource.com/toolchain/gcc/+/master/gcc-4.2.1/

Obtained from:	Google Inc.
MFC after:	3 weeks
This commit is contained in:
Pedro F. Giffuni 2013-11-23 18:32:53 +00:00
parent 0a9655a082
commit 81e5b01765
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=258501
28 changed files with 1860 additions and 159 deletions

View File

@ -983,35 +983,67 @@ unsigned_conversion_warning (tree result, tree operand)
strict aliasing mode is in effect. OTYPE is the original
TREE_TYPE of EXPR, and TYPE the type we're casting to. */
void
bool
strict_aliasing_warning (tree otype, tree type, tree expr)
{
if (flag_strict_aliasing && warn_strict_aliasing
&& POINTER_TYPE_P (type) && POINTER_TYPE_P (otype)
&& TREE_CODE (expr) == ADDR_EXPR
if (!(flag_strict_aliasing && POINTER_TYPE_P (type)
&& POINTER_TYPE_P (otype) && !VOID_TYPE_P (TREE_TYPE (type))))
return false;
if ((warn_strict_aliasing > 1) && TREE_CODE (expr) == ADDR_EXPR
&& (DECL_P (TREE_OPERAND (expr, 0))
|| handled_component_p (TREE_OPERAND (expr, 0)))
&& !VOID_TYPE_P (TREE_TYPE (type)))
|| handled_component_p (TREE_OPERAND (expr, 0))))
{
/* Casting the address of an object to non void pointer. Warn
if the cast breaks type based aliasing. */
if (!COMPLETE_TYPE_P (TREE_TYPE (type)))
warning (OPT_Wstrict_aliasing, "type-punning to incomplete type "
"might break strict-aliasing rules");
if (!COMPLETE_TYPE_P (TREE_TYPE (type)) && warn_strict_aliasing == 2)
{
warning (OPT_Wstrict_aliasing, "type-punning to incomplete type "
"might break strict-aliasing rules");
return true;
}
else
{
HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
/* warn_strict_aliasing >= 3. This includes the default (3).
Only warn if the cast is dereferenced immediately. */
HOST_WIDE_INT set1 =
get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type));
if (!alias_sets_conflict_p (set1, set2))
warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
"pointer will break strict-aliasing rules");
else if (warn_strict_aliasing > 1
&& !alias_sets_might_conflict_p (set1, set2))
warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
"pointer might break strict-aliasing rules");
{
warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
"pointer will break strict-aliasing rules");
return true;
}
else if (warn_strict_aliasing == 2
&& !alias_sets_might_conflict_p (set1, set2))
{
warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
"pointer might break strict-aliasing rules");
return true;
}
}
}
else
if ((warn_strict_aliasing == 1) && !VOID_TYPE_P (TREE_TYPE (otype)))
{
/* At this level, warn for any conversions, even if an address is
not taken in the same statement. This will likely produce many
false positives, but could be useful to pinpoint problems that
are not revealed at higher levels. */
HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (otype));
HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type));
if (!COMPLETE_TYPE_P(type)
|| !alias_sets_might_conflict_p (set1, set2))
{
warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
"pointer might break strict-aliasing rules");
return true;
}
}
return false;
}
@ -3108,6 +3140,85 @@ def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
builtin_types[def] = t;
}
/* Build builtin functions common to both C and C++ language
frontends. */
static void
c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node)
{
#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
builtin_types[ENUM] = VALUE;
#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
def_fn_type (ENUM, RETURN, 0, 0);
#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
def_fn_type (ENUM, RETURN, 0, 1, ARG1);
#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
#define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
#define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6) \
def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7) \
def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
def_fn_type (ENUM, RETURN, 1, 0);
#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
def_fn_type (ENUM, RETURN, 1, 1, ARG1);
#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
#define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
#define DEF_POINTER_TYPE(ENUM, TYPE) \
builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
#include "builtin-types.def"
#undef DEF_PRIMITIVE_TYPE
#undef DEF_FUNCTION_TYPE_1
#undef DEF_FUNCTION_TYPE_2
#undef DEF_FUNCTION_TYPE_3
#undef DEF_FUNCTION_TYPE_4
#undef DEF_FUNCTION_TYPE_5
#undef DEF_FUNCTION_TYPE_6
#undef DEF_FUNCTION_TYPE_VAR_0
#undef DEF_FUNCTION_TYPE_VAR_1
#undef DEF_FUNCTION_TYPE_VAR_2
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
#undef DEF_POINTER_TYPE
builtin_types[(int) BT_LAST] = NULL_TREE;
c_init_attributes ();
#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
NONANSI_P, ATTRS, IMPLICIT, COND) \
if (NAME && COND) \
def_builtin_1 (ENUM, NAME, CLASS, \
builtin_types[(int) TYPE], \
builtin_types[(int) LIBTYPE], \
BOTH_P, FALLBACK_P, NONANSI_P, \
built_in_attributes[(int) ATTRS], IMPLICIT);
#include "builtins.def"
#undef DEF_BUILTIN
build_common_builtin_nodes ();
targetm.init_builtins ();
if (flag_mudflap)
mudflap_init ();
}
/* Build tree nodes and builtin functions common to both C and C++ language
frontends. */
@ -3320,77 +3431,8 @@ c_common_nodes_and_builtins (void)
va_list_ref_type_node = build_reference_type (va_list_type_node);
}
#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
builtin_types[ENUM] = VALUE;
#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
def_fn_type (ENUM, RETURN, 0, 0);
#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
def_fn_type (ENUM, RETURN, 0, 1, ARG1);
#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
#define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
#define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6) \
def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
ARG6, ARG7) \
def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
def_fn_type (ENUM, RETURN, 1, 0);
#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
def_fn_type (ENUM, RETURN, 1, 1, ARG1);
#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
#define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
#define DEF_POINTER_TYPE(ENUM, TYPE) \
builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
#include "builtin-types.def"
#undef DEF_PRIMITIVE_TYPE
#undef DEF_FUNCTION_TYPE_1
#undef DEF_FUNCTION_TYPE_2
#undef DEF_FUNCTION_TYPE_3
#undef DEF_FUNCTION_TYPE_4
#undef DEF_FUNCTION_TYPE_5
#undef DEF_FUNCTION_TYPE_6
#undef DEF_FUNCTION_TYPE_VAR_0
#undef DEF_FUNCTION_TYPE_VAR_1
#undef DEF_FUNCTION_TYPE_VAR_2
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
#undef DEF_POINTER_TYPE
builtin_types[(int) BT_LAST] = NULL_TREE;
c_init_attributes ();
#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
NONANSI_P, ATTRS, IMPLICIT, COND) \
if (NAME && COND) \
def_builtin_1 (ENUM, NAME, CLASS, \
builtin_types[(int) TYPE], \
builtin_types[(int) LIBTYPE], \
BOTH_P, FALLBACK_P, NONANSI_P, \
built_in_attributes[(int) ATTRS], IMPLICIT);
#include "builtins.def"
#undef DEF_BUILTIN
build_common_builtin_nodes ();
targetm.init_builtins ();
if (flag_mudflap)
mudflap_init ();
if (!flag_preprocess_only)
c_define_builtins (va_list_ref_type_node, va_list_arg_type_node);
main_identifier_node = get_identifier ("main");

View File

@ -654,7 +654,7 @@ extern void binary_op_error (enum tree_code);
extern tree fix_string_type (tree);
struct varray_head_tag;
extern void constant_expression_warning (tree);
extern void strict_aliasing_warning(tree, tree, tree);
extern bool strict_aliasing_warning (tree, tree, tree);
extern void empty_body_warning (tree, tree);
extern tree convert_and_check (tree, tree);
extern void overflow_warning (tree);

View File

@ -396,7 +396,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
if (c_dialect_cxx ())
warn_sign_compare = value;
warn_switch = value;
warn_strict_aliasing = value;
set_warn_strict_aliasing (value);
warn_strict_overflow = value;
warn_address = value;
@ -606,6 +606,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
disable_builtin_function (arg);
break;
case OPT_fdirectives_only:
cpp_opts->directives_only = 1;
break;
case OPT_fdollars_in_identifiers:
cpp_opts->dollars_in_ident = value;
break;
@ -1329,6 +1333,11 @@ sanitize_cpp_opts (void)
if (flag_dump_macros == 'M')
flag_no_output = 1;
/* By default, -fdirectives-only implies -dD. This allows subsequent phases
to perform proper macro expansion. */
if (cpp_opts->directives_only && !cpp_opts->preprocessed && !flag_dump_macros)
flag_dump_macros = 'D';
/* Disable -dD, -dN and -dI if normal output is suppressed. Allow
-dM since at least glibc relies on -M -dM to work. */
/* Also, flag_no_output implies flag_no_line_commands, always. */
@ -1359,6 +1368,14 @@ sanitize_cpp_opts (void)
actually output the current directory? */
if (flag_working_directory == -1)
flag_working_directory = (debug_info_level != DINFO_LEVEL_NONE);
if (cpp_opts->directives_only)
{
if (warn_unused_macros)
error ("-fdirectives-only is incompatible with -Wunused_macros");
if (cpp_opts->traditional)
error ("-fdirectives-only is incompatible with -traditional");
}
}
/* Add include path with a prefix at the front of its name. */
@ -1442,6 +1459,8 @@ finish_options (void)
}
}
}
else if (cpp_opts->directives_only)
cpp_init_special_builtins (parse_in);
include_cursor = 0;
push_command_line_include ();

View File

@ -41,6 +41,8 @@ static struct
/* General output routines. */
static void scan_translation_unit (cpp_reader *);
static void print_lines_directives_only (int, const void *, size_t);
static void scan_translation_unit_directives_only (cpp_reader *);
static void scan_translation_unit_trad (cpp_reader *);
static void account_for_newlines (const unsigned char *, size_t);
static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
@ -75,6 +77,9 @@ preprocess_file (cpp_reader *pfile)
}
else if (cpp_get_options (pfile)->traditional)
scan_translation_unit_trad (pfile);
else if (cpp_get_options (pfile)->directives_only
&& !cpp_get_options (pfile)->preprocessed)
scan_translation_unit_directives_only (pfile);
else
scan_translation_unit (pfile);
@ -179,6 +184,26 @@ scan_translation_unit (cpp_reader *pfile)
}
}
static void
print_lines_directives_only (int lines, const void *buf, size_t size)
{
print.src_line += lines;
fwrite (buf, 1, size, print.outf);
}
/* Writes out the preprocessed file, handling spacing and paste
avoidance issues. */
static void
scan_translation_unit_directives_only (cpp_reader *pfile)
{
struct _cpp_dir_only_callbacks cb;
cb.print_lines = print_lines_directives_only;
cb.maybe_print_line = maybe_print_line;
_cpp_preprocess_dir_only (pfile, &cb);
}
/* Adjust print.src_line for newlines embedded in output. */
static void
account_for_newlines (const unsigned char *str, size_t len)

View File

@ -1876,6 +1876,19 @@ build_indirect_ref (tree ptr, const char *errorstring)
if (TREE_CODE (type) == POINTER_TYPE)
{
if (TREE_CODE (pointer) == CONVERT_EXPR
|| TREE_CODE (pointer) == NOP_EXPR
|| TREE_CODE (pointer) == VIEW_CONVERT_EXPR)
{
/* If a warning is issued, mark it to avoid duplicates from
the backend. This only needs to be done at
warn_strict_aliasing > 2. */
if (warn_strict_aliasing > 2)
if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (pointer, 0)),
type, TREE_OPERAND (pointer, 0)))
TREE_NO_WARNING (pointer) = 1;
}
if (TREE_CODE (pointer) == ADDR_EXPR
&& (TREE_TYPE (TREE_OPERAND (pointer, 0))
== TREE_TYPE (type)))
@ -3562,7 +3575,8 @@ build_c_cast (tree type, tree expr)
warning (OPT_Wint_to_pointer_cast, "cast to pointer from integer "
"of different size");
strict_aliasing_warning (otype, type, expr);
if (warn_strict_aliasing <= 2)
strict_aliasing_warning (otype, type, expr);
/* If pedantic, warn for conversions between function and object
pointer types, except for converting a null pointer constant

View File

@ -494,6 +494,10 @@ fdefault-inline
C++ ObjC++
Inline member functions by default
fdirectives-only
C ObjC C++ ObjC++
Preprocess directives only.
fdollars-in-identifiers
C ObjC C++ ObjC++
Permit '$' as an identifier character

View File

@ -95,7 +95,11 @@ Warn when an inlined function cannot be inlined
Wlarger-than-
Common RejectNegative Joined UInteger
-Wlarger-than-<number> Warn if an object is larger than <number> bytes
-Wlarger-than-<number> Warn if an object is larger than <number> bytes
Wframe-larger-than-
Common RejectNegative Joined UInteger
-Wframe-larger-than-<number> Warn if the frame size of a function is larger than <number> bytes
Wunsafe-loop-optimizations
Common Var(warn_unsafe_loop_optimizations)
@ -537,6 +541,14 @@ finstrument-functions
Common Report Var(flag_instrument_function_entry_exit)
Instrument function entry and exit with profiling calls
finstrument-functions-exclude-function-list=
Common RejectNegative Joined
-finstrument-functions-exclude-function-list=name,... Do not instrument listed functions
finstrument-functions-exclude-file-list=
Common RejectNegative Joined
-finstrument-functions-exclude-file-list=filename,... Do not instrument functions listed in files
fipa-cp
Common Report Var(flag_ipa_cp)
Perform Interprocedural constant propagation

View File

@ -429,57 +429,75 @@ tree_coverage_counter_ref (unsigned counter, unsigned no)
static unsigned
coverage_checksum_string (unsigned chksum, const char *string)
{
int i;
char *dup = NULL;
char *ptr;
/* Look for everything that looks if it were produced by
get_file_function_name and zero out the second part
that may result from flag_random_seed. This is not critical
as the checksums are used only for sanity checking. */
for (i = 0; string[i]; i++)
#define GLOBAL_PREFIX "_GLOBAL__"
#define TRAILING_N "N_"
#define ISCAPXDIGIT(a) (((a) >= '0' && (a) <= '9') || ((a) >= 'A' && (a) <= 'F'))
if ((ptr = strstr (string, GLOBAL_PREFIX)))
{
int offset = 0;
if (!strncmp (string + i, "_GLOBAL__N_", 11))
offset = 11;
if (!strncmp (string + i, "_GLOBAL__", 9))
offset = 9;
/* Skip _GLOBAL__. */
ptr += strlen (GLOBAL_PREFIX);
/* C++ namespaces do have scheme:
_GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
since filename might contain extra underscores there seems
to be no better chance then walk all possible offsets looking
for magicnuber. */
if (offset)
{
for (i = i + offset; string[i]; i++)
if (string[i]=='_')
{
int y;
/* Skip optional N_ (in case __GLOBAL_N__). */
if (!strncmp (ptr, TRAILING_N, strlen (TRAILING_N)))
ptr += strlen (TRAILING_N);
/* At this point, ptr should point after "_GLOBAL__N_" or "_GLOBAL__". */
for (y = 1; y < 9; y++)
if (!(string[i + y] >= '0' && string[i + y] <= '9')
&& !(string[i + y] >= 'A' && string[i + y] <= 'F'))
break;
if (y != 9 || string[i + 9] != '_')
continue;
for (y = 10; y < 18; y++)
if (!(string[i + y] >= '0' && string[i + y] <= '9')
&& !(string[i + y] >= 'A' && string[i + y] <= 'F'))
break;
if (y != 18)
continue;
if (!dup)
string = dup = xstrdup (string);
for (y = 10; y < 18; y++)
dup[i + y] = '0';
}
break;
}
while ((ptr = strchr (ptr, '_')) != NULL)
{
int y;
/* For every "_" in the rest of the string,
try the follwing pattern matching */
/* Skip over '_'. */
ptr++;
#define NDIGITS (8)
/* Try matching the pattern:
<8-digit hex>_<8-digit hex>
The second number is randomly generated
so we want to mask it out before computing the checksum. */
for (y = 0; *ptr != 0 && y < NDIGITS; y++, ptr++)
if (!ISCAPXDIGIT (*ptr))
break;
if (y != NDIGITS || *ptr != '_')
continue;
/* Skip over '_' again. */
ptr++;
for (y = 0; *ptr != 0 && y < NDIGITS; y++, ptr++)
if (!ISCAPXDIGIT (*ptr))
break;
if (y == NDIGITS)
{
/* We have a match.
Duplicate the string and mask out
the second 8-digit number. */
dup = xstrdup (string);
ptr = dup + (ptr - string);
for(y = -NDIGITS - 1 ; y < 0; y++)
{
ptr[y] = '0';
}
ptr = dup;
break;
}
}
/* "ptr" should be NULL if we couldn't find the match
(strchr will return NULL if no match is found),
or it should point to dup which contains the string
with the random part masked. */
}
chksum = crc32_string (chksum, string);
chksum = crc32_string (chksum, (ptr) ? ptr : string);
if (dup)
free (dup);
free (dup);
return chksum;
}

View File

@ -2334,6 +2334,19 @@ build_indirect_ref (tree ptr, const char *errorstring)
types. */
tree t = canonical_type_variant (TREE_TYPE (type));
if (TREE_CODE (ptr) == CONVERT_EXPR
|| TREE_CODE (ptr) == NOP_EXPR
|| TREE_CODE (ptr) == VIEW_CONVERT_EXPR)
{
/* If a warning is issued, mark it to avoid duplicates from
the backend. This only needs to be done at
warn_strict_aliasing > 2. */
if (warn_strict_aliasing > 2)
if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (ptr, 0)),
type, TREE_OPERAND (ptr, 0)))
TREE_NO_WARNING (ptr) = 1;
}
if (VOID_TYPE_P (t))
{
/* A pointer to incomplete type (other than cv void) can be
@ -5256,7 +5269,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
/* We need to strip nops here, because the frontend likes to
create (int *)&a for array-to-pointer decay, instead of &a[0]. */
STRIP_NOPS (sexpr);
strict_aliasing_warning (intype, type, sexpr);
if (warn_strict_aliasing <= 2)
strict_aliasing_warning (intype, type, sexpr);
return fold_if_not_in_template (build_nop (type, expr));
}

View File

@ -506,6 +506,22 @@ Search @var{dir} only for header files requested with
@xref{Search Path}.
@end ifset
@item -fdirectives-only
@opindex fdirectives-only
This option provides a simplified preprocessor to improve the
performance of distributed build systems such as distcc. It's
behavior depends on a number of other flags.
If the @option{-E} option is enabled, it suppresses things like macro
expansion, trigraph conversion, and escaped newline splicing
outside of directives. All directives are processed normally, except that
macro definitions are output similar to the @option{-dD} option.
If the @option{-fpreprocessed} option is enabled, it suppresses
predefinition of most builtin and command line macros. This
prevents duplicate definition of macros output with the @option{-E}
option.
@item -fdollars-in-identifiers
@opindex fdollars-in-identifiers
@anchor{fdollars-in-identifiers}

View File

@ -214,7 +214,8 @@ in the following sections.
-Wimport -Wno-import -Winit-self -Winline @gol
-Wno-int-to-pointer-cast @gol
-Wno-invalid-offsetof -Winvalid-pch @gol
-Wlarger-than-@var{len} -Wunsafe-loop-optimizations -Wlong-long @gol
-Wlarger-than-@var{len} -Wframe-larger-than-@var{len} @gol
-Wunsafe-loop-optimizations -Wlong-long @gol
-Wmain -Wmissing-braces -Wmissing-field-initializers @gol
-Wmissing-format-attribute -Wmissing-include-dirs @gol
-Wmissing-noreturn @gol
@ -758,6 +759,8 @@ See S/390 and zSeries Options.
-fnon-call-exceptions -funwind-tables @gol
-fasynchronous-unwind-tables @gol
-finhibit-size-directive -finstrument-functions @gol
-finstrument-functions-exclude-function-list=@var{sym},@var{sym},@dots{} @gol
-finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{} @gol
-fno-common -fno-ident @gol
-fpcc-struct-return -fpic -fPIC -fpie -fPIE @gol
-fno-jump-tables @gol
@ -2505,14 +2508,40 @@ It warns about code which might break the strict aliasing rules that the
compiler is using for optimization. The warning does not catch all
cases, but does attempt to catch the more common pitfalls. It is
included in @option{-Wall}.
It is equivalent to -Wstrict-aliasing=3
@item -Wstrict-aliasing=2
@opindex Wstrict-aliasing=2
@item -Wstrict-aliasing=n
@opindex Wstrict-aliasing=n
This option is only active when @option{-fstrict-aliasing} is active.
It warns about code which might break the strict aliasing rules that the
compiler is using for optimization. This warning catches more cases than
@option{-Wstrict-aliasing}, but it will also give a warning for some ambiguous
cases that are safe.
compiler is using for optimization.
Higher levels correspond to higher accuracy (fewer false positives).
Higher levels also correspond to more effort, similar to the way -O works.
@option{-Wstrict-aliasing} is equivalent to @option{-Wstrict-aliasing=n},
with n=3.
Level 1: Most aggressive, quick, least accurate.
Possibly useful when higher levels
do not warn but -fstrict-aliasing still breaks the code, as it has very few
false negatives. However, it has many false positives.
Warns for all pointer conversions between possibly incompatible types,
even if never dereferenced. Runs in the frontend only.
Level 2: Aggressive, quick, not too precise.
May still have many false positives (not as many as level 1 though),
and few false negatives (but possibly more than level 1).
Unlike level 1, it only warns when an address is taken. Warns about
incomplete types. Runs in the frontend only.
Level 3 (default for @option{-Wstrict-aliasing}):
Should have very few false positives and few false
negatives. Slightly slower than levels 1 or 2 when optimization is enabled.
Takes care of the common punn+dereference pattern in the frontend:
@code{*(int*)&some_float}.
If optimization is enabled, it also runs in the backend, where it deals
with multiple statement cases using flow-sensitive points-to information.
Only warns when the converted pointer is dereferenced.
Does not warn about incomplete types.
@item -Wstrict-overflow
@item -Wstrict-overflow=@var{n}
@ -2828,6 +2857,10 @@ global variable or whenever a built-in function is shadowed.
@opindex Wlarger-than
Warn whenever an object of larger than @var{len} bytes is defined.
@item -Wframe-larger-than-@var{len}
@opindex Wframe-larger-than
Warn whenever the frame size of a function is larger than @var{len} bytes.
@item -Wunsafe-loop-optimizations
@opindex Wunsafe-loop-optimizations
Warn if the loop cannot be optimized because the compiler could not
@ -13355,6 +13388,37 @@ interrupt routines, and any functions from which the profiling functions
cannot safely be called (perhaps signal handlers, if the profiling
routines generate output or allocate memory).
@item -finstrument-functions-exclude-file-list=@var{file},@var{file},@dots{}
@opindex finstrument-functions-exclude-file-list
Set the list of functions that are excluded from instrumentation (see
the description of @code{-finstrument-functions}). If the file that
contains a function definition matches with one of @var{file}, then
that function is not instrumented. The match is done on substrings:
if the @var{file} parameter is a substring of the file name, it is
considered to be a match.
For example,
@code{-finstrument-functions-exclude-file-list=/bits/stl,include/sys}
will exclude any inline function defined in files whose pathnames
contain @code{/bits/stl} or @code{include/sys}.
If, for some reason, you want to include letter @code{','} in one of
@var{sym}, write @code{'\,'}. For example,
@code{-finstrument-functions-exclude-file-list='\,\,tmp'}
(note the single quote surrounding the option).
@item -finstrument-functions-exclude-function-list=@var{sym},@var{sym},@dots{}
@opindex finstrument-functions-exclude-function-list
This is similar to @code{-finstrument-functions-exclude-file-list},
but this option sets the list of function names to be excluded from
instrumentation. The function name to be matched is its user-visible
name, such as @code{vector<int> blah(const vector<int> &)}, not the
internal mangled name (e.g., @code{_Z4blahRSt6vectorIiSaIiEE}). The
match is done on substrings: if the @var{sym} parameter is a substring
of the function name, it is considered to be a match.
@item -fstack-check
@opindex fstack-check
Generate code to verify that you do not go beyond the boundary of the
@ -13932,3 +13996,4 @@ exist, because otherwise they won't get converted.
@xref{Protoize Caveats}, for more information on how to use
@code{protoize} successfully.

View File

@ -1425,6 +1425,15 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1;
}
if (warn_frame_larger_than
&& get_frame_size () > frame_larger_than_size)
{
/* Issue a warning */
warning (OPT_Wframe_larger_than_,
"the frame size of %wd bytes is larger than %wd bytes",
get_frame_size (), frame_larger_than_size);
}
/* First output the function prologue: code to set up the stack frame. */
targetm.asm_out.function_prologue (file, get_frame_size ());
@ -4083,4 +4092,3 @@ struct tree_opt_pass pass_clean_state =
0, /* todo_flags_finish */
0 /* letter */
};

View File

@ -122,6 +122,15 @@ extern bool extra_warnings;
extern void set_Wunused (int setting);
/* Used to set the level of -Wstrict-aliasing, when no level is specified.
The external way to set the default level is to use
-Wstrict-aliasing=level.
ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
and 0 otherwise. After calling this function, wstrict_aliasing will be
set to the default value of -Wstrict_aliasing=level. */
extern void set_warn_strict_aliasing (int onoff);
/* Nonzero means warn about any objects definitions whose size is larger
than N bytes. Also want about function definitions whose returned
values are larger than N bytes. The value N is in `larger_than_size'. */
@ -129,6 +138,12 @@ extern void set_Wunused (int setting);
extern bool warn_larger_than;
extern HOST_WIDE_INT larger_than_size;
/* Nonzero means warn about any function whose frame size is larger
than N bytes. */
extern bool warn_frame_larger_than;
extern HOST_WIDE_INT frame_larger_than_size;
/* Nonzero means warn about constructs which might not be strict
aliasing safe. */
@ -287,6 +302,10 @@ extern const char *flag_random_seed;
#define abi_version_at_least(N) \
(flag_abi_version == 0 || flag_abi_version >= (N))
/* Return whether the function should be excluded from
instrumentation. */
extern bool flag_instrument_functions_exclude_p (tree fndecl);
/* True if the given mode has a NaN representation and the treatment of
NaN operands is important. Certain optimizations, such as folding
x * 0 into 0, are not correct for NaN operands, and are normally

View File

@ -6397,7 +6397,8 @@ gimplify_function_tree (tree fndecl)
catch the exit hook. */
/* ??? Add some way to ignore exceptions for this TFE. */
if (flag_instrument_function_entry_exit
&& ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl))
&& !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
&& !flag_instrument_functions_exclude_p (fndecl))
{
tree tf, x, bind;

View File

@ -59,6 +59,11 @@ bool extra_warnings;
bool warn_larger_than;
HOST_WIDE_INT larger_than_size;
/* True to warn about any function whose frame size is larger
* than N bytes. */
bool warn_frame_larger_than;
HOST_WIDE_INT frame_larger_than_size;
/* Nonzero means warn about constructs which might not be
strict-aliasing safe. */
int warn_strict_aliasing;
@ -358,6 +363,15 @@ static bool flag_unroll_loops_set, flag_tracer_set;
static bool flag_value_profile_transformations_set;
static bool flag_peel_loops_set, flag_branch_probabilities_set;
/* Functions excluded from profiling. */
typedef char *char_p; /* For DEF_VEC_P. */
DEF_VEC_P(char_p);
DEF_VEC_ALLOC_P(char_p,heap);
static VEC(char_p,heap) *flag_instrument_functions_exclude_functions;
static VEC(char_p,heap) *flag_instrument_functions_exclude_files;
/* Input file names. */
const char **in_fnames;
unsigned num_in_fnames;
@ -604,6 +618,87 @@ add_input_filename (const char *filename)
in_fnames[num_in_fnames - 1] = filename;
}
/* Add functions or file names to a vector of names to exclude from
instrumentation. */
static void
add_instrument_functions_exclude_list (VEC(char_p,heap) **pvec,
const char* arg)
{
char *tmp;
char *r;
char *w;
char *token_start;
/* We never free this string. */
tmp = xstrdup (arg);
r = tmp;
w = tmp;
token_start = tmp;
while (*r != '\0')
{
if (*r == ',')
{
*w++ = '\0';
++r;
VEC_safe_push (char_p, heap, *pvec, token_start);
token_start = w;
}
if (*r == '\\' && r[1] == ',')
{
*w++ = ',';
r += 2;
}
else
*w++ = *r++;
}
if (*token_start != '\0')
VEC_safe_push (char_p, heap, *pvec, token_start);
}
/* Return whether we should exclude FNDECL from instrumentation. */
bool
flag_instrument_functions_exclude_p (tree fndecl)
{
if (VEC_length (char_p, flag_instrument_functions_exclude_functions) > 0)
{
const char *name;
int i;
char *s;
name = lang_hooks.decl_printable_name (fndecl, 0);
for (i = 0;
VEC_iterate (char_p, flag_instrument_functions_exclude_functions,
i, s);
++i)
{
if (strstr (name, s) != NULL)
return true;
}
}
if (VEC_length (char_p, flag_instrument_functions_exclude_files) > 0)
{
const char *name;
int i;
char *s;
name = DECL_SOURCE_FILE (fndecl);
for (i = 0;
VEC_iterate (char_p, flag_instrument_functions_exclude_files, i, s);
++i)
{
if (strstr (name, s) != NULL)
return true;
}
}
return false;
}
/* Decode and handle the vector of command line options. LANG_MASK
contains has a single bit set representing the current
language. */
@ -979,7 +1074,15 @@ common_handle_option (size_t scode, const char *arg, int value,
warn_larger_than = value != -1;
break;
case OPT_Wframe_larger_than_:
frame_larger_than_size = value;
warn_frame_larger_than = value != -1;
break;
case OPT_Wstrict_aliasing:
set_warn_strict_aliasing (value);
break;
case OPT_Wstrict_aliasing_:
warn_strict_aliasing = value;
break;
@ -1086,6 +1189,16 @@ common_handle_option (size_t scode, const char *arg, int value,
set_param_value ("max-inline-insns-auto", value / 2);
break;
case OPT_finstrument_functions_exclude_function_list_:
add_instrument_functions_exclude_list
(&flag_instrument_functions_exclude_functions, arg);
break;
case OPT_finstrument_functions_exclude_file_list_:
add_instrument_functions_exclude_list
(&flag_instrument_functions_exclude_files, arg);
break;
case OPT_fmessage_length_:
pp_set_line_maximum_length (global_dc->printer, value);
break;
@ -1348,6 +1461,20 @@ set_Wunused (int setting)
warn_unused_value = setting;
}
/* Used to set the level of strict aliasing warnings,
when no level is specified (i.e., when -Wstrict-aliasing, and not
-Wstrict-aliasing=level was given).
ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
and 0 otherwise. After calling this function, wstrict_aliasing will be
set to the default value of -Wstrict_aliasing=level, currently 3. */
void
set_warn_strict_aliasing (int onoff)
{
gcc_assert (onoff == 0 || onoff == 1);
if (onoff != 0)
warn_strict_aliasing = 3;
}
/* The following routines are useful in setting all the flags that
-ffast-math and -fno-fast-math imply. */
void

View File

@ -694,6 +694,8 @@ static inline bool overlap_subvar (unsigned HOST_WIDE_INT,
definition, a function with this prototype is called. */
typedef bool (*walk_use_def_chains_fn) (tree, tree, void *);
/* In tree-ssa-alias-warnings.c */
extern void strict_aliasing_warning_backend (void);
/* In tree-ssa.c */
extern void init_tree_ssa (void);

File diff suppressed because it is too large Load Diff

View File

@ -652,7 +652,7 @@ static unsigned int
compute_may_aliases (void)
{
struct alias_info *ai;
memset (&alias_stats, 0, sizeof (alias_stats));
/* Initialize aliasing information. */
@ -710,6 +710,9 @@ compute_may_aliases (void)
dump_alias_info (dump_file);
}
/* Report strict aliasing violations. */
strict_aliasing_warning_backend ();
/* Deallocate memory used by aliasing data structures. */
delete_alias_info (ai);

View File

@ -2509,12 +2509,18 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
true))
return;
type = TREE_TYPE (var);
/* If we see a pointer type starting at a constant, then we have an
unusual ivopt. It may legitimately wrap. */
if (POINTER_TYPE_P (type) && is_gimple_min_invariant (init))
return;
/* We use TYPE_MIN_VALUE and TYPE_MAX_VALUE here instead of
negative_overflow_infinity and positive_overflow_infinity,
because we have concluded that the loop probably does not
wrap. */
type = TREE_TYPE (var);
if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
tmin = lower_bound_in_type (type, type);
else

View File

@ -69,14 +69,14 @@ INCLUDES = -I$(srcdir) -I. -I$(srcdir)/../include @INCINTL@ \
ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(INCLUDES) $(CPPFLAGS)
libcpp_a_OBJS = charset.o directives.o errors.o expr.o files.o \
identifiers.o init.o lex.o line-map.o macro.o mkdeps.o \
pch.o symtab.o traditional.o
libcpp_a_OBJS = charset.o directives.o directives-only.o errors.o \
expr.o files.o identifiers.o init.o lex.o line-map.o macro.o \
mkdeps.o pch.o symtab.o traditional.o
makedepend_OBJS = makedepend.o
libcpp_a_SOURCES = charset.c directives.c errors.c expr.c files.c \
identifiers.c init.c lex.c line-map.c macro.c mkdeps.c \
pch.c symtab.c traditional.c
libcpp_a_SOURCES = charset.c directives.c directives-only.c errors.c \
expr.c files.c identifiers.c init.c lex.c line-map.c macro.c \
mkdeps.c pch.c symtab.c traditional.c
all: libcpp.a makedepend$(EXEEXT) $(USED_CATALOGS)

View File

@ -0,0 +1,229 @@
/* CPP Library - directive only preprocessing for distributed compilation.
Copyright (C) 2007
Free Software Foundation, Inc.
Contributed by Ollie Wild <aaw@google.com>.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include "config.h"
#include "system.h"
#include "cpplib.h"
#include "internal.h"
/* DO (Directive only) flags. */
#define DO_BOL (1 << 0) /* At the beginning of a logical line. */
#define DO_STRING (1 << 1) /* In a string constant. */
#define DO_CHAR (1 << 2) /* In a character constant. */
#define DO_BLOCK_COMMENT (1 << 3) /* In a block comment. */
#define DO_LINE_COMMENT (1 << 4) /* In a single line "//-style" comment. */
#define DO_LINE_SPECIAL (DO_STRING | DO_CHAR | DO_LINE_COMMENT)
#define DO_SPECIAL (DO_LINE_SPECIAL | DO_BLOCK_COMMENT)
/* Writes out the preprocessed file, handling spacing and paste
avoidance issues. */
void
_cpp_preprocess_dir_only (cpp_reader *pfile,
const struct _cpp_dir_only_callbacks *cb)
{
struct cpp_buffer *buffer;
const unsigned char *cur, *base, *next_line, *rlimit;
cppchar_t c, last_c;
unsigned flags;
int lines, col;
source_location loc;
restart:
/* Buffer initialization ala _cpp_clean_line(). */
buffer = pfile->buffer;
buffer->cur_note = buffer->notes_used = 0;
buffer->cur = buffer->line_base = buffer->next_line;
buffer->need_line = false;
/* This isn't really needed. It prevents a compiler warning, though. */
loc = pfile->line_table->highest_line;
/* Scan initialization. */
next_line = cur = base = buffer->cur;
rlimit = buffer->rlimit;
flags = DO_BOL;
lines = 0;
col = 1;
for (last_c = '\n', c = *cur; cur < rlimit; last_c = c, c = *++cur, ++col)
{
/* Skip over escaped newlines. */
if (__builtin_expect (c == '\\', false))
{
const unsigned char *tmp = cur + 1;
while (is_nvspace (*tmp) && tmp < rlimit)
tmp++;
if (*tmp == '\r')
tmp++;
if (*tmp == '\n' && tmp < rlimit)
{
CPP_INCREMENT_LINE (pfile, 0);
lines++;
col = 0;
cur = tmp;
c = last_c;
continue;
}
}
if (__builtin_expect (last_c == '#', false) && !(flags & DO_SPECIAL))
{
if (c != '#' && (flags & DO_BOL))
{
struct line_maps *line_table;
if (!pfile->state.skipping && next_line != base)
cb->print_lines (lines, base, next_line - base);
/* Prep things for directive handling. */
buffer->next_line = cur;
buffer->need_line = true;
_cpp_get_fresh_line (pfile);
/* Ensure proper column numbering for generated error messages. */
buffer->line_base -= col - 1;
_cpp_handle_directive (pfile, 0 /* ignore indented */);
/* Sanitize the line settings. Duplicate #include's can mess
things up. */
line_table = pfile->line_table;
line_table->highest_location = line_table->highest_line;
/* The if block prevents us from outputing line information when
the file ends with a directive and no newline. Note that we
must use pfile->buffer, not buffer. */
if (pfile->buffer->cur != pfile->buffer->rlimit)
cb->maybe_print_line (pfile->line_table->highest_line);
goto restart;
}
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
else if (__builtin_expect (last_c == '/', false) \
&& !(flags & DO_SPECIAL) && c != '*' && c != '/')
{
/* If a previous slash is not starting a block comment, clear the
DO_BOL flag. */
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
switch (c)
{
case '/':
if ((flags & DO_BLOCK_COMMENT) && last_c == '*')
{
flags &= ~DO_BLOCK_COMMENT;
c = 0;
}
else if (!(flags & DO_SPECIAL) && last_c == '/')
flags |= DO_LINE_COMMENT;
else if (!(flags & DO_SPECIAL))
/* Mark the position for possible error reporting. */
LINEMAP_POSITION_FOR_COLUMN (loc, pfile->line_table, col);
break;
case '*':
if (!(flags & DO_SPECIAL))
{
if (last_c == '/')
flags |= DO_BLOCK_COMMENT;
else
{
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
}
break;
case '\'':
case '"':
{
unsigned state = (c == '"') ? DO_STRING : DO_CHAR;
if (!(flags & DO_SPECIAL))
{
flags |= state;
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
else if ((flags & state) && last_c != '\\')
flags &= ~state;
break;
}
case '\\':
{
if ((flags & (DO_STRING | DO_CHAR)) && last_c == '\\')
c = 0;
if (!(flags & DO_SPECIAL))
{
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
break;
}
case '\n':
CPP_INCREMENT_LINE (pfile, 0);
lines++;
col = 0;
flags &= ~DO_LINE_SPECIAL;
if (!(flags & DO_SPECIAL))
flags |= DO_BOL;
break;
case '#':
next_line = cur;
/* Don't update DO_BOL yet. */
break;
case ' ': case '\t': case '\f': case '\v': case '\0':
break;
default:
if (!(flags & DO_SPECIAL))
{
flags &= ~DO_BOL;
pfile->mi_valid = false;
}
break;
}
}
if (flags & DO_BLOCK_COMMENT)
cpp_error_with_line (pfile, CPP_DL_ERROR, loc, 0, "unterminated comment");
if (!pfile->state.skipping && cur != base)
cb->print_lines (lines, base, cur - base);
_cpp_pop_buffer (pfile);
if (pfile->buffer)
goto restart;
}

View File

@ -423,8 +423,13 @@ _cpp_handle_directive (cpp_reader *pfile, int indented)
does not cause '#define foo bar' to get executed when
compiled with -save-temps, we recognize directives in
-fpreprocessed mode only if the # is in column 1. macro.c
puts a space in front of any '#' at the start of a macro. */
puts a space in front of any '#' at the start of a macro.
We exclude the -fdirectives-only case because macro expansion
has not been performed yet, and block comments can cause spaces
to preceed the directive. */
if (CPP_OPTION (pfile, preprocessed)
&& !CPP_OPTION (pfile, directives_only)
&& (indented || !(dir->flags & IN_I)))
{
skip = 0;

View File

@ -775,7 +775,8 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
/* Stack the buffer. */
buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
CPP_OPTION (pfile, preprocessed));
CPP_OPTION (pfile, preprocessed)
&& !CPP_OPTION (pfile, directives_only));
buffer->file = file;
buffer->sysp = sysp;

View File

@ -440,6 +440,9 @@ struct cpp_options
/* True means error callback should be used for diagnostics. */
bool client_diagnostic;
/* True disables tokenization outside of preprocessing directives. */
bool directives_only;
};
/* Callback for header lookup for HEADER, which is the name of a
@ -644,6 +647,10 @@ extern struct deps *cpp_get_deps (cpp_reader *);
too. If there was an error opening the file, it returns NULL. */
extern const char *cpp_read_main_file (cpp_reader *, const char *);
/* Set up built-ins with special behavior. Use cpp_init_builtins()
instead unless your know what you are doing. */
extern void cpp_init_special_builtins (cpp_reader *);
/* Set up built-ins like __FILE__. */
extern void cpp_init_builtins (cpp_reader *, int);

View File

@ -348,11 +348,8 @@ mark_named_operators (cpp_reader *pfile)
}
}
/* Read the builtins table above and enter them, and language-specific
macros, into the hash table. HOSTED is true if this is a hosted
environment. */
void
cpp_init_builtins (cpp_reader *pfile, int hosted)
cpp_init_special_builtins (cpp_reader *pfile)
{
const struct builtin *b;
size_t n = ARRAY_SIZE (builtin_array);
@ -361,10 +358,7 @@ cpp_init_builtins (cpp_reader *pfile, int hosted)
n -= 2;
else if (! CPP_OPTION (pfile, stdc_0_in_system_headers)
|| CPP_OPTION (pfile, std))
{
n--;
_cpp_define_builtin (pfile, "__STDC__ 1");
}
n--;
for (b = builtin_array; b < builtin_array + n; b++)
{
@ -373,6 +367,20 @@ cpp_init_builtins (cpp_reader *pfile, int hosted)
hp->flags |= NODE_BUILTIN | NODE_WARN;
hp->value.builtin = (enum builtin_type) b->value;
}
}
/* Read the builtins table above and enter them, and language-specific
macros, into the hash table. HOSTED is true if this is a hosted
environment. */
void
cpp_init_builtins (cpp_reader *pfile, int hosted)
{
cpp_init_special_builtins (pfile);
if (!CPP_OPTION (pfile, traditional)
&& (! CPP_OPTION (pfile, stdc_0_in_system_headers)
|| CPP_OPTION (pfile, std)))
_cpp_define_builtin (pfile, "__STDC__ 1");
if (CPP_OPTION (pfile, cplusplus))
_cpp_define_builtin (pfile, "__cplusplus 1");
@ -620,7 +628,8 @@ post_options (cpp_reader *pfile)
preprocessed text. Read preprocesed source in ISO mode. */
if (CPP_OPTION (pfile, preprocessed))
{
pfile->state.prevent_expansion = 1;
if (!CPP_OPTION (pfile, directives_only))
pfile->state.prevent_expansion = 1;
CPP_OPTION (pfile, traditional) = 0;
}

View File

@ -567,6 +567,17 @@ extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *,
unsigned int, unsigned int);
extern void _cpp_pop_buffer (cpp_reader *);
/* In directives.c */
struct _cpp_dir_only_callbacks
{
/* Called to print a block of lines. */
void (*print_lines) (int, const void *, size_t);
void (*maybe_print_line) (source_location);
};
extern void _cpp_preprocess_dir_only (cpp_reader *,
const struct _cpp_dir_only_callbacks *);
/* In traditional.c. */
extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *);
extern bool _cpp_read_logical_line_trad (cpp_reader *);

View File

@ -264,6 +264,9 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
break;
case BT_COUNTER:
if (CPP_OPTION (pfile, directives_only) && pfile->state.in_directive)
cpp_error (pfile, CPP_DL_ERROR,
"__COUNTER__ expanded inside directive with -fdirectives-only");
number = pfile->nextcounter++;
break;
}

View File

@ -210,10 +210,11 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
};
// Note: assumes long is at least 32 bits.
enum { _S_num_primes = 28 };
enum { _S_num_primes = 29 };
static const unsigned long __stl_prime_list[_S_num_primes] =
{
5ul, // 5ul mini size is a Google addition
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
@ -1076,6 +1077,10 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::
clear()
{
// Google addition: do not iterate over buckets when empty
if (_M_num_elements == 0)
return;
for (size_type __i = 0; __i < _M_buckets.size(); ++__i)
{
_Node* __cur = _M_buckets[__i];