diff options
author | Ian Lance Taylor <iant@google.com> | 2009-06-16 14:24:40 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2009-06-16 14:24:40 +0000 |
commit | 7d882b8356b9ee3e6844bf4898a996289223fab2 (patch) | |
tree | 7a42ffff9a8ca843cf87a59b7858690a5f169948 /gcc/cp | |
parent | 2e4078422e64a42224ca69daa70604885698a942 (diff) | |
download | gcc-7d882b8356b9ee3e6844bf4898a996289223fab2.zip gcc-7d882b8356b9ee3e6844bf4898a996289223fab2.tar.gz gcc-7d882b8356b9ee3e6844bf4898a996289223fab2.tar.bz2 |
c-common.c (skip_evaluation): Don't define.
./: * c-common.c (skip_evaluation): Don't define.
(c_inhibit_evaluation_warnings): Define global variable.
(overflow_warning): Check c_inhibit_evaluation_warnings rather
than skip_evaluation.
(convert_and_check, warn_for_div_by_zero): Likewise.
* c-common.h (skip_evaluation): Don't declare.
(c_inhibit_evaluation_warnings): Declare.
* c-parser.c (c_parser_typeof_specifier): Set
c_inhibit_evaluation_warnings rather than skip_evaluation.
(c_parser_conditional_expression): Likewise.
(c_parser_binary_expression): Likewise.
(c_parser_sizeof_expression): Likewise.
(c_parser_alignof_expression): Likewise.
* c-typeck.c (build_indirect_ref): Check
c_inhibit_evaluation_warnings rather than skip_evaluation.
(build_conditional_expr, build_binary_op): Likewise.
cp/:
* parser.c (cp_unevaluated_operand): Define global variable.
(cp_parser_question_colon_clause): Increment
c_inhibit_evaluation_warnings when evaluating an expression which
will never be executed.
(cp_parser_decltype): Increment cp_unevaluated_operand and
c_inhibit_evaluation_warnings, not skip_evaluation.
(cp_parser_sizeof_operand): Likewise.
(cp_parser_enclosed_template_argument_list): Save
cp_unevaluated_operand and c_inhibit_evaluation_warnings, not
skip_evaluation.
* cp-tree.h (struct saved_scope): Remove skip_evaluation field.
Add unevaluated_operand and inhibit_evaluation_warnings fields.
(cp_unevaluated_operand): Declare.
* name-lookup.c (push_to_top_level): Save cp_unevaluated_operand
and c_inhibit_evaluation_warnings rather than skip_evaluation.
(pop_from_top_level): Restore cp_unevaluated_operand and
c_inhibit_evaluation_warnings rather than skip_evaluation.
* class.c (build_base_path): Check cp_unevaluated_operand rather
than skip_evaluation.
* typeck.c (build_class_member_access_expr): Likewise.
(cp_build_binary_op): Don't warn about bad shift counts if
c_inhibit_evaluation_warnings is non-zero.
* pt.c (coerce_template_parms): Save state of
cp_unevaluated_operand and c_inhibit_evaluation_warnings, not
skip_evaluation.
(tsubst_aggr_type): Likewise.
(tsubst_pack_expansion): Check cp_unevaluated_operand rather than
skip_evaluation.
(tsubst_copy): Likewise.
(tsubst): Set cp_unevaluated_operand and
c_inhibit_evaluation_warnings, not skip_evaluation.
(tsubst_copy_and_build): Likewise.
* call.c (convert_arg_to_ellipsis): Check cp_unevaluated_operand
rather than skip_evaluation.
* decl2.c (mark_used): Likewise.
* semantics.c (finish_non_static_data_member): Likewise.
* cvt.c (cp_convert_and_check): Check
c_inhibit_evaluation_warnings rather than skip_evaluation.
* mangle.c (write_type): Set cp_unevaluated_operand rather than
skip_evaluation.
testsuite/:
* g++.dg/warn/skip-1.C: New testcase.
From-SVN: r148535
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 43 | ||||
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 12 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 4 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 9 | ||||
-rw-r--r-- | gcc/cp/parser.c | 48 | ||||
-rw-r--r-- | gcc/cp/pt.c | 40 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 14 |
12 files changed, 140 insertions, 42 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 911081a..3912688 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,46 @@ +2009-06-16 Ian Lance Taylor <iant@google.com> + + * parser.c (cp_unevaluated_operand): Define global variable. + (cp_parser_question_colon_clause): Increment + c_inhibit_evaluation_warnings when evaluating an expression which + will never be executed. + (cp_parser_decltype): Increment cp_unevaluated_operand and + c_inhibit_evaluation_warnings, not skip_evaluation. + (cp_parser_sizeof_operand): Likewise. + (cp_parser_enclosed_template_argument_list): Save + cp_unevaluated_operand and c_inhibit_evaluation_warnings, not + skip_evaluation. + * cp-tree.h (struct saved_scope): Remove skip_evaluation field. + Add unevaluated_operand and inhibit_evaluation_warnings fields. + (cp_unevaluated_operand): Declare. + * name-lookup.c (push_to_top_level): Save cp_unevaluated_operand + and c_inhibit_evaluation_warnings rather than skip_evaluation. + (pop_from_top_level): Restore cp_unevaluated_operand and + c_inhibit_evaluation_warnings rather than skip_evaluation. + * class.c (build_base_path): Check cp_unevaluated_operand rather + than skip_evaluation. + * typeck.c (build_class_member_access_expr): Likewise. + (cp_build_binary_op): Don't warn about bad shift counts if + c_inhibit_evaluation_warnings is non-zero. + * pt.c (coerce_template_parms): Save state of + cp_unevaluated_operand and c_inhibit_evaluation_warnings, not + skip_evaluation. + (tsubst_aggr_type): Likewise. + (tsubst_pack_expansion): Check cp_unevaluated_operand rather than + skip_evaluation. + (tsubst_copy): Likewise. + (tsubst): Set cp_unevaluated_operand and + c_inhibit_evaluation_warnings, not skip_evaluation. + (tsubst_copy_and_build): Likewise. + * call.c (convert_arg_to_ellipsis): Check cp_unevaluated_operand + rather than skip_evaluation. + * decl2.c (mark_used): Likewise. + * semantics.c (finish_non_static_data_member): Likewise. + * cvt.c (cp_convert_and_check): Check + c_inhibit_evaluation_warnings rather than skip_evaluation. + * mangle.c (write_type): Set cp_unevaluated_operand rather than + skip_evaluation. + 2009-06-15 Ian Lance Taylor <iant@google.com> * parser.c (cp_parser_direct_declarator): Add braces around diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f33d645..e89d585 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5064,7 +5064,7 @@ convert_arg_to_ellipsis (tree arg) If the call appears in the context of a sizeof expression, there is no need to emit a warning, since the expression won't be evaluated. We keep the builtin_trap just as a safety check. */ - if (!skip_evaluation) + if (cp_unevaluated_operand == 0) warning (0, "cannot pass objects of non-POD type %q#T through %<...%>; " "call will abort at runtime", TREE_TYPE (arg)); arg = call_builtin_trap (); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 94b75ca..b762019 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -295,7 +295,7 @@ build_base_path (enum tree_code code, /* Don't bother with the calculations inside sizeof; they'll ICE if the source type is incomplete and the pointer value doesn't matter. */ - if (skip_evaluation) + if (cp_unevaluated_operand != 0) { expr = build_nop (build_pointer_type (target_type), expr); if (!want_pointer) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4cb34f5..8c45b8a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -755,7 +755,9 @@ struct GTY(()) saved_scope { int x_processing_specialization; BOOL_BITFIELD x_processing_explicit_instantiation : 1; BOOL_BITFIELD need_pop_function_context : 1; - BOOL_BITFIELD skip_evaluation : 1; + + int unevaluated_operand; + int inhibit_evaluation_warnings; struct stmt_tree_s x_stmt_tree; @@ -3621,6 +3623,14 @@ extern GTY(()) tree integer_three_node; function, two inside the body of a function in a local class, etc.) */ extern int function_depth; +/* In parser.c. */ + +/* Nonzero if we are parsing an unevaluated operand: an operand to + sizeof, typeof, or alignof. This is a count since operands to + sizeof can be nested. */ + +extern int cp_unevaluated_operand; + /* in pt.c */ /* These values are used for the `STRICT' parameter to type_unification and diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 596e81c..dfd0ea8 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -565,7 +565,9 @@ cp_convert_and_check (tree type, tree expr) result = cp_convert (type, expr); - if (!skip_evaluation && !TREE_OVERFLOW_P (expr) && result != error_mark_node) + if (c_inhibit_evaluation_warnings == 0 + && !TREE_OVERFLOW_P (expr) + && result != error_mark_node) warnings_for_convert_and_check (type, expr, result); return result; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 495c8e7..308f767 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3815,7 +3815,7 @@ mark_used (tree decl) return; } /* If we don't need a value, then we don't need to synthesize DECL. */ - if (skip_evaluation) + if (cp_unevaluated_operand != 0) return; /* If within finish_function, defer the rest until that function diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index c905304..f7d9d41 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -1684,9 +1684,9 @@ write_type (tree type) write_char ('t'); else write_char ('T'); - ++skip_evaluation; + ++cp_unevaluated_operand; write_expression (DECLTYPE_TYPE_EXPR (type)); - --skip_evaluation; + --cp_unevaluated_operand; write_char ('E'); break; diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index f6b22bb..143fcf3 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -5319,7 +5319,8 @@ push_to_top_level (void) s->bindings = b; s->need_pop_function_context = need_pop; s->function_decl = current_function_decl; - s->skip_evaluation = skip_evaluation; + s->unevaluated_operand = cp_unevaluated_operand; + s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; scope_chain = s; current_function_decl = NULL_TREE; @@ -5327,7 +5328,8 @@ push_to_top_level (void) current_lang_name = lang_name_cplusplus; current_namespace = global_namespace; push_class_stack (); - skip_evaluation = 0; + cp_unevaluated_operand = 0; + c_inhibit_evaluation_warnings = 0; timevar_pop (TV_NAME_LOOKUP); } @@ -5360,7 +5362,8 @@ pop_from_top_level (void) if (s->need_pop_function_context) pop_function_context (); current_function_decl = s->function_decl; - skip_evaluation = s->skip_evaluation; + cp_unevaluated_operand = s->unevaluated_operand; + c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings; timevar_pop (TV_NAME_LOOKUP); } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0314bb3..bdf3058 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -247,6 +247,10 @@ static void cp_parser_initial_pragma static FILE *cp_lexer_debug_stream; #endif /* ENABLE_CHECKING */ +/* Nonzero if we are parsing an unevaluated operand: an operand to + sizeof, typeof, or alignof. */ +int cp_unevaluated_operand; + /* Create a new main C++ lexer, the lexer that gets tokens from the preprocessor. */ @@ -6385,16 +6389,26 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr) cp_lexer_consume_token (parser->lexer); if (cp_parser_allow_gnu_extensions_p (parser) && cp_lexer_next_token_is (parser->lexer, CPP_COLON)) - /* Implicit true clause. */ - expr = NULL_TREE; + { + /* Implicit true clause. */ + expr = NULL_TREE; + c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node; + } else - /* Parse the expression. */ - expr = cp_parser_expression (parser, /*cast_p=*/false, NULL); + { + /* Parse the expression. */ + c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_false_node; + expr = cp_parser_expression (parser, /*cast_p=*/false, NULL); + c_inhibit_evaluation_warnings += + ((logical_or_expr == truthvalue_true_node) + - (logical_or_expr == truthvalue_false_node)); + } /* The next token should be a `:'. */ cp_parser_require (parser, CPP_COLON, "%<:%>"); /* Parse the assignment-expression. */ assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); + c_inhibit_evaluation_warnings -= logical_or_expr == truthvalue_true_node; /* Build the conditional-expression. */ return build_x_conditional_expr (logical_or_expr, @@ -8857,7 +8871,10 @@ cp_parser_decltype (cp_parser *parser) parser->integral_constant_expression_p = false; /* Do not actually evaluate the expression. */ - ++skip_evaluation; + ++cp_unevaluated_operand; + + /* Do not warn about problems with the expression. */ + ++c_inhibit_evaluation_warnings; /* Parse the opening `('. */ if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>")) @@ -8961,7 +8978,8 @@ cp_parser_decltype (cp_parser *parser) } /* Go back to evaluating expressions. */ - --skip_evaluation; + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; /* Restore the old message and the integral constant expression flags. */ @@ -18188,7 +18206,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) tree saved_qualifying_scope; tree saved_object_scope; bool saved_greater_than_is_operator_p; - bool saved_skip_evaluation; + int saved_unevaluated_operand; + int saved_inhibit_evaluation_warnings; /* [temp.names] @@ -18205,8 +18224,10 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) saved_object_scope = parser->object_scope; /* We need to evaluate the template arguments, even though this template-id may be nested within a "sizeof". */ - saved_skip_evaluation = skip_evaluation; - skip_evaluation = false; + saved_unevaluated_operand = cp_unevaluated_operand; + cp_unevaluated_operand = 0; + saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + c_inhibit_evaluation_warnings = 0; /* Parse the template-argument-list itself. */ if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER) || cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT)) @@ -18273,7 +18294,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) parser->scope = saved_scope; parser->qualifying_scope = saved_qualifying_scope; parser->object_scope = saved_object_scope; - skip_evaluation = saved_skip_evaluation; + cp_unevaluated_operand = saved_unevaluated_operand; + c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings; return arguments; } @@ -18507,7 +18529,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword) } /* Do not actually evaluate the expression. */ - ++skip_evaluation; + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; /* If it's a `(', then we might be looking at the type-id construction. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) @@ -18556,7 +18579,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword) expr = make_pack_expansion (expr); /* Go back to evaluating expressions. */ - --skip_evaluation; + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; /* Free the message we created. */ free (tmp); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7fe4012..5645b23 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5264,7 +5264,8 @@ coerce_template_parms (tree parms, tree inner_args; tree new_args; tree new_inner_args; - bool saved_skip_evaluation; + int saved_unevaluated_operand; + int saved_inhibit_evaluation_warnings; /* When used as a boolean value, indicates whether this is a variadic template parameter list. Since it's an int, we can also @@ -5322,8 +5323,10 @@ coerce_template_parms (tree parms, /* We need to evaluate the template arguments, even though this template-id may be nested within a "sizeof". */ - saved_skip_evaluation = skip_evaluation; - skip_evaluation = false; + saved_unevaluated_operand = cp_unevaluated_operand; + cp_unevaluated_operand = 0; + saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + c_inhibit_evaluation_warnings = 0; new_inner_args = make_tree_vec (nparms); new_args = add_outermost_template_args (args, new_inner_args); for (parm_idx = 0, arg_idx = 0; parm_idx < nparms; parm_idx++, arg_idx++) @@ -5416,7 +5419,8 @@ coerce_template_parms (tree parms, lost++; TREE_VEC_ELT (new_inner_args, arg_idx) = arg; } - skip_evaluation = saved_skip_evaluation; + cp_unevaluated_operand = saved_unevaluated_operand; + c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings; if (lost) return error_mark_node; @@ -7553,7 +7557,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, /* This can happen for a parameter name used later in a function declaration (such as in a late-specified return type). Just make a dummy decl, since it's only used for its type. */ - gcc_assert (skip_evaluation); + gcc_assert (cp_unevaluated_operand != 0); arg_pack = tsubst_decl (parm_pack, args, complain); arg_pack = make_fnparm_pack (arg_pack); } @@ -7944,11 +7948,14 @@ tsubst_aggr_type (tree t, tree argvec; tree context; tree r; - bool saved_skip_evaluation; + int saved_unevaluated_operand; + int saved_inhibit_evaluation_warnings; /* In "sizeof(X<I>)" we need to evaluate "I". */ - saved_skip_evaluation = skip_evaluation; - skip_evaluation = false; + saved_unevaluated_operand = cp_unevaluated_operand; + cp_unevaluated_operand = 0; + saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + c_inhibit_evaluation_warnings = 0; /* First, determine the context for the type we are looking up. */ @@ -7983,7 +7990,8 @@ tsubst_aggr_type (tree t, r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain); } - skip_evaluation = saved_skip_evaluation; + cp_unevaluated_operand = saved_unevaluated_operand; + c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings; return r; } @@ -9782,13 +9790,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { tree type; - ++skip_evaluation; + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; type = tsubst_expr (DECLTYPE_TYPE_EXPR (t), args, complain, in_decl, /*integral_constant_expression_p=*/false); - --skip_evaluation; + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; type = finish_decltype_type (type, @@ -10047,7 +10057,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* This can happen for a parameter name used later in a function declaration (such as in a late-specified return type). Just make a dummy decl, since it's only used for its type. */ - gcc_assert (skip_evaluation); + gcc_assert (cp_unevaluated_operand != 0); /* We copy T because want to tsubst the PARM_DECL only, not the following PARM_DECLs that are chained to T. */ c = copy_node (t); @@ -11407,11 +11417,13 @@ tsubst_copy_and_build (tree t, } else { - ++skip_evaluation; + ++cp_unevaluated_operand; + ++c_inhibit_evaluation_warnings; op1 = tsubst_copy_and_build (op1, args, complain, in_decl, /*function_p=*/false, /*integral_constant_expression_p=*/false); - --skip_evaluation; + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; } if (TYPE_P (op1)) return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index bacb09a..9a43863 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1423,7 +1423,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) { gcc_assert (TREE_CODE (decl) == FIELD_DECL); - if (!object && skip_evaluation) + if (!object && cp_unevaluated_operand != 0) { /* DR 613: Can use non-static data members without an associated object in sizeof/decltype/alignof. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 1ad7506..e3ed871 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2019,7 +2019,7 @@ build_class_member_access_expr (tree object, tree member, if (null_object_p && warn_invalid_offsetof && CLASSTYPE_NON_POD_P (object_type) && !DECL_FIELD_IS_BASE (member) - && !skip_evaluation + && cp_unevaluated_operand == 0 && (complain & tf_warning)) { warning (OPT_Winvalid_offsetof, @@ -3559,13 +3559,15 @@ cp_build_binary_op (location_t location, { if (tree_int_cst_lt (op1, integer_zero_node)) { - if (complain & tf_warning) + if ((complain & tf_warning) + && c_inhibit_evaluation_warnings == 0) warning (0, "right shift count is negative"); } else { if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0 - && (complain & tf_warning)) + && (complain & tf_warning) + && c_inhibit_evaluation_warnings == 0) warning (0, "right shift count >= width of type"); } } @@ -3586,12 +3588,14 @@ cp_build_binary_op (location_t location, { if (tree_int_cst_lt (op1, integer_zero_node)) { - if (complain & tf_warning) + if ((complain & tf_warning) + && c_inhibit_evaluation_warnings == 0) warning (0, "left shift count is negative"); } else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0) { - if (complain & tf_warning) + if ((complain & tf_warning) + && c_inhibit_evaluation_warnings == 0) warning (0, "left shift count >= width of type"); } } |