diff options
author | Jason Merrill <jason@redhat.com> | 2011-07-29 03:10:21 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-07-29 03:10:21 -0400 |
commit | 17b3c7a2dbccfb4dcb7d78e0c974a0ad212262a9 (patch) | |
tree | 0c7f40afebdcb16dd3bc1da94958d723f3244a58 | |
parent | 7d7d50baf7dbd0d5cb6c16951007726b8cc7f66d (diff) | |
download | gcc-17b3c7a2dbccfb4dcb7d78e0c974a0ad212262a9.zip gcc-17b3c7a2dbccfb4dcb7d78e0c974a0ad212262a9.tar.gz gcc-17b3c7a2dbccfb4dcb7d78e0c974a0ad212262a9.tar.bz2 |
re PR c++/49808 (GCC adds an address-of somewhere!)
PR c++/49808
* pt.c (tsubst) [TEMPLATE_PARM_INDEX]: Call convert_from_reference.
(convert_nontype_argument, tsubst_template_arg): Handle its output.
From-SVN: r176916
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 50 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/nontype24.C | 16 |
4 files changed, 56 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ccaba95..d6330bb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2011-07-28 Jason Merrill <jason@redhat.com> + + PR c++/49808 + * pt.c (tsubst) [TEMPLATE_PARM_INDEX]: Call convert_from_reference. + (convert_nontype_argument, tsubst_template_arg): Handle its output. + 2011-07-28 Paolo Carlini <paolo.carlini@oracle.com> PR c++/49813 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b9e09af..a3cd956 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5556,41 +5556,45 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) function). We just strip everything and get to the arg. See g++.old-deja/g++.oliva/template4.C and g++.dg/template/nontype9.C for examples. */ - if (TREE_CODE (expr) == NOP_EXPR) + if (TYPE_REF_OBJ_P (type) || TYPE_REFFN_P (type)) { - if (TYPE_REF_OBJ_P (type) || TYPE_REFFN_P (type)) + tree probe_type, probe = expr; + if (REFERENCE_REF_P (probe)) + probe = TREE_OPERAND (probe, 0); + probe_type = TREE_TYPE (probe); + if (TREE_CODE (probe) == NOP_EXPR) { /* ??? Maybe we could use convert_from_reference here, but we would need to relax its constraints because the NOP_EXPR could actually change the type to something more cv-qualified, and this is not folded by convert_from_reference. */ - tree addr = TREE_OPERAND (expr, 0); - gcc_assert (TREE_CODE (expr_type) == REFERENCE_TYPE); + tree addr = TREE_OPERAND (probe, 0); + gcc_assert (TREE_CODE (probe_type) == REFERENCE_TYPE); gcc_assert (TREE_CODE (addr) == ADDR_EXPR); gcc_assert (TREE_CODE (TREE_TYPE (addr)) == POINTER_TYPE); gcc_assert (same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (expr_type), + (TREE_TYPE (probe_type), TREE_TYPE (TREE_TYPE (addr)))); expr = TREE_OPERAND (addr, 0); expr_type = TREE_TYPE (expr); } + } - /* We could also generate a NOP_EXPR(ADDR_EXPR()) when the - parameter is a pointer to object, through decay and - qualification conversion. Let's strip everything. */ - else if (TYPE_PTROBV_P (type)) - { - STRIP_NOPS (expr); - gcc_assert (TREE_CODE (expr) == ADDR_EXPR); - gcc_assert (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE); - /* Skip the ADDR_EXPR only if it is part of the decay for - an array. Otherwise, it is part of the original argument - in the source code. */ - if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == ARRAY_TYPE) - expr = TREE_OPERAND (expr, 0); - expr_type = TREE_TYPE (expr); - } + /* We could also generate a NOP_EXPR(ADDR_EXPR()) when the + parameter is a pointer to object, through decay and + qualification conversion. Let's strip everything. */ + else if (TREE_CODE (expr) == NOP_EXPR && TYPE_PTROBV_P (type)) + { + STRIP_NOPS (expr); + gcc_assert (TREE_CODE (expr) == ADDR_EXPR); + gcc_assert (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE); + /* Skip the ADDR_EXPR only if it is part of the decay for + an array. Otherwise, it is part of the original argument + in the source code. */ + if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == ARRAY_TYPE) + expr = TREE_OPERAND (expr, 0); + expr_type = TREE_TYPE (expr); } /* [temp.arg.nontype]/5, bullet 1 @@ -8941,6 +8945,10 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) /*integral_constant_expression_p=*/true); if (!(complain & tf_warning)) --c_inhibit_evaluation_warnings; + /* Preserve the raw-reference nature of T. */ + if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE + && REFERENCE_REF_P (r)) + r = TREE_OPERAND (r, 0); } return r; } @@ -10981,7 +10989,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) } else /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX. */ - return unshare_expr (arg); + return convert_from_reference (unshare_expr (arg)); } if (level == 1) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aebaf01..c825d3b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-07-28 Jason Merrill <jason@redhat.com> + + PR c++/49808 + * g++.dg/template/nontype24.C: New. + 2011-07-28 H.J. Lu <hongjiu.lu@intel.com> PR rtl-optimization/47958 diff --git a/gcc/testsuite/g++.dg/template/nontype24.C b/gcc/testsuite/g++.dg/template/nontype24.C new file mode 100644 index 0000000..57fbe43 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype24.C @@ -0,0 +1,16 @@ +// PR c++/49808 + +template <class X, X g> +struct A +{ + A() { float r = g(0); } +}; + +struct f_t +{ + float operator() (float) const { return 1; } +}; + +f_t f; + +A<f_t&, f> x; |