re PR c++/43321 ([c++0x] ICE on valid auto)
authorJason Merrill <jason@redhat.com>
Mon, 20 Jun 2011 14:39:53 +0000 (10:39 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 20 Jun 2011 14:39:53 +0000 (10:39 -0400)
PR c++/43321
* semantics.c (describable_type): Remove.
* cp-tree.h: Likewise.
* decl.c (cp_finish_decl): Don't call it.
* init.c (build_new): Likewise.
* parser.c (cp_parser_omp_for_loop): Likewise.
* pt.c (tsubst_decl): Likewise.
(do_auto_deduction): If we fail in a template, try again
at instantiation time.

From-SVN: r175212

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/auto26.C [new file with mode: 0644]

index 5d85ee0c3776efbfd67169a7596e4e0c79c10d54..1746670c520ee8f53ca7f229b1f9614aa97e7fab 100644 (file)
@@ -1,5 +1,15 @@
 2011-06-20  Jason Merrill  <jason@redhat.com>
 
+       PR c++/43321
+       * semantics.c (describable_type): Remove.
+       * cp-tree.h: Likewise.
+       * decl.c (cp_finish_decl): Don't call it.
+       * init.c (build_new): Likewise.
+       * parser.c (cp_parser_omp_for_loop): Likewise.
+       * pt.c (tsubst_decl): Likewise.
+       (do_auto_deduction): If we fail in a template, try again
+       at instantiation time.
+
        PR c++/43831
        * parser.c (cp_parser_lambda_introducer): Complain about redundant
        captures.
index 2773e34de2314a9082f68eeb9c406bc4cfb9f986..904e44c77b16076d2232ff30c31d77a27e7c130d 100644 (file)
@@ -5445,7 +5445,6 @@ extern bool cxx_omp_create_clause_info            (tree, tree, bool, bool, bool);
 extern tree baselink_for_fns                    (tree);
 extern void finish_static_assert                (tree, tree, location_t,
                                                  bool);
-extern tree describable_type                   (tree);
 extern tree finish_decltype_type                (tree, bool, tsubst_flags_t);
 extern tree finish_trait_expr                  (enum cp_trait_kind, tree, tree);
 extern tree build_lambda_expr                   (void);
index 59c4a4c9d01665717a5e4347e6aa3bb5908a1af8..85249f114804b3a33f5960290d576a2501b60243 100644 (file)
@@ -5944,13 +5944,10 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
        d_init = build_x_compound_expr_from_list (d_init, ELK_INIT,
                                                  tf_warning_or_error);
       d_init = resolve_nondeduced_context (d_init);
-      if (describable_type (d_init))
-       {
-         type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
-                                                      auto_node);
-         if (type == error_mark_node)
-           return;
-       }
+      type = TREE_TYPE (decl) = do_auto_deduction (type, d_init,
+                                                  auto_node);
+      if (type == error_mark_node)
+       return;
     }
 
   if (!ensure_literal_type_for_constexpr_object (decl))
index 3b926657c5e7259759aaca29fa0bf2d2eec75151..140e064b6599b9645d8a66b3642acd967038591e 100644 (file)
@@ -2600,8 +2600,7 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts,
        {
          tree d_init = VEC_index (tree, *init, 0);
          d_init = resolve_nondeduced_context (d_init);
-         if (describable_type (d_init))
-           type = do_auto_deduction (type, d_init, auto_node);
+         type = do_auto_deduction (type, d_init, auto_node);
        }
     }
 
index 75dac6ae2147fe454e9aacefaab73a171d3cbb20..856a8a7b67c076dbb6721c203f1548d9d55297e3 100644 (file)
@@ -24504,7 +24504,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
                                                    &is_direct_init,
                                                    &is_non_constant_init);
 
