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 <ja...@redhat.com>
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<tree, va_gc> *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