re PR c++/55878 (--enable-checking=yes rejection of typeid)
authorJason Merrill <jason@redhat.com>
Thu, 10 Jan 2013 02:54:39 +0000 (21:54 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 10 Jan 2013 02:54:39 +0000 (21:54 -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.

From-SVN: r195075

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/testsuite/g++.dg/template/typeid1.C [new file with mode: 0644]

index fe64da5..eba897f 100644 (file)
@@ -1,5 +1,10 @@
 2013-01-09  Jason Merrill  <jason@redhat.com>
 
+       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.
+
        PR c++/55893
        * decl.c (cp_finish_decl): Clear TREE_READONLY if the variable
        needs destruction.
index 810df7d..5482923 100644 (file)
@@ -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);
index 8a90bec..36e9342 100644 (file)
@@ -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);
          }
index c55dabe..6d78dd2 100644 (file)
@@ -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));
          }
       }
 
index de28371..77fd046 100644 (file)
@@ -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
diff --git a/gcc/testsuite/g++.dg/template/typeid1.C b/gcc/testsuite/g++.dg/template/typeid1.C
new file mode 100644 (file)
index 0000000..6df5f71
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/55878
+
+#include <typeinfo>
+
+struct S;
+
+template <typename T>
+static bool fn (S *s)
+{
+  return typeid (*s) == typeid (T);
+}
+
+struct S
+{
+};
+
+bool x = fn<S> (__null);