From 1401bfe3006861b8254a5bfac158193ab59c322d Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 7 Jan 2015 15:17:59 +0000 Subject: PR c++/63658 * pt.c (convert_nontype_argument): Call convert_from_reference. (check_instantiated_arg): Don't be confused by reference refs. (unify): Look through reference refs on the arg, too. * mangle.c (write_template_arg): Look through reference refs. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@219305 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/mangle.c | 2 ++ gcc/cp/pt.c | 11 ++++++++--- gcc/testsuite/g++.dg/template/ref9.C | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/ref9.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 049171425c4..f95ce7ed432 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2015-01-07 Jason Merrill + + PR c++/63658 + * pt.c (convert_nontype_argument): Call convert_from_reference. + (check_instantiated_arg): Don't be confused by reference refs. + (unify): Look through reference refs on the arg, too. + * mangle.c (write_template_arg): Look through reference refs. + 2014-12-19 Paolo Carlini PR c++/60955 diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index d944d5e0f3a..c9b1c5f8eb0 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3111,6 +3111,8 @@ write_template_arg (tree node) } } + if (REFERENCE_REF_P (node)) + node = TREE_OPERAND (node, 0); if (TREE_CODE (node) == NOP_EXPR && TREE_CODE (TREE_TYPE (node)) == REFERENCE_TYPE) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5d265ae2db9..cfe79648a33 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6084,7 +6084,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) right type? */ gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (expr))); - return expr; + return convert_from_reference (expr); } /* Subroutine of coerce_template_template_parms, which returns 1 if @@ -15436,6 +15436,7 @@ check_instantiated_arg (tree tmpl, tree t, tsubst_flags_t complain) constant. */ else if (TREE_TYPE (t) && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t)) + && !REFERENCE_REF_P (t) && !TREE_CONSTANT (t)) { if (complain & tf_error) @@ -18159,8 +18160,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, case INDIRECT_REF: if (REFERENCE_REF_P (parm)) - return unify (tparms, targs, TREE_OPERAND (parm, 0), arg, - strict, explain_p); + { + if (REFERENCE_REF_P (arg)) + arg = TREE_OPERAND (arg, 0); + return unify (tparms, targs, TREE_OPERAND (parm, 0), arg, + strict, explain_p); + } /* FALLTHRU */ default: diff --git a/gcc/testsuite/g++.dg/template/ref9.C b/gcc/testsuite/g++.dg/template/ref9.C new file mode 100644 index 00000000000..983f627887f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ref9.C @@ -0,0 +1,15 @@ +// PR c++/63658 + +struct Descriptor {}; + +template +struct foo +{ + void size (); +}; + +Descriptor g_descriptor = {}; + +template<> void foo::size() +{ +} -- cgit v1.2.3 From 756aa6e5f6df89484c90826d341f3cc7ef31d78b Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 7 Jan 2015 15:18:05 +0000 Subject: PR c++/63657 PR c++/38958 * call.c (set_up_extended_ref_temp): Set TREE_USED on the reference if the temporary has a non-trivial destructor. * decl.c (poplevel): Don't look through references. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@219306 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/call.c | 4 ++++ gcc/cp/decl.c | 3 +-- gcc/testsuite/g++.dg/warn/Wunused-var-22.C | 12 ++++++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wunused-var-22.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f95ce7ed432..1f7478ec1e0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2015-01-07 Jason Merrill + PR c++/63657 + PR c++/38958 + * call.c (set_up_extended_ref_temp): Set TREE_USED on the reference + if the temporary has a non-trivial destructor. + * decl.c (poplevel): Don't look through references. + PR c++/63658 * pt.c (convert_nontype_argument): Call convert_from_reference. (check_instantiated_arg): Don't be confused by reference refs. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 709b6be0e3d..46bb880a878 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -9393,6 +9393,10 @@ set_up_extended_ref_temp (tree decl, tree expr, vec **cleanups, /* Check whether the dtor is callable. */ cxx_maybe_build_cleanup (var, tf_warning_or_error); } + /* Avoid -Wunused-variable warning (c++/38958). */ + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) + && TREE_CODE (decl) == VAR_DECL) + TREE_USED (decl) = DECL_READ_P (decl) = true; *initp = init; return var; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1f3a552f94f..f5e942371d9 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -630,8 +630,7 @@ poplevel (int keep, int reverse, int functionbody) push_local_binding where the list of decls returned by getdecls is built. */ decl = TREE_CODE (d) == TREE_LIST ? TREE_VALUE (d) : d; - // See through references for improved -Wunused-variable (PR 38958). - tree type = non_reference (TREE_TYPE (decl)); + tree type = TREE_TYPE (decl); if (VAR_P (decl) && (! TREE_USED (decl) || !DECL_READ_P (decl)) && ! DECL_IN_SYSTEM_HEADER (decl) diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-22.C b/gcc/testsuite/g++.dg/warn/Wunused-var-22.C new file mode 100644 index 00000000000..8ae46c17f82 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wunused-var-22.C @@ -0,0 +1,12 @@ +// PR c++/63657 +// { dg-options "-Wunused-variable" } + +class Bar +{ + virtual ~Bar() {} +}; +Bar& getbar(); +void bar() +{ + Bar& b = getbar(); // { dg-warning "unused" } +} -- cgit v1.2.3 From 1246395b1326e1ef73e45f777a55967bef253b3f Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 7 Jan 2015 15:18:16 +0000 Subject: PR c++/64029 * decl.c (grok_reference_init): Complete array type. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@219307 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/decl.c | 17 ++++++++++++++++- gcc/testsuite/g++.dg/cpp0x/initlist89.C | 4 ++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist89.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1f7478ec1e0..02ea105ce4c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2015-01-07 Jason Merrill + PR c++/64029 + * decl.c (grok_reference_init): Complete array type. + PR c++/63657 PR c++/38958 * call.c (set_up_extended_ref_temp): Set TREE_USED on the reference diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f5e942371d9..1613e9ac0aa 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4791,11 +4791,26 @@ grok_reference_init (tree decl, tree type, tree init, int flags) init = build_x_compound_expr_from_list (init, ELK_INIT, tf_warning_or_error); - if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE + tree ttype = TREE_TYPE (type); + if (TREE_CODE (ttype) != ARRAY_TYPE && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) /* Note: default conversion is only called in very special cases. */ init = decay_conversion (init, tf_warning_or_error); + /* check_initializer handles this for non-reference variables, but for + references we need to do it here or the initializer will get the + incomplete array type and confuse later calls to + cp_complete_array_type. */ + if (TREE_CODE (ttype) == ARRAY_TYPE + && TYPE_DOMAIN (ttype) == NULL_TREE + && (BRACE_ENCLOSED_INITIALIZER_P (init) + || TREE_CODE (init) == STRING_CST)) + { + cp_complete_array_type (&ttype, init, false); + if (ttype != TREE_TYPE (type)) + type = cp_build_reference_type (ttype, TYPE_REF_IS_RVALUE (type)); + } + /* Convert INIT to the reference type TYPE. This may involve the creation of a temporary, whose lifetime must be the same as that of the reference. If so, a DECL_EXPR for the temporary will be diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist89.C b/gcc/testsuite/g++.dg/cpp0x/initlist89.C new file mode 100644 index 00000000000..e221664e30f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist89.C @@ -0,0 +1,4 @@ +// PR c++/64029 +// { dg-do compile { target c++11 } } + +const int (&in)[]{1,2,3,4,5}; -- cgit v1.2.3 From 4b8c24b2d5e50af0786a3349d6e22c4e3318cdf0 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 7 Jan 2015 15:18:21 +0000 Subject: PR c++/64297 * typeck.c (apply_memfn_quals): Correct wrong TYPE_CANONICAL. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@219308 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/typeck.c | 6 ++++++ gcc/testsuite/g++.dg/cpp0x/ref-qual16.C | 12 ++++++++++++ 3 files changed, 21 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/ref-qual16.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 02ea105ce4c..2096703f0ec 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2015-01-07 Jason Merrill + PR c++/64297 + * typeck.c (apply_memfn_quals): Correct wrong TYPE_CANONICAL. + PR c++/64029 * decl.c (grok_reference_init): Complete array type. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 03d7ab807d7..cd8318d92c6 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8881,6 +8881,12 @@ apply_memfn_quals (tree type, cp_cv_quals memfn_quals, cp_ref_qualifier rqual) /* This should really have a different TYPE_MAIN_VARIANT, but that gets complex. */ tree result = build_qualified_type (type, memfn_quals); + if (tree canon = TYPE_CANONICAL (result)) + if (canon != result) + /* check_qualified_type doesn't check the ref-qualifier, so make sure + TYPE_CANONICAL is correct. */ + TYPE_CANONICAL (result) + = build_ref_qualified_type (canon, type_memfn_rqual (result)); result = build_exception_variant (result, TYPE_RAISES_EXCEPTIONS (type)); return build_ref_qualified_type (result, rqual); } diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual16.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual16.C new file mode 100644 index 00000000000..1d7650bb61b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/ref-qual16.C @@ -0,0 +1,12 @@ +// PR c++/64297 +// { dg-do compile { target c++11 } } + +struct A { + typedef int X; + template X m_fn1() const; +}; +template struct is_function {}; +is_function i; +struct D { + template > D(Y); +} b(&A::m_fn1<0>); -- cgit v1.2.3 From ee4777507605dfc95e7433e1bf5659add2fc0f21 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 7 Jan 2015 15:18:27 +0000 Subject: PR c++/64251 * decl2.c (mark_used): Don't mark if in_template_function. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@219309 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/decl2.c | 2 +- gcc/testsuite/g++.dg/template/non-dependent14.C | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/template/non-dependent14.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2096703f0ec..832baf84b22 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2015-01-07 Jason Merrill + PR c++/64251 + * decl2.c (mark_used): Don't mark if in_template_function. + PR c++/64297 * typeck.c (apply_memfn_quals): Correct wrong TYPE_CANONICAL. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a2626d4c77b..78c1124e277 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4914,7 +4914,7 @@ mark_used (tree decl, tsubst_flags_t complain) --function_depth; } - if (processing_template_decl) + if (processing_template_decl || in_template_function ()) return true; /* Check this too in case we're within fold_non_dependent_expr. */ diff --git a/gcc/testsuite/g++.dg/template/non-dependent14.C b/gcc/testsuite/g++.dg/template/non-dependent14.C new file mode 100644 index 00000000000..b257d9baf1a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/non-dependent14.C @@ -0,0 +1,7 @@ +// PR c++/64251 + +class DictionaryValue {}; +template void CreateValue(T) { + DictionaryValue(0); + CreateValue(0); +} -- cgit v1.2.3 From f8e0536caf1c2a6b4ac1a3281ad6f076c95b455a Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 7 Jan 2015 15:18:32 +0000 Subject: PR c++/64352 * pt.c (tsubst_copy_and_build): Pass complain to mark_used. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@219310 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/pt.c | 2 +- gcc/testsuite/g++.dg/cpp0x/deleted9.C | 31 +++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/deleted9.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 832baf84b22..0d7e2fe8639 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2015-01-07 Jason Merrill + PR c++/64352 + * pt.c (tsubst_copy_and_build): Pass complain to mark_used. + PR c++/64251 * decl2.c (mark_used): Don't mark if in_template_function. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index cfe79648a33..699ae69175c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14818,7 +14818,7 @@ tsubst_copy_and_build (tree t, /* Remember that there was a reference to this entity. */ if (DECL_P (function)) - mark_used (function); + mark_used (function, complain); /* Put back tf_decltype for the actual call. */ complain |= decltype_flag; diff --git a/gcc/testsuite/g++.dg/cpp0x/deleted9.C b/gcc/testsuite/g++.dg/cpp0x/deleted9.C new file mode 100644 index 00000000000..af97be7c35e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/deleted9.C @@ -0,0 +1,31 @@ +// PR c++/64352 +// { dg-do compile { target c++11 } } + +template struct bool_type +{ static constexpr bool value = B; }; + +using true_type = bool_type; +using false_type = bool_type; + +template T&& declval(); + +template struct void_ { using type = void; }; +template using void_t = typename void_::type; + +template +struct _Has_addressof_free: false_type { }; + +template +struct _Has_addressof_free +<_Tp, void_t()) )>> +: true_type { }; + +struct foo {}; +void operator&(foo) = delete; + +int main() +{ + static_assert( !_Has_addressof_free::value, "" ); + // error: use of deleted function 'void operator&(foo)' + static_assert( !_Has_addressof_free::value, "" ); +} -- cgit v1.2.3 From 06833bfdb40a5b286e753add8b9e4ce751013165 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 7 Jan 2015 15:18:39 +0000 Subject: PR c++/64487 * semantics.c (finish_offsetof): Handle templates here. * parser.c (cp_parser_builtin_offsetof): Not here. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@219311 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/parser.c | 7 +------ gcc/cp/semantics.c | 8 ++++++++ gcc/testsuite/g++.dg/template/offsetof3.C | 18 ++++++++++++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/offsetof3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0d7e2fe8639..8fcbbe65352 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2015-01-07 Jason Merrill + PR c++/64487 + * semantics.c (finish_offsetof): Handle templates here. + * parser.c (cp_parser_builtin_offsetof): Not here. + PR c++/64352 * pt.c (tsubst_copy_and_build): Pass complain to mark_used. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7893235afba..93f94d260c1 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -8479,12 +8479,7 @@ cp_parser_builtin_offsetof (cp_parser *parser) } success: - /* If we're processing a template, we can't finish the semantics yet. - Otherwise we can fold the entire expression now. */ - if (processing_template_decl) - expr = build1 (OFFSETOF_EXPR, size_type_node, expr); - else - expr = finish_offsetof (expr); + expr = finish_offsetof (expr); failure: parser->integral_constant_expression_p = save_ice_p; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index e9635f6a202..bbed56fb06e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3803,6 +3803,14 @@ finish_bases (tree type, bool direct) tree finish_offsetof (tree expr) { + /* If we're processing a template, we can't finish the semantics yet. + Otherwise we can fold the entire expression now. */ + if (processing_template_decl) + { + expr = build1 (OFFSETOF_EXPR, size_type_node, expr); + return expr; + } + if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR) { error ("cannot apply % to destructor %<~%T%>", diff --git a/gcc/testsuite/g++.dg/template/offsetof3.C b/gcc/testsuite/g++.dg/template/offsetof3.C new file mode 100644 index 00000000000..b17374645b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/offsetof3.C @@ -0,0 +1,18 @@ +// PR c++/64487 + +struct foo { + int member; +}; + +template < int N> +struct bar {}; + +template +struct qux { + static bar static_member; +}; + +template +bar qux::static_member; + +int main() { } -- cgit v1.2.3