Patchwork C++ PATCH for various template non-type argument tests in C++11 mode

login
register
mail settings
Submitter Jason Merrill
Date Nov. 9, 2011, 5:41 p.m.
Message ID <4EBABB4C.5000902@redhat.com>
Download mbox | patch
Permalink /patch/124637/
State New
Headers show

Comments

Jason Merrill - Nov. 9, 2011, 5:41 p.m.
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.

Patch

commit b1ec006abd6e4dbf45fca99160b09dab0827a10c
Author: Jason Merrill <jason@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,