Fixing issues reported by users. 2014-10-20 Andrew Sutton <andrew.n.sut...@gmail.com>
Fixing user-reported issues and regressions * gcc/cp/parser.c (cp_parser_template_declaration_after_exp): Only pop access checks on failed parsing. * gcc/cp/pt.cpp (type_dependent_expr_p): Always treat a requires-expr as if dependently typed. Otherwise, we try to evaluate these expressions when they have dependent types. * gcc/cp/constriant.cc (normalize_stmt_list): Remove unused function. (normalize_call): Don't fold constraints during normalization. * gcc/testsuite/g++.dg/concepts/decl-diagnose.C: Update diagnostics. Andrew Sutton
Index: pt.c =================================================================== --- pt.c (revision 214991) +++ pt.c (working copy) @@ -21646,6 +21646,16 @@ type_dependent_expression_p (tree expres return dependent_type_p (type); } + // A requires expression has type bool, but is always treated as if + // it were a dependent expression. + // + // FIXME: This could be improved. Perhaps the type of the requires + // expression depends on the satisfaction of its constraints. That + // is, its type is bool only if its substitution into its normalized + // constraints succeeds. + if (TREE_CODE (expression) == REQUIRES_EXPR) + return true; + if (TREE_CODE (expression) == SCOPE_REF) { tree scope = TREE_OPERAND (expression, 0); Index: constraint.cc =================================================================== --- constraint.cc (revision 216159) +++ constraint.cc (working copy) @@ -326,7 +326,6 @@ tree normalize_nested_req (tree); tree normalize_var (tree); tree normalize_cleanup_point (tree); tree normalize_template_id (tree); -tree normalize_stmt_list (tree); tree normalize_atom (tree); // Reduce the requirement T into a logical formula written in terms of @@ -559,13 +558,13 @@ normalize_call (tree t) tree fn = TREE_VALUE (check); tree args = TREE_PURPOSE (check); - // Reduce the body of the function into the constriants language. + // Normalize the body of the function into the constriants language. tree body = normalize_constraints (DECL_SAVED_TREE (fn)); if (!body) return error_mark_node; // Instantiate the reduced results using the deduced args. - tree result = tsubst_constraint_expr (body, args, false); + tree result = tsubst_constraint_expr (body, args, true); if (result == error_mark_node) return error_mark_node;
Index: testsuite/g++.dg/concepts/decl-diagnose.C =================================================================== --- testsuite/g++.dg/concepts/decl-diagnose.C (revision 214241) +++ testsuite/g++.dg/concepts/decl-diagnose.C (working copy) @@ -4,12 +4,12 @@ typedef concept int CINT; // { dg-error void f(concept int); // { dg-error "a parameter cannot be declared 'concept'" } -concept int f2(); // { dg-error "result must be bool" } +concept int f2(); // { dg-error "return type" } concept bool f3(); struct X { - concept int f4(); // { dg-error "result must be bool|declared with function parameters" } + concept int f4(); // { dg-error "return type|function parameters" } concept bool f5(); // { dg-error "declared with function parameters" } static concept bool f6(); // { dg-error "a concept cannot be a static member function" } static concept bool x; // { dg-error "declared 'concept'" }
Index: cp/parser.c =================================================================== --- cp/parser.c (revision 216159) +++ cp/parser.c (working copy) @@ -24422,12 +24422,10 @@ cp_parser_template_declaration_after_exp push_deferring_access_checks (dk_deferred); parameter_list = cp_parser_template_introduction (parser); - pop_deferring_access_checks (); - if (parameter_list == error_mark_node) { - // Restore template requirements before returning. current_template_reqs = saved_template_reqs; + pop_deferring_access_checks (); return; }