From: Patrick Palka Date: Thu, 26 May 2016 18:17:43 +0000 (+0000) Subject: Fix PR c++/70822 (bogus error with parenthesized SCOPE_REF) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cac177cfad2b48c29870caeb0af51d7cee645fae;p=gcc.git Fix PR c++/70822 (bogus error with parenthesized SCOPE_REF) gcc/cp/ChangeLog: PR c++/70822 PR c++/70106 * cp-tree.h (REF_PARENTHESIZED_P): Make this flag apply to SCOPE_REFs too. * pt.c (tsubst_qualified_id): If REF_PARENTHESIZED_P is set on the qualified_id then propagate it to the resulting expression. (do_auto_deduction): Check REF_PARENTHESIZED_P on SCOPE_REFs too. * semantics.c (force_paren_expr): If given a SCOPE_REF, just set its REF_PARENTHESIZED_P flag. gcc/testsuite/ChangeLog: PR c++/70822 PR c++/70106 * g++.dg/cpp1y/auto-fn32.C: New test. * g++.dg/cpp1y/paren4.C: New test. From-SVN: r236792 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f0cd5d9abc0..ff5d8f4825c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2016-05-26 Patrick Palka + + PR c++/70822 + PR c++/70106 + * cp-tree.h (REF_PARENTHESIZED_P): Make this flag apply to + SCOPE_REFs too. + * pt.c (tsubst_qualified_id): If REF_PARENTHESIZED_P is set + on the qualified_id then propagate it to the resulting + expression. + (do_auto_deduction): Check REF_PARENTHESIZED_P on SCOPE_REFs + too. + * semantics.c (force_paren_expr): If given a SCOPE_REF, just set + its REF_PARENTHESIZED_P flag. + 2016-05-25 Jason Merrill PR c++/71173 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 02ed5d69cc1..f562a5255b1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -170,7 +170,7 @@ operator == (const cp_expr &lhs, tree rhs) TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR) FNDECL_USED_AUTO (in FUNCTION_DECL) DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE) - REF_PARENTHESIZED_P (in COMPONENT_REF, INDIRECT_REF) + REF_PARENTHESIZED_P (in COMPONENT_REF, INDIRECT_REF, SCOPE_REF) AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR) CONSTRUCTOR_MUTABLE_POISON (in CONSTRUCTOR) 3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). @@ -3398,12 +3398,12 @@ extern void decl_shadowed_for_var_insert (tree, tree); #define PAREN_STRING_LITERAL_P(NODE) \ TREE_LANG_FLAG_0 (STRING_CST_CHECK (NODE)) -/* Indicates whether a COMPONENT_REF has been parenthesized, or an - INDIRECT_REF comes from parenthesizing a _DECL. Currently only set - some of the time in C++14 mode. */ +/* Indicates whether a COMPONENT_REF or a SCOPE_REF has been parenthesized, or + an INDIRECT_REF comes from parenthesizing a _DECL. Currently only set some + of the time in C++14 mode. */ #define REF_PARENTHESIZED_P(NODE) \ - TREE_LANG_FLAG_2 (TREE_CHECK2 ((NODE), COMPONENT_REF, INDIRECT_REF)) + TREE_LANG_FLAG_2 (TREE_CHECK3 ((NODE), COMPONENT_REF, INDIRECT_REF, SCOPE_REF)) /* Nonzero if this AGGR_INIT_EXPR provides for initialization via a constructor call, rather than an ordinary function call. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index df3d634687d..4a24c9840fc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13739,8 +13739,10 @@ tsubst_qualified_id (tree qualified_id, tree args, { if (is_template) expr = build_min_nt_loc (loc, TEMPLATE_ID_EXPR, expr, template_args); - return build_qualified_name (NULL_TREE, scope, expr, - QUALIFIED_NAME_IS_TEMPLATE (qualified_id)); + tree r = build_qualified_name (NULL_TREE, scope, expr, + QUALIFIED_NAME_IS_TEMPLATE (qualified_id)); + REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (qualified_id); + return r; } if (!BASELINK_P (name) && !DECL_P (expr)) @@ -13820,6 +13822,9 @@ tsubst_qualified_id (tree qualified_id, tree args, && TREE_CODE (expr) != OFFSET_REF) expr = convert_from_reference (expr); + if (REF_PARENTHESIZED_P (qualified_id)) + expr = force_paren_expr (expr); + return expr; } @@ -24016,8 +24021,10 @@ do_auto_deduction (tree type, tree init, tree auto_node, if (AUTO_IS_DECLTYPE (auto_node)) { - bool id = (DECL_P (init) || (TREE_CODE (init) == COMPONENT_REF - && !REF_PARENTHESIZED_P (init))); + bool id = (DECL_P (init) + || ((TREE_CODE (init) == COMPONENT_REF + || TREE_CODE (init) == SCOPE_REF) + && !REF_PARENTHESIZED_P (init))); targs = make_tree_vec (1); TREE_VEC_ELT (targs, 0) = finish_decltype_type (init, id, tf_warning_or_error); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 8a3e7fd619b..0cef86758f8 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1647,17 +1647,10 @@ force_paren_expr (tree expr) && TREE_CODE (expr) != SCOPE_REF) return expr; - if (TREE_CODE (expr) == COMPONENT_REF) + if (TREE_CODE (expr) == COMPONENT_REF + || TREE_CODE (expr) == SCOPE_REF) REF_PARENTHESIZED_P (expr) = true; - else if (type_dependent_expression_p (expr) - /* When processing_template_decl, a SCOPE_REF may actually be - referring to a non-static data member of the current class, in - which case its TREE_TYPE may not be properly cv-qualified (the - cv-qualifiers of the implicit *this object haven't yet been taken - into account) so we have to delay building a static_cast until - instantiation. */ - || (processing_template_decl - && TREE_CODE (expr) == SCOPE_REF)) + else if (type_dependent_expression_p (expr)) expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr); else if (VAR_P (expr) && DECL_HARD_REGISTER (expr)) /* We can't bind a hard register variable to a reference. */; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fbd252098de..962421200cd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-05-26 Patrick Palka + + PR c++/70822 + PR c++/70106 + * g++.dg/cpp1y/auto-fn32.C: New test. + * g++.dg/cpp1y/paren4.C: New test. + 2016-05-26 Nathan Sidwell * gcc.dg/20060410.c: Xfail on ptx. diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn32.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn32.C new file mode 100644 index 00000000000..0a5dafce858 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn32.C @@ -0,0 +1,33 @@ +// { dg-do compile { target c++14 } } + +template struct same_type; +template struct same_type {}; + +struct A +{ + static int b; + int c; + + template + decltype(auto) f() { return A::c; } + + template + decltype(auto) g() { return (A::c); } +}; + +A a; + +template +decltype(auto) f() { return A::b; } + +template +decltype(auto) g() { return (A::b); } + +int main() +{ + same_type()), int>(); + same_type()), int&>(); + + same_type()), int>(); + same_type()), int&>(); +} diff --git a/gcc/testsuite/g++.dg/cpp1y/paren4.C b/gcc/testsuite/g++.dg/cpp1y/paren4.C new file mode 100644 index 00000000000..71abe846dbf --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/paren4.C @@ -0,0 +1,14 @@ +// PR c++/70822 +// { dg-do compile { target c++14 } } + +struct a +{ + static int b; +}; + +template +void +foo () +{ + &(a::b); +}