OSDN Git Service

* pt.c (convert_nontype_argument): Only integral arguments
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Nov 2011 17:53:12 +0000 (17:53 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Nov 2011 17:53:12 +0000 (17:53 +0000)
get early folding.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181219 138bc75d-0d04-0410-961f-82ee72b054a4

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

index c975530..095f671 100644 (file)
@@ -1,5 +1,8 @@
 2011-11-09  Jason Merrill  <jason@redhat.com>
 
 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.
 
        * parser.c (cp_parser_alias_declaration): Don't do semantic
        processing if parsing failed.
 
index e53e90f..a804fda 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);
 
       && (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,
 
   /* HACK: Due to double coercion, we can get a
      NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here,