-                     if (auto_node && describable_type (init))
+                     if (auto_node)
                        {
                          TREE_TYPE (decl)
                            = do_auto_deduction (TREE_TYPE (decl), init,
index 85f27497d9004d4d6f6f24269c14980c2d8a5bb3..6f15101d6e921dc9029f659b3b6ec6c44454432a 100644 (file)
@@ -10122,11 +10122,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
            if (auto_node && init)
              {
                init = resolve_nondeduced_context (init);
-               if (describable_type (init))
-                 {
-                   type = do_auto_deduction (type, init, auto_node);
-                   TREE_TYPE (r) = type;
-                 }
+               TREE_TYPE (r) = type
+                 = do_auto_deduction (type, init, auto_node);
              }
          }
        else
@@ -19302,6 +19299,12 @@ do_auto_deduction (tree type, tree init, tree auto_node)
   tree decl;
   int val;
 
+  if (processing_template_decl
+      && (TREE_TYPE (init) == NULL_TREE
+         || BRACE_ENCLOSED_INITIALIZER_P (init)))
+    /* Not enough information to try this yet.  */
+    return type;
+
   /* The name of the object being declared shall not appear in the
      initializer expression.  */
   decl = cp_walk_tree_without_duplicates (&init, contains_auto_r, type);
@@ -19331,6 +19334,9 @@ do_auto_deduction (tree type, tree init, tree auto_node)
                               DEDUCE_CALL, LOOKUP_NORMAL);
   if (val > 0)
     {
+      if (processing_template_decl)
+       /* Try again at instantiation time.  */
+       return type;
       if (type && type != error_mark_node)
        /* If type is error_mark_node a diagnostic must have been
           emitted by now.  Also, having a mention to '<type error>'
index 1f683c7f9bdc51bbc360014b284f1d9a81d39a29..cfe3959462eb56f6c80c93180ca3361c7bab620c 100644 (file)
@@ -4803,65 +4803,6 @@ finish_static_assert (tree condition, tree message, location_t location,
     }
 }
 \f
-/* Returns the type of EXPR for cases where we can determine it even though
-   EXPR is a type-dependent expression.  */
-
-tree
-describable_type (tree expr)
-{
-  tree type = NULL_TREE;
-
-  if (! type_dependent_expression_p (expr)
-      && ! type_unknown_p (expr))
-    {
-      type = unlowered_expr_type (expr);
-      if (real_lvalue_p (expr))
-       type = build_reference_type (type);
-    }
-
-  if (type)
-    return type;
-
-  switch (TREE_CODE (expr))
-    {
-    case VAR_DECL:
-    case PARM_DECL:
-    case RESULT_DECL:
-    case FUNCTION_DECL:
-      return TREE_TYPE (expr);
-      break;
-
-    case NEW_EXPR:
-    case CONST_DECL:
-    case TEMPLATE_PARM_INDEX:
-    case CAST_EXPR:
-    case STATIC_CAST_EXPR:
-    case REINTERPRET_CAST_EXPR:
-    case CONST_CAST_EXPR:
-    case DYNAMIC_CAST_EXPR:
-      type = TREE_TYPE (expr);
-      break;
-
-    case INDIRECT_REF:
-      {
-       tree ptrtype = describable_type (TREE_OPERAND (expr, 0));
-       if (ptrtype && POINTER_TYPE_P (ptrtype))
-         type = build_reference_type (TREE_TYPE (ptrtype));
-      }
-      break;
-
-    default:
-      if (TREE_CODE_CLASS (TREE_CODE (expr)) == tcc_constant)
-       type = TREE_TYPE (expr);
-      break;
-    }
-
-  if (type && type_uses_auto (type))
-    return NULL_TREE;
-  else
-    return type;
-}
-
 /* Implements the C++0x decltype keyword. Returns the type of EXPR,
    suitable for use as a type-specifier.
 
index 39e974bb8027befe26b276a70e36d849774a1cb4..7af76b1be7614e45a094a71d1fe867fbeaf274c3 100644 (file)
@@ -2681,8 +2681,7 @@ build_x_indirect_ref (tree expr, ref_operator errorstring,
 
   if (processing_template_decl)
     {
-      /* Retain the type if we know the operand is a pointer so that
-        describable_type doesn't make auto deduction break.  */
+      /* Retain the type if we know the operand is a pointer.  */
       if (TREE_TYPE (expr) && POINTER_TYPE_P (TREE_TYPE (expr)))
        return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
       if (type_dependent_expression_p (expr))
index 789cdda7cddae71b8867815faa4240e93e6cf7b4..6bfc81b0838de9167123056072e054d279fcb5e1 100644 (file)
@@ -1,5 +1,8 @@
 2011-06-20  Jason Merrill  <jason@redhat.com>
 
+       PR c++/43321
+       * g++.dg/cpp0x/auto26.C: New.
+
        PR c++/43831
        * g++.dg/cpp0x/lambda/lambda-capture-reduncancy.C: New.
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto26.C b/gcc/testsuite/g++.dg/cpp0x/auto26.C
new file mode 100644 (file)
index 0000000..6e55aa4
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/43321
+// { dg-options -std=c++0x }
+
+template <class T>
+void f(T t)
+{
+  auto *p = t;
+}
+
+template <class T>
+void g(const T& tr)
+{
+  auto p = *tr;
+}
+
+int main()
+{
+  int b;
+  f(&b);
+  g(&b);
+}