aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-11-09 12:53:12 -0500
committerJason Merrill <jason@gcc.gnu.org>2011-11-09 12:53:12 -0500
commitecf658592bd49b71fd6579f3da8122df9e27504f (patch)
tree568b2c3490f6b046a964b6ced5a820cdcb4888f0
parent78d16361e1d3052e65d18229d6919d15d7bd21ff (diff)
downloadgcc-ecf658592bd49b71fd6579f3da8122df9e27504f.zip
gcc-ecf658592bd49b71fd6579f3da8122df9e27504f.tar.gz
gcc-ecf658592bd49b71fd6579f3da8122df9e27504f.tar.bz2
pt.c (convert_nontype_argument): Only integral arguments get early folding.
* pt.c (convert_nontype_argument): Only integral arguments get early folding. From-SVN: r181219
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/pt.c22
2 files changed, 21 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c975530..095f671 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2011-11-09 Jason Merrill <jason@redhat.com>
+ * pt.c (convert_nontype_argument): Only integral arguments
+ get early folding.
+
* parser.c (cp_parser_alias_declaration): Don't do semantic
processing if parsing failed.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e53e90f..a804fda 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5681,10 +5681,24 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
&& (TYPE_PTR_P (type) || TYPE_PTR_TO_MEMBER_P (type)))
expr = convert (type, expr);
- /* In C++11, non-type template arguments can be arbitrary constant
- expressions. But don't fold a PTRMEM_CST to a CONSTRUCTOR yet. */
- if (cxx_dialect >= cxx0x && TREE_CODE (expr) != PTRMEM_CST)
- expr = maybe_constant_value (expr);
+ /* In C++11, integral or enumeration non-type template arguments can be
+ arbitrary constant expressions. Pointer and pointer to
+ member arguments can be general constant expressions that evaluate
+ to a null value, but otherwise still need to be of a specific form. */
+ if (cxx_dialect >= cxx0x)
+ {
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ expr = maybe_constant_value (expr);
+ else if (TYPE_PTR_P (type)
+ || (TYPE_PTR_TO_MEMBER_P (type)
+ && TREE_CODE (expr) != PTRMEM_CST))
+ {
+ tree folded = maybe_constant_value (expr);
+ if (TYPE_PTR_P (type) ? integer_zerop (folded)
+ : null_member_pointer_value_p (folded))
+ expr = folded;
+ }
+ }
/* HACK: Due to double coercion, we can get a
NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here,