]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
pt.c (convert_nontype_argument): Only integral arguments get early folding.
authorJason Merrill <jason@redhat.com>
Wed, 9 Nov 2011 17:53:12 +0000 (12:53 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 9 Nov 2011 17:53:12 +0000 (12:53 -0500)
* pt.c (convert_nontype_argument): Only integral arguments
get early folding.

From-SVN: r181219

gcc/cp/ChangeLog
gcc/cp/pt.c

index c97553092de116419e74cff111108f489e83f34a..095f671f51e9e84fbcb7ab023200dd87d7a7b617 100644 (file)
@@ -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.
 
index e53e90ffbedeb98f1732394c9cbe7fa743fc12a1..a804fda494ac23bac8441c1cfd5ddea89c1a98f4 100644 (file)
@@ -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,