OSDN Git Service

/cp
[pf3gnuchains/gcc-fork.git] / gcc / cp / pt.c
index f0ee0c5..820b1ff 100644 (file)
@@ -2976,6 +2976,20 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
     (struct find_parameter_pack_data*)data;
   bool parameter_pack_p = false;
 
+  /* Handle type aliases/typedefs.  */
+  if (TYPE_P (t)
+      && TYPE_NAME (t)
+      && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
+      && TYPE_DECL_ALIAS_P (TYPE_NAME (t)))
+    {
+      if (TYPE_TEMPLATE_INFO (t))
+       cp_walk_tree (&TYPE_TI_ARGS (t),
+                     &find_parameter_packs_r,
+                     ppd, ppd->visited);
+      *walk_subtrees = 0;
+      return NULL_TREE;
+    }
+
   /* Identify whether this is a parameter pack or not.  */
   switch (TREE_CODE (t))
     {
@@ -4905,7 +4919,10 @@ push_template_decl_real (tree decl, bool is_friend)
       if (check_for_bare_parameter_packs (TYPE_RAISES_EXCEPTIONS (type)))
        TYPE_RAISES_EXCEPTIONS (type) = NULL_TREE;
     }
-  else if (check_for_bare_parameter_packs (TREE_TYPE (decl)))
+  else if (check_for_bare_parameter_packs ((TREE_CODE (decl) == TYPE_DECL
+                                           && TYPE_DECL_ALIAS_P (decl))
+                                          ? DECL_ORIGINAL_TYPE (decl)
+                                          : TREE_TYPE (decl)))
     {
       TREE_TYPE (decl) = error_mark_node;
       return error_mark_node;
@@ -5501,9 +5518,16 @@ static int
 unify_inconsistency (bool explain_p, tree parm, tree first, tree second)
 {
   if (explain_p)
-    inform (input_location,
-           "  conflicting deductions for parameter %qE (%qE and %qE)",
-           parm, first, second);
+    {
+      if (TYPE_P (parm))
+       inform (input_location,
+               "  deduced conflicting types for parameter %qT (%qT and %qT)",
+               parm, first, second);
+      else
+       inform (input_location,
+               "  deduced conflicting values for non-type parameter "
+               "%qE (%qE and %qE)", parm, first, second);
+    }
   return 1;
 }
 
@@ -5696,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)
@@ -6417,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),
@@ -9103,14 +9139,20 @@ instantiate_class_template_1 (tree type)
 
   if (CLASSTYPE_LAMBDA_EXPR (type))
     {
-      tree lambda = CLASSTYPE_LAMBDA_EXPR (type);
-      if (LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda))
+      tree decl = lambda_function (type);
+      if (decl)
        {
-         apply_lambda_return_type (lambda, void_type_node);
-         LAMBDA_EXPR_RETURN_TYPE (lambda) = NULL_TREE;
+         tree lambda = CLASSTYPE_LAMBDA_EXPR (type);
+         if (LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda))
+           {
+             apply_lambda_return_type (lambda, void_type_node);
+             LAMBDA_EXPR_RETURN_TYPE (lambda) = NULL_TREE;
+           }
+         instantiate_decl (decl, false, false);
+         maybe_add_lambda_conv_op (type);
        }
-      instantiate_decl (lambda_function (type), false, false);
-      maybe_add_lambda_conv_op (type);
+      else
+       gcc_assert (errorcount);
     }
 
   /* Set the file and line number information to whatever is given for
@@ -9350,7 +9392,9 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
            len = my_len;
           else if (len != my_len)
             {
-              if (TREE_CODE (t) == TYPE_PACK_EXPANSION)
+             if (!(complain & tf_error))
+               /* Fail quietly.  */;
+              else if (TREE_CODE (t) == TYPE_PACK_EXPANSION)
                 error ("mismatched argument pack lengths while expanding "
                        "%<%T%>",
                        pattern);
@@ -10607,7 +10651,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
              type = DECL_ORIGINAL_TYPE (t);
            else
              type = TREE_TYPE (t);
-           if (TREE_CODE (t) == VAR_DECL && VAR_HAD_UNKNOWN_BOUND (t))
+           if (TREE_CODE (t) == VAR_DECL
+               && VAR_HAD_UNKNOWN_BOUND (t)
+               && type != error_mark_node)
              type = strip_array_domain (type);
            type = tsubst (type, args, complain, in_decl);
          }
@@ -12793,6 +12839,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
                    && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
                  /* Anonymous aggregates are a special case.  */
                  finish_anon_union (decl);
+               else if (is_capture_proxy (DECL_EXPR_DECL (t)))
+                 {
+                   DECL_CONTEXT (decl) = current_function_decl;
+                   insert_capture_proxy (decl);
+                 }
                else
                  {
                    int const_init = false;
@@ -13207,20 +13258,33 @@ 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;
           }
       }
       break;
 
+    case MUST_NOT_THROW_EXPR:
+      return build_must_not_throw_expr (RECUR (TREE_OPERAND (t, 0)),
+                                       RECUR (MUST_NOT_THROW_COND (t)));
+
     case EXPR_PACK_EXPANSION:
       error ("invalid use of pack expansion expression");
       return error_mark_node;
@@ -14288,6 +14352,10 @@ tsubst_copy_and_build (tree t,
        return r;
       }
 
+    case TRANSACTION_EXPR:
+      return tsubst_expr(t, args, complain, in_decl,
+            integral_constant_expression_p);
+
     default:
       /* Handle Objective-C++ constructs, if appropriate.  */
       {
@@ -16554,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);