c: add support for per-location warning groups.
gcc/ChangeLog: * tree.h (warning_suppressed_at, copy_warning, warning_suppressed_p, suppress_warning): New functions. gcc/c/ChangeLog: * c-decl.c (pop_scope): Replace direct uses of TREE_NO_WARNING with warning_suppressed_p, suppress_warning, and copy_no_warning. (diagnose_mismatched_decls): Same. (duplicate_decls): Same. (grokdeclarator): Same. (finish_function): Same. (c_write_global_declarations_1): Same. * c-fold.c (c_fully_fold_internal): Same. * c-parser.c (c_parser_expr_no_commas): Same. (c_parser_postfix_expression): Same. * c-typeck.c (array_to_pointer_conversion): Same. (function_to_pointer_conversion): Same. (default_function_array_conversion): Same. (convert_lvalue_to_rvalue): Same. (default_conversion): Same. (build_indirect_ref): Same. (build_function_call_vec): Same. (build_atomic_assign): Same. (build_unary_op): Same. (c_finish_return): Same. (emit_side_effect_warnings): Same. (c_finish_stmt_expr): Same. (c_omp_clause_copy_ctor): Same.
This commit is contained in:
parent
7036e9ef46
commit
1ebd2b2c94
|
@ -1295,7 +1295,7 @@ pop_scope (void)
|
|||
case VAR_DECL:
|
||||
/* Warnings for unused variables. */
|
||||
if ((!TREE_USED (p) || !DECL_READ_P (p))
|
||||
&& !TREE_NO_WARNING (p)
|
||||
&& !warning_suppressed_p (p, OPT_Wunused_but_set_variable)
|
||||
&& !DECL_IN_SYSTEM_HEADER (p)
|
||||
&& DECL_NAME (p)
|
||||
&& !DECL_ARTIFICIAL (p)
|
||||
|
@ -2159,8 +2159,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
|
|||
|
||||
if (DECL_IN_SYSTEM_HEADER (newdecl)
|
||||
|| DECL_IN_SYSTEM_HEADER (olddecl)
|
||||
|| TREE_NO_WARNING (newdecl)
|
||||
|| TREE_NO_WARNING (olddecl))
|
||||
|| warning_suppressed_p (newdecl, OPT_Wpedantic)
|
||||
|| warning_suppressed_p (olddecl, OPT_Wpedantic))
|
||||
return true; /* Allow OLDDECL to continue in use. */
|
||||
|
||||
if (variably_modified_type_p (newtype, NULL))
|
||||
|
@ -2956,7 +2956,7 @@ duplicate_decls (tree newdecl, tree olddecl)
|
|||
if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype))
|
||||
{
|
||||
/* Avoid `unused variable' and other warnings for OLDDECL. */
|
||||
TREE_NO_WARNING (olddecl) = 1;
|
||||
suppress_warning (olddecl, OPT_Wunused);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -7543,10 +7543,7 @@ grokdeclarator (const struct c_declarator *declarator,
|
|||
FIELD_DECL, declarator->u.id.id, type);
|
||||
DECL_NONADDRESSABLE_P (decl) = bitfield;
|
||||
if (bitfield && !declarator->u.id.id)
|
||||
{
|
||||
TREE_NO_WARNING (decl) = 1;
|
||||
DECL_PADDING_P (decl) = 1;
|
||||
}
|
||||
DECL_PADDING_P (decl) = 1;
|
||||
|
||||
if (size_varies)
|
||||
C_DECL_VARIABLE_SIZE (decl) = 1;
|
||||
|
@ -10244,7 +10241,7 @@ finish_function (location_t end_loc)
|
|||
&& targetm.warn_func_return (fndecl)
|
||||
&& warning (OPT_Wreturn_type,
|
||||
"no return statement in function returning non-void"))
|
||||
TREE_NO_WARNING (fndecl) = 1;
|
||||
suppress_warning (fndecl, OPT_Wreturn_type);
|
||||
|
||||
/* Complain about parameters that are only set, but never otherwise used. */
|
||||
if (warn_unused_but_set_parameter)
|
||||
|
@ -10259,7 +10256,7 @@ finish_function (location_t end_loc)
|
|||
&& !DECL_READ_P (decl)
|
||||
&& DECL_NAME (decl)
|
||||
&& !DECL_ARTIFICIAL (decl)
|
||||
&& !TREE_NO_WARNING (decl))
|
||||
&& !warning_suppressed_p (decl, OPT_Wunused_but_set_parameter))
|
||||
warning_at (DECL_SOURCE_LOCATION (decl),
|
||||
OPT_Wunused_but_set_parameter,
|
||||
"parameter %qD set but not used", decl);
|
||||
|
@ -12126,19 +12123,20 @@ c_write_global_declarations_1 (tree globals)
|
|||
{
|
||||
if (C_DECL_USED (decl))
|
||||
{
|
||||
/* TODO: Add OPT_Wundefined-inline. */
|
||||
if (pedwarn (input_location, 0, "%q+F used but never defined",
|
||||
decl))
|
||||
TREE_NO_WARNING (decl) = 1;
|
||||
suppress_warning (decl /* OPT_Wundefined-inline. */);
|
||||
}
|
||||
/* For -Wunused-function warn about unused static prototypes. */
|
||||
else if (warn_unused_function
|
||||
&& ! DECL_ARTIFICIAL (decl)
|
||||
&& ! TREE_NO_WARNING (decl))
|
||||
&& ! warning_suppressed_p (decl, OPT_Wunused_function))
|
||||
{
|
||||
if (warning (OPT_Wunused_function,
|
||||
"%q+F declared %<static%> but never defined",
|
||||
decl))
|
||||
TREE_NO_WARNING (decl) = 1;
|
||||
suppress_warning (decl, OPT_Wunused_function);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
|||
tree orig_op0, orig_op1, orig_op2;
|
||||
bool op0_const = true, op1_const = true, op2_const = true;
|
||||
bool op0_const_self = true, op1_const_self = true, op2_const_self = true;
|
||||
bool nowarning = TREE_NO_WARNING (expr);
|
||||
bool nowarning = warning_suppressed_p (expr, OPT_Woverflow);
|
||||
bool unused_p;
|
||||
bool op0_lval = false;
|
||||
source_range old_range;
|
||||
|
@ -670,13 +670,13 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
|
|||
out:
|
||||
/* Some folding may introduce NON_LVALUE_EXPRs; all lvalue checks
|
||||
have been done by this point, so remove them again. */
|
||||
nowarning |= TREE_NO_WARNING (ret);
|
||||
nowarning |= warning_suppressed_p (ret, OPT_Woverflow);
|
||||
STRIP_TYPE_NOPS (ret);
|
||||
if (nowarning && !TREE_NO_WARNING (ret))
|
||||
if (nowarning && !warning_suppressed_p (ret, OPT_Woverflow))
|
||||
{
|
||||
if (!CAN_HAVE_LOCATION_P (ret))
|
||||
ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
|
||||
TREE_NO_WARNING (ret) = 1;
|
||||
suppress_warning (ret, OPT_Woverflow);
|
||||
}
|
||||
if (ret != expr)
|
||||
{
|
||||
|
|
|
@ -7558,7 +7558,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
|
|||
ret.original_code = MODIFY_EXPR;
|
||||
else
|
||||
{
|
||||
TREE_NO_WARNING (ret.value) = 1;
|
||||
suppress_warning (ret.value, OPT_Wparentheses);
|
||||
ret.original_code = ERROR_MARK;
|
||||
}
|
||||
ret.original_type = NULL;
|
||||
|
@ -9088,7 +9088,7 @@ c_parser_postfix_expression (c_parser *parser)
|
|||
c_parser_consume_token (parser);
|
||||
expr = c_parser_expression (parser);
|
||||
if (TREE_CODE (expr.value) == MODIFY_EXPR)
|
||||
TREE_NO_WARNING (expr.value) = 1;
|
||||
suppress_warning (expr.value, OPT_Wparentheses);
|
||||
if (expr.original_code != C_MAYBE_CONST_EXPR
|
||||
&& expr.original_code != SIZEOF_EXPR)
|
||||
expr.original_code = ERROR_MARK;
|
||||
|
|
|
@ -1911,8 +1911,7 @@ array_to_pointer_conversion (location_t loc, tree exp)
|
|||
|
||||
STRIP_TYPE_NOPS (exp);
|
||||
|
||||
if (TREE_NO_WARNING (orig_exp))
|
||||
TREE_NO_WARNING (exp) = 1;
|
||||
copy_warning (exp, orig_exp);
|
||||
|
||||
ptrtype = build_pointer_type (restype);
|
||||
|
||||
|
@ -1945,8 +1944,7 @@ function_to_pointer_conversion (location_t loc, tree exp)
|
|||
|
||||
STRIP_TYPE_NOPS (exp);
|
||||
|
||||
if (TREE_NO_WARNING (orig_exp))
|
||||
TREE_NO_WARNING (exp) = 1;
|
||||
copy_warning (exp, orig_exp);
|
||||
|
||||
return build_unary_op (loc, ADDR_EXPR, exp, false);
|
||||
}
|
||||
|
@ -2055,8 +2053,7 @@ default_function_array_conversion (location_t loc, struct c_expr exp)
|
|||
exp.value = TREE_OPERAND (exp.value, 0);
|
||||
}
|
||||
|
||||
if (TREE_NO_WARNING (orig_exp))
|
||||
TREE_NO_WARNING (exp.value) = 1;
|
||||
copy_warning (exp.value, orig_exp);
|
||||
|
||||
lvalue_array_p = !not_lvalue && lvalue_p (exp.value);
|
||||
if (!flag_isoc99 && !lvalue_array_p)
|
||||
|
@ -2154,7 +2151,8 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp,
|
|||
tmp = create_tmp_var_raw (nonatomic_type);
|
||||
tmp_addr = build_unary_op (loc, ADDR_EXPR, tmp, false);
|
||||
TREE_ADDRESSABLE (tmp) = 1;
|
||||
TREE_NO_WARNING (tmp) = 1;
|
||||
/* Do not disable warnings for TMP even though it's artificial.
|
||||
-Winvalid-memory-model depends on it. */
|
||||
|
||||
/* Issue __atomic_load (&expr, &tmp, SEQ_CST); */
|
||||
fndecl = builtin_decl_explicit (BUILT_IN_ATOMIC_LOAD);
|
||||
|
@ -2251,8 +2249,7 @@ default_conversion (tree exp)
|
|||
orig_exp = exp;
|
||||
STRIP_TYPE_NOPS (exp);
|
||||
|
||||
if (TREE_NO_WARNING (orig_exp))
|
||||
TREE_NO_WARNING (exp) = 1;
|
||||
copy_warning (exp, orig_exp);
|
||||
|
||||
if (code == VOID_TYPE)
|
||||
{
|
||||
|
@ -2616,7 +2613,7 @@ build_indirect_ref (location_t loc, tree ptr, ref_operator errstring)
|
|||
if (warn_strict_aliasing > 2)
|
||||
if (strict_aliasing_warning (EXPR_LOCATION (pointer),
|
||||
type, TREE_OPERAND (pointer, 0)))
|
||||
TREE_NO_WARNING (pointer) = 1;
|
||||
suppress_warning (pointer, OPT_Wstrict_aliasing_);
|
||||
}
|
||||
|
||||
if (TREE_CODE (pointer) == ADDR_EXPR
|
||||
|
@ -3218,7 +3215,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
|
|||
/* If -Wnonnull warning has been diagnosed, avoid diagnosing it again
|
||||
later. */
|
||||
if (warned_p && TREE_CODE (result) == CALL_EXPR)
|
||||
TREE_NO_WARNING (result) = 1;
|
||||
suppress_warning (result, OPT_Wnonnull);
|
||||
|
||||
/* In this improbable scenario, a nested function returns a VM type.
|
||||
Create a TARGET_EXPR so that the call always has a LHS, much as
|
||||
|
@ -4167,7 +4164,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
|
|||
TYPE_UNQUALIFIED);
|
||||
val = create_tmp_var_raw (nonatomic_rhs_type);
|
||||
TREE_ADDRESSABLE (val) = 1;
|
||||
TREE_NO_WARNING (val) = 1;
|
||||
suppress_warning (val);
|
||||
rhs = build4 (TARGET_EXPR, nonatomic_rhs_type, val, rhs, NULL_TREE,
|
||||
NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (rhs) = 1;
|
||||
|
@ -4268,7 +4265,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
|
|||
|
||||
newval = create_tmp_var_raw (nonatomic_lhs_type);
|
||||
TREE_ADDRESSABLE (newval) = 1;
|
||||
TREE_NO_WARNING (newval) = 1;
|
||||
suppress_warning (newval);
|
||||
rhs = build4 (TARGET_EXPR, nonatomic_lhs_type, newval, func_call,
|
||||
NULL_TREE, NULL_TREE);
|
||||
SET_EXPR_LOCATION (rhs, loc);
|
||||
|
@ -4287,12 +4284,12 @@ cas_loop:
|
|||
old = create_tmp_var_raw (nonatomic_lhs_type);
|
||||
old_addr = build_unary_op (loc, ADDR_EXPR, old, false);
|
||||
TREE_ADDRESSABLE (old) = 1;
|
||||
TREE_NO_WARNING (old) = 1;
|
||||
suppress_warning (old);
|
||||
|
||||
newval = create_tmp_var_raw (nonatomic_lhs_type);
|
||||
newval_addr = build_unary_op (loc, ADDR_EXPR, newval, false);
|
||||
TREE_ADDRESSABLE (newval) = 1;
|
||||
TREE_NO_WARNING (newval) = 1;
|
||||
suppress_warning (newval);
|
||||
|
||||
loop_decl = create_artificial_label (loc);
|
||||
loop_label = build1 (LABEL_EXPR, void_type_node, loop_decl);
|
||||
|
@ -4781,8 +4778,6 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
|
|||
else
|
||||
val = build2 (code, TREE_TYPE (arg), arg, inc);
|
||||
TREE_SIDE_EFFECTS (val) = 1;
|
||||
if (TREE_CODE (val) != code)
|
||||
TREE_NO_WARNING (val) = 1;
|
||||
ret = val;
|
||||
goto return_build_unary_op;
|
||||
}
|
||||
|
@ -10962,7 +10957,8 @@ c_finish_return (location_t loc, tree retval, tree origtype)
|
|||
}
|
||||
|
||||
ret_stmt = build_stmt (loc, RETURN_EXPR, retval);
|
||||
TREE_NO_WARNING (ret_stmt) |= no_warning;
|
||||
if (no_warning)
|
||||
suppress_warning (ret_stmt, OPT_Wreturn_type);
|
||||
return add_stmt (ret_stmt);
|
||||
}
|
||||
|
||||
|
@ -11238,7 +11234,8 @@ emit_side_effect_warnings (location_t loc, tree expr)
|
|||
;
|
||||
else if (!TREE_SIDE_EFFECTS (expr))
|
||||
{
|
||||
if (!VOID_TYPE_P (TREE_TYPE (expr)) && !TREE_NO_WARNING (expr))
|
||||
if (!VOID_TYPE_P (TREE_TYPE (expr))
|
||||
&& !warning_suppressed_p (expr, OPT_Wunused_value))
|
||||
warning_at (loc, OPT_Wunused_value, "statement with no effect");
|
||||
}
|
||||
else if (TREE_CODE (expr) == COMPOUND_EXPR)
|
||||
|
@ -11254,8 +11251,8 @@ emit_side_effect_warnings (location_t loc, tree expr)
|
|||
if (!TREE_SIDE_EFFECTS (r)
|
||||
&& !VOID_TYPE_P (TREE_TYPE (r))
|
||||
&& !CONVERT_EXPR_P (r)
|
||||
&& !TREE_NO_WARNING (r)
|
||||
&& !TREE_NO_WARNING (expr))
|
||||
&& !warning_suppressed_p (r, OPT_Wunused_value)
|
||||
&& !warning_suppressed_p (expr, OPT_Wunused_value))
|
||||
warning_at (cloc, OPT_Wunused_value,
|
||||
"right-hand operand of comma expression has no effect");
|
||||
}
|
||||
|
@ -11424,7 +11421,7 @@ c_finish_stmt_expr (location_t loc, tree body)
|
|||
last = c_wrap_maybe_const (last, true);
|
||||
/* Do not warn if the return value of a statement expression is
|
||||
unused. */
|
||||
TREE_NO_WARNING (last) = 1;
|
||||
suppress_warning (last, OPT_Wunused);
|
||||
return last;
|
||||
}
|
||||
|
||||
|
@ -15503,7 +15500,7 @@ c_omp_clause_copy_ctor (tree clause, tree dst, tree src)
|
|||
tree tmp = create_tmp_var (nonatomic_type);
|
||||
tree tmp_addr = build_fold_addr_expr (tmp);
|
||||
TREE_ADDRESSABLE (tmp) = 1;
|
||||
TREE_NO_WARNING (tmp) = 1;
|
||||
suppress_warning (tmp);
|
||||
tree src_addr = build_fold_addr_expr (src);
|
||||
tree dst_addr = build_fold_addr_expr (dst);
|
||||
tree seq_cst = build_int_cst (integer_type_node, MEMMODEL_SEQ_CST);
|
||||
|
|
15
gcc/tree.h
15
gcc/tree.h
|
@ -6448,9 +6448,24 @@ constexpr opt_code no_warning = opt_code ();
|
|||
/* Wildcard code that refers to all warnings. */
|
||||
constexpr opt_code all_warnings = N_OPTS;
|
||||
|
||||
/* Return the disposition for a warning (or all warnings by default)
|
||||
at a location. */
|
||||
extern bool warning_suppressed_at (location_t, opt_code = all_warnings);
|
||||
/* Set the disposition for a warning (or all warnings by default)
|
||||
at a location to disabled by default. */
|
||||
extern bool suppress_warning_at (location_t, opt_code = all_warnings,
|
||||
bool = true);
|
||||
/* Copy warning disposition from one location to another. */
|
||||
extern void copy_warning (location_t, location_t);
|
||||
|
||||
/* Return the disposition for a warning (or all warnings by default)
|
||||
for an expression. */
|
||||
extern bool warning_suppressed_p (const_tree, opt_code = all_warnings);
|
||||
/* Set the disposition for a warning (or all warnings by default)
|
||||
at a location to disabled by default. */
|
||||
extern void suppress_warning (tree, opt_code = all_warnings, bool = true)
|
||||
ATTRIBUTE_NONNULL (1);
|
||||
/* Copy warning disposition from one expression to another. */
|
||||
extern void copy_warning (tree, const_tree);
|
||||
|
||||
#endif /* GCC_TREE_H */
|
||||
|
|
Loading…
Reference in New Issue