From d84572a4009158fe24931e2f8d8a7aa496d8a570 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 20 Jun 2011 10:39:53 -0400 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 10 +++++ gcc/cp/cp-tree.h | 1 - gcc/cp/decl.c | 11 ++---- gcc/cp/init.c | 3 +- gcc/cp/parser.c | 2 +- gcc/cp/pt.c | 16 +++++--- gcc/cp/semantics.c | 59 ----------------------------- gcc/cp/typeck.c | 3 +- gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/g++.dg/cpp0x/auto26.C | 21 ++++++++++ 10 files changed, 52 insertions(+), 77 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/auto26.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5d85ee0c377..1746670c520 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,15 @@ 2011-06-20 Jason Merrill + 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 2773e34de23..904e44c77b1 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 59c4a4c9d01..85249f11480 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 3b926657c5e..140e064b659 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 75dac6ae214..856a8a7b67c 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 85f27497d90..6f15101d6e9 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 '' diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 1f683c7f9bd..cfe3959462e 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 39e974bb802..7af76b1be76 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 789cdda7cdd..6bfc81b0838 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2011-06-20 Jason Merrill + 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 00000000000..6e55aa451ac --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto26.C @@ -0,0 +1,21 @@ +// PR c++/43321 +// { dg-options -std=c++0x } + +template +void f(T t) +{ + auto *p = t; +} + +template +void g(const T& tr) +{ + auto p = *tr; +} + +int main() +{ + int b; + f(&b); + g(&b); +} -- 2.30.2