From patchwork Thu Jan 10 02:52:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: C++ PATCH for c++/55878 (wrong error with --enable-checking) From: Jason Merrill X-Patchwork-Id: 210930 Message-Id: <50EE2D0B.9060405@redhat.com> To: gcc-patches List Date: Wed, 09 Jan 2013 21:52:59 -0500 I still think a bogus error only with --enable-checking doesn't merit P1, but it's still worth fixing. The problem was that the typeid code hadn't been SFINAEd yet. Tested x86_64-pc-linux-gnu, applying to trunk. commit 0b605fda3f97fd69b8106f096109535881413c83 Author: Jason Merrill Date: Wed Jan 9 20:48:15 2013 -0500 PR c++/55878 * rtti.c (build_typeid, get_typeid): Add complain parm. (get_tinfo_decl_dynamic): Likewise. * cp-tree.h, parser.c, pt.c: Adjust. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 810df7d..5482923 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5476,9 +5476,9 @@ extern void finish_repo (void); extern GTY(()) vec *unemitted_tinfo_decls; extern void init_rtti_processing (void); -extern tree build_typeid (tree); +extern tree build_typeid (tree, tsubst_flags_t); extern tree get_tinfo_decl (tree); -extern tree get_typeid (tree); +extern tree get_typeid (tree, tsubst_flags_t); extern tree build_headof (tree); extern tree build_dynamic_cast (tree, tree, tsubst_flags_t); extern void emit_support_tinfos (void); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8a90bec..36e9342 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -5473,7 +5473,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* If all went well, simply lookup the type-id. */ if (cp_parser_parse_definitely (parser)) - postfix_expression = get_typeid (type); + postfix_expression = get_typeid (type, tf_warning_or_error); /* Otherwise, fall back to the expression variant. */ else { @@ -5482,7 +5482,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, /* Look for an expression. */ expression = cp_parser_expression (parser, /*cast_p=*/false, & idk); /* Compute its typeid. */ - postfix_expression = build_typeid (expression); + postfix_expression = build_typeid (expression, tf_warning_or_error); /* Look for the `)' token. */ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c55dabef..6d78dd2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14223,12 +14223,12 @@ tsubst_copy_and_build (tree t, if (TYPE_P (operand_0)) { operand_0 = tsubst (operand_0, args, complain, in_decl); - RETURN (get_typeid (operand_0)); + RETURN (get_typeid (operand_0, complain)); } else { operand_0 = RECUR (operand_0); - RETURN (build_typeid (operand_0)); + RETURN (build_typeid (operand_0, complain)); } } diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index de28371..77fd046 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -108,7 +108,6 @@ static tree tinfo_name (tree, bool); static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t); static tree throw_bad_cast (void); static tree throw_bad_typeid (void); -static tree get_tinfo_decl_dynamic (tree); static tree get_tinfo_ptr (tree); static bool typeid_ok_p (void); static int qualifier_flags (tree); @@ -238,7 +237,7 @@ throw_bad_typeid (void) otherwise return the static type of the expression. */ static tree -get_tinfo_decl_dynamic (tree exp) +get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain) { tree type; tree t; @@ -257,7 +256,7 @@ get_tinfo_decl_dynamic (tree exp) /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */ if (CLASS_TYPE_P (type) || type == unknown_type_node || type == init_list_type_node) - type = complete_type_or_else (type, exp); + type = complete_type_or_maybe_complain (type, exp, complain); if (!type) return error_mark_node; @@ -278,7 +277,7 @@ get_tinfo_decl_dynamic (tree exp) /* Otherwise return the type_info for the static type of the expr. */ t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type)); - return cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error); + return cp_build_indirect_ref (t, RO_NULL, complain); } static bool @@ -316,7 +315,7 @@ typeid_ok_p (void) an lvalue of type "const std::type_info". */ tree -build_typeid (tree exp) +build_typeid (tree exp, tsubst_flags_t complain) { tree cond = NULL_TREE, initial_expr = exp; int nonnull = 0; @@ -340,10 +339,10 @@ build_typeid (tree exp) exp = mark_lvalue_use (exp); exp = stabilize_reference (exp); cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0), - tf_warning_or_error); + complain); } - exp = get_tinfo_decl_dynamic (exp); + exp = get_tinfo_decl_dynamic (exp, complain); if (exp == error_mark_node) return error_mark_node; @@ -469,7 +468,7 @@ get_tinfo_ptr (tree type) /* Return the type_info object for TYPE. */ tree -get_typeid (tree type) +get_typeid (tree type, tsubst_flags_t complain) { if (type == error_mark_node || !typeid_ok_p ()) return error_mark_node; @@ -489,13 +488,12 @@ get_typeid (tree type) /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics. */ if (CLASS_TYPE_P (type) || type == unknown_type_node || type == init_list_type_node) - type = complete_type_or_else (type, NULL_TREE); + type = complete_type_or_maybe_complain (type, NULL_TREE, complain); if (!type) return error_mark_node; - return cp_build_indirect_ref (get_tinfo_ptr (type), RO_NULL, - tf_warning_or_error); + return cp_build_indirect_ref (get_tinfo_ptr (type), RO_NULL, complain); } /* Check whether TEST is null before returning RESULT. If TEST is used in