diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-01-07 16:03:43 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2015-01-07 16:03:43 +0000 |
commit | f17e41c12d71ca74fe59bcf3ea59fe7410918673 (patch) | |
tree | 8c86934eb12f74fa47c2881767b4bf2d8d331878 | |
parent | af8fa99f2e708a4dbccaeaadb8a1eb44f71a4291 (diff) | |
parent | 06833bfdb40a5b286e753add8b9e4ce751013165 (diff) |
svn merge -r219275:219311 svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/redhat/gcc-4_9-branch@219315 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 30 | ||||
-rw-r--r-- | gcc/cp/call.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 20 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 2 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 7 | ||||
-rw-r--r-- | gcc/cp/pt.c | 13 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 8 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/deleted9.C | 31 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist89.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/ref-qual16.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/non-dependent14.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/offsetof3.C | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/ref9.C | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wunused-var-22.C | 12 |
16 files changed, 177 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6d4461eba3e..1c9dae489c6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,33 @@ +2015-01-07 Jason Merrill <jason@redhat.com> + + 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. + + 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. + + 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 + 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. + (unify): Look through reference refs on the arg, too. + * mangle.c (write_template_arg): Look through reference refs. + 2014-12-19 Paolo Carlini <paolo.carlini@oracle.com> PR c++/60955 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<tree, va_gc> **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 fdc1794ce39..a355d6e84ba 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) @@ -4792,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/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/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/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/pt.c b/gcc/cp/pt.c index 5d265ae2db9..699ae69175c 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 @@ -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; @@ -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/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 %<offsetof%> to destructor %<~%T%>", diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 64b58d409a2..c564c14f97f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8878,6 +8878,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/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<bool B> struct bool_type +{ static constexpr bool value = B; }; + +using true_type = bool_type<true>; +using false_type = bool_type<false>; + +template<typename T> T&& declval(); + +template<typename...> struct void_ { using type = void; }; +template<typename... I> using void_t = typename void_<I...>::type; + +template<typename _Tp, typename = void> +struct _Has_addressof_free: false_type { }; + +template<typename _Tp> +struct _Has_addressof_free +<_Tp, void_t<decltype( operator&(declval<const _Tp&>()) )>> +: true_type { }; + +struct foo {}; +void operator&(foo) = delete; + +int main() +{ + static_assert( !_Has_addressof_free<int>::value, "" ); + // error: use of deleted function 'void operator&(foo)' + static_assert( !_Has_addressof_free<foo>::value, "" ); +} 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}; 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 <int> X m_fn1() const; +}; +template <typename> struct is_function {}; +is_function<int() const &> i; +struct D { + template <typename Y, typename = is_function<Y>> D(Y); +} b(&A::m_fn1<0>); 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 <typename T> void CreateValue(T) { + DictionaryValue(0); + CreateValue(0); +} 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 <int N> +struct qux { + static bar<N+__builtin_offsetof(foo,member)> static_member; +}; + +template <int N> +bar<N+__builtin_offsetof(foo,member)> qux<N>::static_member; + +int main() { } 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 <Descriptor & D> +struct foo +{ + void size (); +}; + +Descriptor g_descriptor = {}; + +template<> void foo<g_descriptor>::size() +{ +} 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" } +} |