I'm improving the C++11 coverage of the testsuite, which resulted in several failures on non-type argument tests in the current testsuite. Fixed by folding constant expressions in fewer cases.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit b1ec006abd6e4dbf45fca99160b09dab0827a10c
Author: Jason Merrill <ja...@redhat.com>
Date:   Tue Nov 8 20:36:49 2011 -0500

    	* pt.c (convert_nontype_argument): Only integral arguments
    	get early folding.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8c91a9e..38c26a7 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,

Reply via email to