mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-25 12:02:01 +01: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:
parent
0a9655a082
commit
81e5b01765
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=258501
contrib
gcc
c-common.cc-common.hc-opts.cc-ppoutput.cc-typeck.cc.optcommon.optcoverage.c
cp
doc
final.cflags.hgimplify.copts.ctree-flow.htree-ssa-alias-warnings.ctree-ssa-alias.ctree-vrp.cgcclibs/libcpp
libstdc++/include/ext
@ -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");
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 ();
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
1036
contrib/gcc/tree-ssa-alias-warnings.c
Normal file
1036
contrib/gcc/tree-ssa-alias-warnings.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
229
contrib/gcclibs/libcpp/directives-only.c
Normal file
229
contrib/gcclibs/libcpp/directives-only.c
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user