aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-06-20 10:39:53 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-06-20 10:39:53 -0400
commitd84572a4009158fe24931e2f8d8a7aa496d8a570 (patch)
treeddd46f42a2c74e5fd3e577ca9e425f8c61baaaf8
parent4b7d9ed4a8e049e777252718c4cddb85fece7cde (diff)
downloadgcc-d84572a4009158fe24931e2f8d8a7aa496d8a570.zip
gcc-d84572a4009158fe24931e2f8d8a7aa496d8a570.tar.gz
gcc-d84572a4009158fe24931e2f8d8a7aa496d8a570.tar.bz2
re PR c++/43321 ([c++0x] ICE on valid auto)
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
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c11
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/cp/pt.c16
-rw-r--r--gcc/cp/semantics.c59
-rw-r--r--gcc/cp/typeck.c3
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto26.C21
10 files changed, 52 insertions, 77 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5d85ee0..1746670 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2773e34de..904e44c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 59c4a4c..85249f1 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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))
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 3b92665..140e064 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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);
}
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 75dac6a..856a8a7 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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,
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 85f2749..6f15101 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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>'
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 1f683c7..cfe3959 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4803,65 +4803,6 @@ finish_static_assert (tree condition, tree message, location_t location,
}
}
-/* 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.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 39e974b..7af76b1 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 789cdda..6bfc81b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..6e55aa4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/auto26.C
@@ -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);
+}