OSDN Git Service

/cp
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index f5a3175..820b1ff 100644 (file)
@@ -5720,11 +5720,15 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
      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))
+      if (TREE_CODE (expr) == PTRMEM_CST)
+       /* A PTRMEM_CST is already constant, and a valid template
+          argument for a parameter of pointer to member type, we just want
+          to leave it in that form rather than lower it to a
+          CONSTRUCTOR.  */;
+      else 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))
+              || TYPE_PTR_TO_MEMBER_P (type))
        {
          tree folded = maybe_constant_value (expr);
          if (TYPE_PTR_P (type) ? integer_zerop (folded)
@@ -6441,8 +6445,16 @@ convert_template_argument (tree parm,
   if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF
       && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM)
     {
-      permerror (input_location, "to refer to a type member of a template parameter, "
-                "use %<typename %E%>", orig_arg);
+      if (TREE_CODE (TREE_OPERAND (arg, 1)) == BIT_NOT_EXPR)
+       {
+         if (complain & tf_error)
+           error ("invalid use of destructor %qE as a type", orig_arg);
+         return error_mark_node;
+       }
+
+      permerror (input_location,
+                "to refer to a type member of a template parameter, "
+                "use %<typename %E%>", orig_arg);
 
       orig_arg = make_typename_type (TREE_OPERAND (arg, 0),
                                     TREE_OPERAND (arg, 1),
@@ -13246,15 +13258,24 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
 
         if (TRANSACTION_EXPR_IS_STMT (t))
           {
+           tree body = TRANSACTION_EXPR_BODY (t);
+           tree noex = NULL_TREE;
+           if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
+             {
+               noex = MUST_NOT_THROW_COND (body);
+               if (noex == NULL_TREE)
+                 noex = boolean_true_node;
+               body = TREE_OPERAND (body, 0);
+             }
             stmt = begin_transaction_stmt (input_location, NULL, flags);
-            RECUR (TRANSACTION_EXPR_BODY (t));
-            finish_transaction_stmt (stmt, NULL, flags);
+            RECUR (body);
+            finish_transaction_stmt (stmt, NULL, flags, RECUR (noex));
           }
         else
           {
             stmt = build_transaction_expr (EXPR_LOCATION (t),
                                           RECUR (TRANSACTION_EXPR_BODY (t)),
-                                          flags);
+                                          flags, NULL_TREE);
             return stmt;
           }
       }
@@ -16601,6 +16622,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
     case BOOLEAN_TYPE:
     case ENUMERAL_TYPE:
     case VOID_TYPE:
+    case NULLPTR_TYPE:
       if (TREE_CODE (arg) != TREE_CODE (parm))
        return unify_type_mismatch (explain_p, parm, arg);