]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
/cp
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Jun 2012 23:01:45 +0000 (23:01 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Jun 2012 23:01:45 +0000 (23:01 +0000)
2012-06-06  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/53567
* typeck.c (cp_perform_integral_promotions): New, like
perform_integral_promotions but also takes a tsubst_flags_t parameter.
(pointer_diff): Add tsubst_flags_t parameter.
(decay_conversion, cp_default_conversion, cp_build_array_ref,
cp_build_binary_op, cp_build_unary_op, build_static_cast_1,
build_reinterpret_cast_1, cp_build_modify_expr,
convert_for_assignment): Adjust.
* optimize.c (build_delete_destructor_body): Adjust.
* init.c (expand_virtual_init, expand_default_init, build_new_1,
build_new, build_vec_delete_1, build_vec_init, build_delete): Adjust.
(construct_virtual_base): Adjust LOOKUP_COMPLAIN -> 0.
* class.c (build_base_path): Adjust.
* decl.c (compute_array_index_type, finish_destructor_body): Likewise.
* method.c (synthesized_method_walk): Adjust flag and complain.
* rtti.c (ifnonnull): Add tsubst_flags_t parameter.
(build_typeid, build_dynamic_cast_1): Adjust.
* except.c (initialize_handler_parm): Likewise.
* typeck2.c (process_init_constructor_record): Likewise.
* pt.c (tsubst_friend_class): Don't change flags.
* semantics.c (finish_goto_stmt, handle_omp_for_class_iterator,
finish_static_assert): Likewise.
* parser.c (cp_parser_lookup_name): Just pass 0 as flags to
lookup_name_real.
* call.c (build_op_delete_call): Add tsubst_flags_t parameter.
(convert_like_real, convert_arg_to_ellipsis, convert_for_arg_passing):
Adjust.
(standard_conversion): Adjust LOOKUP_COMPLAIN -> 0.
(implicit_conversion): Mask out tf_error with a FIXME.
(build_user_type_conversion_1, build_new_op_1, build_over_call): Use
complain & tf_error instead of flags & LOOKUP_COMPLAIN.
* cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
build_up_reference, convert_to_reference, cp_convert,
cp_convert_and_check, ocp_convert, convert_force): Add tsubst_flags_t
parameter.
(convert_to_reference, ocp_convert): Use complain & tf_error instead
of flags & LOOKUP_COMPLAIN.
(convert_force): Adjust LOOKUP_COMPLAIN -> 0.
* name-lookup.c (identifier_type_value_1, lookup_qualified_name,
lookup_name_real, lookup_function_nonclass, lookup_name,
lookup_name_prefer_type): Adjust LOOKUP_COMPLAIN -> 0.
* cp-tree.h: Adjust prototypes; remove LOOKUP_COMPLAIN.

/testsuite
2012-06-06  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/53567
* g++.dg/cpp0x/alias-decl-19.C: New.

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

19 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/name-lookup.c
gcc/cp/optimize.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C [new file with mode: 0644]

index 49e1dfedf250769b24d34e687dbcda9362549e5b..e8a11f31321843fbc91b9daf193298de65e1f580 100644 (file)
@@ -1,3 +1,48 @@
+2012-06-06  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/53567
+       * typeck.c (cp_perform_integral_promotions): New, like
+       perform_integral_promotions but also takes a tsubst_flags_t parameter.
+       (pointer_diff): Add tsubst_flags_t parameter.
+       (decay_conversion, cp_default_conversion, cp_build_array_ref,
+       cp_build_binary_op, cp_build_unary_op, build_static_cast_1,
+       build_reinterpret_cast_1, cp_build_modify_expr,
+       convert_for_assignment): Adjust.
+       * optimize.c (build_delete_destructor_body): Adjust.
+       * init.c (expand_virtual_init, expand_default_init, build_new_1,
+       build_new, build_vec_delete_1, build_vec_init, build_delete): Adjust.
+       (construct_virtual_base): Adjust LOOKUP_COMPLAIN -> 0.
+       * class.c (build_base_path): Adjust.
+       * decl.c (compute_array_index_type, finish_destructor_body): Likewise.
+       * method.c (synthesized_method_walk): Adjust flag and complain.
+       * rtti.c (ifnonnull): Add tsubst_flags_t parameter.
+       (build_typeid, build_dynamic_cast_1): Adjust.
+       * except.c (initialize_handler_parm): Likewise.
+       * typeck2.c (process_init_constructor_record): Likewise.
+       * pt.c (tsubst_friend_class): Don't change flags.
+       * semantics.c (finish_goto_stmt, handle_omp_for_class_iterator,
+       finish_static_assert): Likewise.
+       * parser.c (cp_parser_lookup_name): Just pass 0 as flags to
+       lookup_name_real.
+       * call.c (build_op_delete_call): Add tsubst_flags_t parameter.
+       (convert_like_real, convert_arg_to_ellipsis, convert_for_arg_passing):
+       Adjust.
+       (standard_conversion): Adjust LOOKUP_COMPLAIN -> 0.
+       (implicit_conversion): Mask out tf_error with a FIXME.
+       (build_user_type_conversion_1, build_new_op_1, build_over_call): Use
+       complain & tf_error instead of flags & LOOKUP_COMPLAIN.
+       * cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
+       build_up_reference, convert_to_reference, cp_convert,
+       cp_convert_and_check, ocp_convert, convert_force): Add tsubst_flags_t
+       parameter.
+       (convert_to_reference, ocp_convert): Use complain & tf_error instead
+       of flags & LOOKUP_COMPLAIN.
+       (convert_force): Adjust LOOKUP_COMPLAIN -> 0.
+       * name-lookup.c (identifier_type_value_1, lookup_qualified_name,
+       lookup_name_real, lookup_function_nonclass, lookup_name,
+       lookup_name_prefer_type): Adjust LOOKUP_COMPLAIN -> 0.
+       * cp-tree.h: Adjust prototypes; remove LOOKUP_COMPLAIN.
+
 2012-06-06  Steven Bosscher  <steven@gcc.gnu.org>
 
        * decl.c: Do not include output.h.
index ad31f6a1c8743c0c7daaadef4826cba520b2946d..09965b321cc1e46f0aa2eea9daaffc396b6b763f 100644 (file)
@@ -1695,6 +1695,13 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
            |LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE
            |LOOKUP_NO_NARROWING|LOOKUP_PROTECT);
 
+  /* FIXME: actually we don't want warnings either, but we can't just
+     have 'complain &= ~(tf_warning|tf_error)' because it would cause
+     the regression of, eg, g++.old-deja/g++.benjamin/16077.C.
+     We really ought not to issue that warning until we've committed
+     to that conversion.  */
+  complain &= ~tf_error;
+
   if (TREE_CODE (to) == REFERENCE_TYPE)
     conv = reference_binding (to, from, expr, c_cast_p, flags, complain);
   else
@@ -3607,8 +3614,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
   cand = tourney (candidates, complain);
   if (cand == 0)
     {
-      if ((flags & LOOKUP_COMPLAIN)
-         && (complain & tf_error))
+      if (complain & tf_error)
        {
          error ("conversion from %qT to %qT is ambiguous",
                 fromtype, totype);
@@ -5098,7 +5104,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
             distinguish between prefix and postfix ++ and
             operator++() was used for both, so we allow this with
             -fpermissive.  */
-         if (flags & LOOKUP_COMPLAIN)
+         else
            {
              const char *msg = (flag_permissive) 
                ? G_("no %<%D(int)%> declared for postfix %qs,"
@@ -5127,7 +5133,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
          break;
 
        default:
-         if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
+         if (complain & tf_error)
            {
                /* If one of the arguments of the operator represents
                   an invalid use of member function pointer, try to report
@@ -5153,7 +5159,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
       cand = tourney (candidates, complain);
       if (cand == 0)
        {
-         if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
+         if (complain & tf_error)
            {
              op_error (loc, code, code2, arg1, arg2, arg3, TRUE);
              print_z_candidates (loc, candidates);
@@ -5379,7 +5385,7 @@ non_placement_deallocation_fn_p (tree t)
 tree
 build_op_delete_call (enum tree_code code, tree addr, tree size,
                      bool global_p, tree placement,
-                     tree alloc_fn)
+                     tree alloc_fn, tsubst_flags_t complain)
 {
   tree fn = NULL_TREE;
   tree fns, fnname, type, t;
@@ -5413,7 +5419,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
     fns = lookup_name_nonclass (fnname);
 
   /* Strip const and volatile from addr.  */
-  addr = cp_convert (ptr_type_node, addr);
+  addr = cp_convert (ptr_type_node, addr, complain);
 
   if (placement)
     {
@@ -5452,8 +5458,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
                  && FUNCTION_ARG_CHAIN (elt) == void_list_node)
                goto ok;
            }
-         permerror (0, "non-placement deallocation function %q+D", fn);
-         permerror (input_location, "selected for placement delete");
+         if (complain & tf_error)
+           {
+             permerror (0, "non-placement deallocation function %q+D", fn);
+             permerror (input_location, "selected for placement delete");
+           }
+         else
+           return error_mark_node;
        ok:;
        }
     }
@@ -5518,7 +5529,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
          VEC_quick_push (tree, args, addr);
          if (FUNCTION_ARG_CHAIN (fn) != void_list_node)
            VEC_quick_push (tree, args, size);
-         ret = cp_build_function_call_vec (fn, &args, tf_warning_or_error);
+         ret = cp_build_function_call_vec (fn, &args, complain);
          VEC_free (tree, gc, args);
          return ret;
        }
@@ -5531,14 +5542,16 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
      be freed.  */
   if (alloc_fn)
     {
-      if (!placement)
+      if ((complain & tf_warning)
+         && !placement)
        warning (0, "no corresponding deallocation function for %qD",
                 alloc_fn);
       return NULL_TREE;
     }
 
-  error ("no suitable %<operator %s%> for %qT",
-        operator_name_info[(int)code].name, type);
+  if (complain & tf_error)
+    error ("no suitable %<operator %s%> for %qT",
+          operator_name_info[(int)code].name, type);
   return error_mark_node;
 }
 
@@ -5685,9 +5698,10 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
                                        complain);
              if (convs->kind == ck_ref_bind)
                return convert_to_reference (totype, expr, CONV_IMPLICIT,
-                                            LOOKUP_NORMAL, NULL_TREE);
+                                            LOOKUP_NORMAL, NULL_TREE,
+                                            complain);
              else
-               return cp_convert (totype, expr);
+               return cp_convert (totype, expr, complain);
            }
          else if (t->kind == ck_user || !t->bad_p)
            {
@@ -5712,7 +5726,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        permerror (DECL_SOURCE_LOCATION (fn),
                   "  initializing argument %P of %qD", argnum, fn);
 
-      return cp_convert (totype, expr);
+      return cp_convert (totype, expr, complain);
     }
 
   if (issue_conversion_warnings && (complain & tf_warning))
@@ -5851,7 +5865,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        /* Take the address explicitly rather than via decay_conversion
           to avoid the error about taking the address of a temporary.  */
        array = cp_build_addr_expr (array, complain);
-       array = cp_convert (build_pointer_type (elttype), array);
+       array = cp_convert (build_pointer_type (elttype), array, complain);
 
        /* Build up the initializer_list object.  */
        totype = complete_type (totype);
@@ -6017,7 +6031,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
           reference.  This will adjust the pointer if a derived to
           base conversion is being performed.  */
        expr = cp_convert (build_pointer_type (TREE_TYPE (ref_type)),
-                          expr);
+                          expr, complain);
        /* Convert the pointer to the desired reference type.  */
        return build_nop (ref_type, expr);
       }
@@ -6099,9 +6113,9 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
          if (complain & tf_warning)
            warning_at (loc, OPT_Wabi, "scoped enum %qT will not promote to an "
                        "integral type in a future version of GCC", arg_type);
-         arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg);
+         arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg, complain);
        }
-      arg = perform_integral_promotions (arg);
+      arg = cp_perform_integral_promotions (arg, complain);
     }
 
   arg = require_complete_type (arg);
@@ -6336,7 +6350,7 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
           && COMPLETE_TYPE_P (type)
           && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
                                   TYPE_SIZE (integer_type_node)))
-    val = perform_integral_promotions (val);
+    val = cp_perform_integral_promotions (val, complain);
   if ((complain & tf_warning)
       && warn_suggest_attribute_format)
     {
@@ -6487,7 +6501,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       if (flags & LOOKUP_SPECULATIVE)
        {
          if (!speculative_access_check (cand->access_path, access_fn, fn,
-                                        !!(flags & LOOKUP_COMPLAIN)))
+                                        complain & tf_error))
            return error_mark_node;
        }
       else
@@ -6500,13 +6514,13 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
     {
       if (DECL_DELETED_FN (fn))
        {
-         if (flags & LOOKUP_COMPLAIN)
+         if (complain & tf_error)
            mark_used (fn);
          return error_mark_node;
        }
       if (cand->viable == 1)
        return fn;
-      else if (!(flags & LOOKUP_COMPLAIN))
+      else if (!(complain & tf_error))
        /* Reject bad conversions now.  */
        return error_mark_node;
       /* else continue to get conversion error.  */
index c30054d57097d1b24f906a54f2eea4b0254ebf43..e85aac96c39ed60a015f4667050777eb0bc664d9 100644 (file)
@@ -366,7 +366,7 @@ build_base_path (enum tree_code code,
   /* Now that we've saved expr, build the real null test.  */
   if (null_test)
     {
-      tree zero = cp_convert (TREE_TYPE (expr), nullptr_node);
+      tree zero = cp_convert (TREE_TYPE (expr), nullptr_node, complain);
       null_test = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
                               expr, zero);
     }
index 7c901be7960285c84547724e27085144ac0abc3a..22012e25d952ec19be4478bb37c4247451c7fd31 100644 (file)
@@ -4371,16 +4371,13 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
    behaviors relevant to them.  */
 /* Check for access violations.  */
 #define LOOKUP_PROTECT (1 << 0)
-/* Complain if no suitable member function matching the arguments is
-   found.  */
-#define LOOKUP_COMPLAIN (1 << 1)
-#define LOOKUP_NORMAL (LOOKUP_PROTECT | LOOKUP_COMPLAIN)
+#define LOOKUP_NORMAL (LOOKUP_PROTECT)
 /* Even if the function found by lookup is a virtual function, it
    should be called directly.  */
-#define LOOKUP_NONVIRTUAL (1 << 2)
+#define LOOKUP_NONVIRTUAL (1 << 1)
 /* Non-converting (i.e., "explicit") constructors are not tried.  This flag
    indicates that we are not performing direct-initialization.  */
-#define LOOKUP_ONLYCONVERTING (1 << 3)
+#define LOOKUP_ONLYCONVERTING (1 << 2)
 #define LOOKUP_IMPLICIT (LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING)
 /* If a temporary is created, it should be created so that it lives
    as long as the current variable bindings; otherwise it only lives
@@ -4388,20 +4385,20 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
    direct-initialization in cases where other parts of the compiler
    have already generated a temporary, such as reference
    initialization and the catch parameter.  */
-#define DIRECT_BIND (1 << 4)
+#define DIRECT_BIND (1 << 3)
 /* We're performing a user-defined conversion, so more user-defined
    conversions are not permitted (only built-in conversions).  */
-#define LOOKUP_NO_CONVERSION (1 << 5)
+#define LOOKUP_NO_CONVERSION (1 << 4)
 /* The user has explicitly called a destructor.  (Therefore, we do
    not need to check that the object is non-NULL before calling the
    destructor.)  */
-#define LOOKUP_DESTRUCTOR (1 << 6)
+#define LOOKUP_DESTRUCTOR (1 << 5)
 /* Do not permit references to bind to temporaries.  */
-#define LOOKUP_NO_TEMP_BIND (1 << 7)
+#define LOOKUP_NO_TEMP_BIND (1 << 6)
 /* Do not accept objects, and possibly namespaces.  */
-#define LOOKUP_PREFER_TYPES (1 << 8)
+#define LOOKUP_PREFER_TYPES (1 << 7)
 /* Do not accept objects, and possibly types.   */
-#define LOOKUP_PREFER_NAMESPACES (1 << 9)
+#define LOOKUP_PREFER_NAMESPACES (1 << 8)
 /* Accept types or namespaces.  */
 #define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
 /* Return friend declarations and un-declared builtin functions.
@@ -4894,7 +4891,9 @@ extern tree build_new_op                  (location_t, enum tree_code,
                                                 tsubst_flags_t);
 extern tree build_op_call                      (tree, VEC(tree,gc) **,
                                                 tsubst_flags_t);
-extern tree build_op_delete_call               (enum tree_code, tree, tree, bool, tree, tree);
+extern tree build_op_delete_call               (enum tree_code, tree, tree,
+                                                bool, tree, tree,
+                                                tsubst_flags_t);
 extern bool can_convert                                (tree, tree, tsubst_flags_t);
 extern bool can_convert_arg                    (tree, tree, tree, int,
                                                 tsubst_flags_t);
@@ -5001,16 +5000,19 @@ extern void adjust_clone_args                   (tree);
 extern void deduce_noexcept_on_destructor       (tree);
 
 /* in cvt.c */
-extern tree convert_to_reference               (tree, tree, int, int, tree);
+extern tree convert_to_reference               (tree, tree, int, int, tree,
+                                                tsubst_flags_t);
 extern tree convert_from_reference             (tree);
 extern tree force_rvalue                       (tree, tsubst_flags_t);
-extern tree ocp_convert                                (tree, tree, int, int);
-extern tree cp_convert                         (tree, tree);
-extern tree cp_convert_and_check                (tree, tree);
+extern tree ocp_convert                                (tree, tree, int, int,
+                                                tsubst_flags_t);
+extern tree cp_convert                         (tree, tree, tsubst_flags_t);
+extern tree cp_convert_and_check                (tree, tree, tsubst_flags_t);
 extern tree cp_fold_convert                    (tree, tree);
 extern tree convert_to_void                    (tree, impl_conv_void,
                                                 tsubst_flags_t);
-extern tree convert_force                      (tree, tree, int);
+extern tree convert_force                      (tree, tree, int,
+                                                tsubst_flags_t);
 extern tree build_expr_type_conversion         (int, tree, bool);
 extern tree type_promotes_to                   (tree);
 extern tree perform_qualification_conversions  (tree, tree);
@@ -5901,6 +5903,7 @@ extern void check_template_keyword                (tree);
 extern bool check_raw_literal_operator         (const_tree decl);
 extern bool check_literal_operator_args                (const_tree, bool *, bool *);
 extern void maybe_warn_about_useless_cast       (tree, tree, tsubst_flags_t);
+extern tree cp_perform_integral_promotions      (tree, tsubst_flags_t);
 
 /* in typeck2.c */
 extern void require_complete_eh_spec_types     (tree, tree);
index ebd750529c6feac55427a1a1f938f685a68e6635..998d4eb345e719ee414157e8504843bbd3255cd6 100644 (file)
@@ -38,10 +38,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "decl.h"
 #include "target.h"
 
-static tree cp_convert_to_pointer (tree, tree);
-static tree convert_to_pointer_force (tree, tree);
+static tree cp_convert_to_pointer (tree, tree, tsubst_flags_t);
+static tree convert_to_pointer_force (tree, tree, tsubst_flags_t);
 static tree build_type_conversion (tree, tree);
-static tree build_up_reference (tree, tree, int, tree);
+static tree build_up_reference (tree, tree, int, tree, tsubst_flags_t);
 static void warn_ref_binding (location_t, tree, tree, tree);
 
 /* Change of width--truncation and extension of integers or reals--
@@ -74,7 +74,7 @@ static void warn_ref_binding (location_t, tree, tree, tree);
    else try C-style pointer conversion.  */
 
 static tree
-cp_convert_to_pointer (tree type, tree expr)
+cp_convert_to_pointer (tree type, tree expr, tsubst_flags_t complain)
 {
   tree intype = TREE_TYPE (expr);
   enum tree_code form;
@@ -89,15 +89,17 @@ cp_convert_to_pointer (tree type, tree expr)
       intype = complete_type (intype);
       if (!COMPLETE_TYPE_P (intype))
        {
-         error_at (loc, "can%'t convert from incomplete type %qT to %qT",
-                   intype, type);
+         if (complain & tf_error)
+           error_at (loc, "can%'t convert from incomplete type %qT to %qT",
+                     intype, type);
          return error_mark_node;
        }
 
       rval = build_type_conversion (type, expr);
       if (rval)
        {
-         if (rval == error_mark_node)
+         if ((complain & tf_error)
+             && rval == error_mark_node)
            error_at (loc, "conversion of %qE from %qT to %qT is ambiguous",
                      expr, intype, type);
          return rval;
@@ -111,7 +113,7 @@ cp_convert_to_pointer (tree type, tree expr)
     {
       if (TYPE_PTRMEMFUNC_P (intype)
          || TREE_CODE (intype) == METHOD_TYPE)
-       return convert_member_func_to_ptr (type, expr, tf_warning_or_error);
+       return convert_member_func_to_ptr (type, expr, complain);
       if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
        return build_nop (type, expr);
       intype = TREE_TYPE (expr);
@@ -159,8 +161,7 @@ cp_convert_to_pointer (tree type, tree expr)
          if (binfo || same_p)
            {
              if (binfo)
-               expr = build_base_path (code, expr, binfo, 0,
-                                       tf_warning_or_error);
+               expr = build_base_path (code, expr, binfo, 0, complain);
              /* Add any qualifier conversions.  */
              return build_nop (type, expr);
            }
@@ -168,8 +169,9 @@ cp_convert_to_pointer (tree type, tree expr)
 
       if (TYPE_PTRMEMFUNC_P (type))
        {
-         error_at (loc, "cannot convert %qE from type %qT to type %qT",
-                   expr, intype, type);
+         if (complain & tf_error)
+           error_at (loc, "cannot convert %qE from type %qT to type %qT",
+                     expr, intype, type);
          return error_mark_node;
        }
 
@@ -178,20 +180,20 @@ cp_convert_to_pointer (tree type, tree expr)
   else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
           || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
     return convert_ptrmem (type, expr, /*allow_inverse_p=*/false,
-                          /*c_cast_p=*/false, tf_warning_or_error);
+                          /*c_cast_p=*/false, complain);
   else if (TYPE_PTRMEMFUNC_P (intype))
     {
       if (!warn_pmf2ptr)
        {
          if (TREE_CODE (expr) == PTRMEM_CST)
-           return cp_convert_to_pointer (type,
-                                         PTRMEM_CST_MEMBER (expr));
+           return cp_convert_to_pointer (type, PTRMEM_CST_MEMBER (expr),
+                                         complain);
          else if (TREE_CODE (expr) == OFFSET_REF)
            {
              tree object = TREE_OPERAND (expr, 0);
              return get_member_function_from_ptrfunc (&object,
                                                       TREE_OPERAND (expr, 1),
-                                                      tf_warning_or_error);
+                                                      complain);
            }
        }
       error_at (loc, "cannot convert %qE from type %qT to type %qT",
@@ -201,14 +203,15 @@ cp_convert_to_pointer (tree type, tree expr)
 
   if (null_ptr_cst_p (expr))
     {
-      if (c_inhibit_evaluation_warnings == 0
+      if ((complain & tf_warning)
+         && c_inhibit_evaluation_warnings == 0
          && !NULLPTR_TYPE_P (TREE_TYPE (expr)))
        warning_at (loc, OPT_Wzero_as_null_pointer_constant,
                    "zero as null pointer constant");
 
       if (TYPE_PTRMEMFUNC_P (type))
        return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
-                                /*c_cast_p=*/false, tf_warning_or_error);
+                                /*c_cast_p=*/false, complain);
 
       if (TYPE_PTRDATAMEM_P (type))
        {
@@ -223,7 +226,8 @@ cp_convert_to_pointer (tree type, tree expr)
     }
   else if (TYPE_PTRMEM_P (type) && INTEGRAL_CODE_P (form))
     {
-      error_at (loc, "invalid conversion from %qT to %qT", intype, type);
+      if (complain & tf_error)
+       error_at (loc, "invalid conversion from %qT to %qT", intype, type);
       return error_mark_node;
     }
 
@@ -231,7 +235,8 @@ cp_convert_to_pointer (tree type, tree expr)
     {
       if (TYPE_PRECISION (intype) == POINTER_SIZE)
        return build1 (CONVERT_EXPR, type, expr);
-      expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr);
+      expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr,
+                        complain);
       /* Modes may be different but sizes should be the same.  There
         is supposed to be some integral type that is the same width
         as a pointer.  */
@@ -242,10 +247,11 @@ cp_convert_to_pointer (tree type, tree expr)
     }
 
   if (type_unknown_p (expr))
-    return instantiate_type (type, expr, tf_warning_or_error);
+    return instantiate_type (type, expr, complain);
 
-  error_at (loc, "cannot convert %qE from type %qT to type %qT",
-           expr, intype, type);
+  if (complain & tf_error)
+    error_at (loc, "cannot convert %qE from type %qT to type %qT",
+             expr, intype, type);
   return error_mark_node;
 }
 
@@ -254,7 +260,7 @@ cp_convert_to_pointer (tree type, tree expr)
    (such as conversion from sub-type to private super-type).  */
 
 static tree
-convert_to_pointer_force (tree type, tree expr)
+convert_to_pointer_force (tree type, tree expr, tsubst_flags_t complain)
 {
   tree intype = TREE_TYPE (expr);
   enum tree_code form = TREE_CODE (intype);
@@ -284,8 +290,7 @@ convert_to_pointer_force (tree type, tree expr)
            return error_mark_node;
          if (binfo)
            {
-             expr = build_base_path (code, expr, binfo, 0,
-                                     tf_warning_or_error);
+             expr = build_base_path (code, expr, binfo, 0, complain);
              if (expr == error_mark_node)
                 return error_mark_node;
              /* Add any qualifier conversions.  */
@@ -297,7 +302,7 @@ convert_to_pointer_force (tree type, tree expr)
        }
     }
 
-  return cp_convert_to_pointer (type, expr);
+  return cp_convert_to_pointer (type, expr, complain);
 }
 
 /* We are passing something to a function which requires a reference.
@@ -309,7 +314,8 @@ convert_to_pointer_force (tree type, tree expr)
      If DIRECT_BIND is set, DECL is the reference we're binding to.  */
 
 static tree
-build_up_reference (tree type, tree arg, int flags, tree decl)
+build_up_reference (tree type, tree arg, int flags, tree decl,
+                   tsubst_flags_t complain)
 {
   tree rval;
   tree argtype = TREE_TYPE (arg);
@@ -351,12 +357,12 @@ build_up_reference (tree type, tree arg, int flags, tree decl)
        return error_mark_node;
       if (binfo == NULL_TREE)
        return error_not_base_type (target_type, argtype);
-      rval = build_base_path (PLUS_EXPR, rval, binfo, 1,
-                             tf_warning_or_error);
+      rval = build_base_path (PLUS_EXPR, rval, binfo, 1, complain);
     }
   else
     rval
-      = convert_to_pointer_force (build_pointer_type (target_type), rval);
+      = convert_to_pointer_force (build_pointer_type (target_type),
+                                 rval, complain);
   return build_nop (type, rval);
 }
 
@@ -403,15 +409,13 @@ warn_ref_binding (location_t loc, tree reftype, tree intype, tree decl)
 
 tree
 convert_to_reference (tree reftype, tree expr, int convtype,
-                     int flags, tree decl)
+                     int flags, tree decl, tsubst_flags_t complain)
 {
   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
   tree intype;
   tree rval = NULL_TREE;
   tree rval_as_conversion = NULL_TREE;
   bool can_convert_intype_to_type;
-  tsubst_flags_t complain = ((flags & LOOKUP_COMPLAIN)
-                            ? tf_warning_or_error : tf_none);
   location_t loc = EXPR_LOC_OR_HERE (expr);
 
   if (TREE_CODE (type) == FUNCTION_TYPE
@@ -452,21 +456,26 @@ convert_to_reference (tree reftype, tree expr, int convtype,
   if (((convtype & CONV_STATIC) && can_convert (intype, type, complain))
       || ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
     {
-      if (flags & LOOKUP_COMPLAIN)
-       {
-         tree ttl = TREE_TYPE (reftype);
-         tree ttr = lvalue_type (expr);
+      {
+       tree ttl = TREE_TYPE (reftype);
+       tree ttr = lvalue_type (expr);
 
-         if (! real_lvalue_p (expr))
-           warn_ref_binding (loc, reftype, intype, decl);
+       if ((complain & tf_warning)
+           && ! real_lvalue_p (expr))
+         warn_ref_binding (loc, reftype, intype, decl);
 
-         if (! (convtype & CONV_CONST)
-                  && !at_least_as_qualified_p (ttl, ttr))
-           permerror (loc, "conversion from %qT to %qT discards qualifiers",
-                      ttr, reftype);
-       }
+       if (! (convtype & CONV_CONST)
+           && !at_least_as_qualified_p (ttl, ttr))
+         {
+           if (complain & tf_error)
+             permerror (loc, "conversion from %qT to %qT discards qualifiers",
+                        ttr, reftype);
+           else
+             return error_mark_node;
+         }
+      }
 
-      return build_up_reference (reftype, expr, flags, decl);
+      return build_up_reference (reftype, expr, flags, decl, complain);
     }
   else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr))
     {
@@ -477,28 +486,29 @@ convert_to_reference (tree reftype, tree expr, int convtype,
 
       /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
         meant.  */
-      if (TREE_CODE (intype) == POINTER_TYPE
+      if ((complain & tf_warning)
+         && TREE_CODE (intype) == POINTER_TYPE
          && (comptypes (TREE_TYPE (intype), type,
                         COMPARE_BASE | COMPARE_DERIVED)))
        warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
                    intype, reftype);
 
-      rval = cp_build_addr_expr (expr, tf_warning_or_error);
+      rval = cp_build_addr_expr (expr, complain);
       if (rval != error_mark_node)
        rval = convert_force (build_pointer_type (TREE_TYPE (reftype)),
-                             rval, 0);
+                             rval, 0, complain);
       if (rval != error_mark_node)
        rval = build1 (NOP_EXPR, reftype, rval);
     }
   else
     {
       rval = convert_for_initialization (NULL_TREE, type, expr, flags,
-                                        ICR_CONVERTING, 0, 0,
-                                         tf_warning_or_error);
+                                        ICR_CONVERTING, 0, 0, complain);
       if (rval == NULL_TREE || rval == error_mark_node)
        return rval;
-      warn_ref_binding (loc, reftype, intype, decl);
-      rval = build_up_reference (reftype, rval, flags, decl);
+      if (complain & tf_warning)
+       warn_ref_binding (loc, reftype, intype, decl);
+      rval = build_up_reference (reftype, rval, flags, decl, complain);
     }
 
   if (rval)
@@ -507,7 +517,7 @@ convert_to_reference (tree reftype, tree expr, int convtype,
       return rval;
     }
 
-  if (flags & LOOKUP_COMPLAIN)
+  if (complain & tf_error)
     error_at (loc, "cannot convert type %qT to type %qT", intype, reftype);
 
   return error_mark_node;
@@ -595,9 +605,9 @@ cp_fold_convert (tree type, tree expr)
 /* C++ conversions, preference to static cast conversions.  */
 
 tree
-cp_convert (tree type, tree expr)
+cp_convert (tree type, tree expr, tsubst_flags_t complain)
 {
-  return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL);
+  return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL, complain);
 }
 
 /* C++ equivalent of convert_and_check but using cp_convert as the
@@ -608,16 +618,17 @@ cp_convert (tree type, tree expr)
    i.e. because of language rules and not because of an explicit cast.  */
 
 tree
-cp_convert_and_check (tree type, tree expr)
+cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain)
 {
   tree result;
 
   if (TREE_TYPE (expr) == type)
     return expr;
   
-  result = cp_convert (type, expr);
+  result = cp_convert (type, expr, complain);
 
-  if (c_inhibit_evaluation_warnings == 0
+  if ((complain & tf_warning)
+      && c_inhibit_evaluation_warnings == 0
       && !TREE_OVERFLOW_P (expr)
       && result != error_mark_node)
     warnings_for_convert_and_check (type, expr, result);
@@ -630,7 +641,8 @@ cp_convert_and_check (tree type, tree expr)
    FLAGS indicates how we should behave.  */
 
 tree
-ocp_convert (tree type, tree expr, int convtype, int flags)
+ocp_convert (tree type, tree expr, int convtype, int flags,
+            tsubst_flags_t complain)
 {
   tree e = expr;
   enum tree_code code = TREE_CODE (type);
@@ -647,7 +659,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
   if ((invalid_conv_diag
        = targetm.invalid_conversion (TREE_TYPE (expr), type)))
     {
-      error (invalid_conv_diag);
+      if (complain & tf_error)
+       error (invalid_conv_diag);
       return error_mark_node;
     }
 
@@ -696,7 +709,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
 
   if (code == VOID_TYPE && (convtype & CONV_STATIC))
     {
-      e = convert_to_void (e, ICV_CAST, tf_warning_or_error);
+      e = convert_to_void (e, ICV_CAST, complain);
       return e;
     }
 
@@ -714,9 +727,9 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
               && ! (convtype & CONV_STATIC))
              || TREE_CODE (intype) == POINTER_TYPE)
            {
-             if (flags & LOOKUP_COMPLAIN)
+             if (complain & tf_error)
                permerror (loc, "conversion from %q#T to %q#T", intype, type);
-             if (!flag_permissive)
+             else
                return error_mark_node;
            }
 
@@ -727,7 +740,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
             the original value is within the range of the enumeration
             values. Otherwise, the resulting enumeration value is
             unspecified.  */
-         if (TREE_CODE (expr) == INTEGER_CST
+         if ((complain & tf_warning)
+             && TREE_CODE (expr) == INTEGER_CST
              && !int_fits_type_p (expr, ENUM_UNDERLYING_TYPE (type)))
            warning_at (loc, OPT_Wconversion, 
                        "the result of the conversion is unspecified because "
@@ -740,7 +754,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
          rval = build_type_conversion (type, e);
          if (rval)
            return rval;
-         if (flags & LOOKUP_COMPLAIN)
+         if (complain & tf_error)
            error_at (loc, "%q#T used where a %qT was expected", intype, type);
          return error_mark_node;
        }
@@ -748,8 +762,10 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
        {
          if (TREE_CODE (intype) == VOID_TYPE)
            {
-             error_at (loc, "could not convert %qE from %<void%> to %<bool%>",
-                       expr);
+             if (complain & tf_error)
+               error_at (loc,
+                         "could not convert %qE from %<void%> to %<bool%>",
+                         expr);
              return error_mark_node;
            }
 
@@ -768,7 +784,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
   if (NULLPTR_TYPE_P (type) && e && null_ptr_cst_p (e))
     return nullptr_node;
   if (POINTER_TYPE_P (type) || TYPE_PTRMEM_P (type))
-    return fold_if_not_in_template (cp_convert_to_pointer (type, e));
+    return fold_if_not_in_template (cp_convert_to_pointer (type, e, complain));
   if (code == VECTOR_TYPE)
     {
       tree in_vtype = TREE_TYPE (e);
@@ -778,8 +794,9 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
          ret_val = build_type_conversion (type, e);
          if (ret_val)
            return ret_val;
-         if (flags & LOOKUP_COMPLAIN)
-           error_at (loc, "%q#T used where a %qT was expected", in_vtype, type);
+         if (complain & tf_error)
+           error_at (loc, "%q#T used where a %qT was expected",
+                     in_vtype, type);
          return error_mark_node;
        }
       return fold_if_not_in_template (convert_to_vector (type, e));
@@ -792,10 +809,10 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
          rval = build_type_conversion (type, e);
          if (rval)
            return rval;
-         else
-           if (flags & LOOKUP_COMPLAIN)
-             error_at (loc, "%q#T used where a floating point value was expected",
-                       TREE_TYPE (e));
+         else if (complain & tf_error)
+           error_at (loc,
+                     "%q#T used where a floating point value was expected",
+                     TREE_TYPE (e));
        }
       if (code == REAL_TYPE)
        return fold_if_not_in_template (convert_to_real (type, e));
@@ -826,33 +843,31 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
        return error_mark_node;
 
       if (BRACE_ENCLOSED_INITIALIZER_P (ctor))
-       ctor = perform_implicit_conversion (type, ctor, tf_warning_or_error);
+       ctor = perform_implicit_conversion (type, ctor, complain);
       else if ((flags & LOOKUP_ONLYCONVERTING)
               && ! (CLASS_TYPE_P (dtype) && DERIVED_FROM_P (type, dtype)))
        /* For copy-initialization, first we create a temp of the proper type
           with a user-defined conversion sequence, then we direct-initialize
           the target with the temp (see [dcl.init]).  */
-       ctor = build_user_type_conversion (type, ctor, flags,
-                                          tf_warning_or_error);
+       ctor = build_user_type_conversion (type, ctor, flags, complain);
       else
        {
          VEC(tree,gc) *ctor_vec = make_tree_vector_single (ctor);
          ctor = build_special_member_call (NULL_TREE,
                                            complete_ctor_identifier,
                                            &ctor_vec,
-                                           type, flags,
-                                           tf_warning_or_error);
+                                           type, flags, complain);
          release_tree_vector (ctor_vec);
        }
       if (ctor)
-       return build_cplus_new (type, ctor, tf_warning_or_error);
+       return build_cplus_new (type, ctor, complain);
     }
 
-  if (flags & LOOKUP_COMPLAIN)
+  if (complain & tf_error)
     {
       /* If the conversion failed and expr was an invalid use of pointer to
         member function, try to report a meaningful error.  */
-      if (invalid_nonstatic_memfn_p (expr, tf_warning_or_error))
+      if (invalid_nonstatic_memfn_p (expr, complain))
        /* We displayed the error message.  */;
       else
        error_at (loc, "conversion from %qT to non-scalar type %qT requested",
@@ -1416,7 +1431,8 @@ convert (tree type, tree expr)
     return fold_if_not_in_template (build_nop (type, expr));
 
   return ocp_convert (type, expr, CONV_OLD_CONVERT,
-                     LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
+                     LOOKUP_NORMAL|LOOKUP_NO_CONVERSION,
+                     tf_warning_or_error);
 }
 
 /* Like cp_convert, except permit conversions to take place which
@@ -1424,18 +1440,19 @@ convert (tree type, tree expr)
    (such as conversion from sub-type to private super-type).  */
 
 tree
-convert_force (tree type, tree expr, int convtype)
+convert_force (tree type, tree expr, int convtype, tsubst_flags_t complain)
 {
   tree e = expr;
   enum tree_code code = TREE_CODE (type);
 
   if (code == REFERENCE_TYPE)
     return (fold_if_not_in_template
-           (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN,
-                                  NULL_TREE)));
+           (convert_to_reference (type, e, CONV_C_CAST, 0,
+                                  NULL_TREE, complain)));
 
   if (code == POINTER_TYPE)
-    return fold_if_not_in_template (convert_to_pointer_force (type, e));
+    return fold_if_not_in_template (convert_to_pointer_force (type, e,
+                                                             complain));
 
   /* From typeck.c convert_for_assignment */
   if (((TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE && TREE_CODE (e) == ADDR_EXPR
@@ -1446,9 +1463,9 @@ convert_force (tree type, tree expr, int convtype)
       && TYPE_PTRMEMFUNC_P (type))
     /* compatible pointer to member functions.  */
     return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1,
-                            /*c_cast_p=*/1, tf_warning_or_error);
+                            /*c_cast_p=*/1, complain);
 
-  return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL);
+  return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL, complain);
 }
 
 /* Convert an aggregate EXPR to type XTYPE.  If a conversion
index aa98f8b24d79121e8837c62e4d17413990eaa3be..b0f62a3350c62dd71bc3a9ba6c044e66eac503fa 100644 (file)
@@ -8091,9 +8091,10 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
       processing_template_decl = 0;
       itype = cp_build_binary_op (input_location,
                                  MINUS_EXPR,
-                                 cp_convert (ssizetype, size),
-                                 cp_convert (ssizetype, integer_one_node),
-                                 tf_warning_or_error);
+                                 cp_convert (ssizetype, size, complain),
+                                 cp_convert (ssizetype, integer_one_node,
+                                             complain),
+                                 complain);
       itype = fold (itype);
       processing_template_decl = saved_processing_template_decl;
 
@@ -13277,11 +13278,12 @@ finish_destructor_body (void)
       an implicit definition), non-placement operator delete shall
       be looked up in the scope of the destructor's class and if
       found shall be accessible and unambiguous.  */
-      exprstmt = build_op_delete_call(DELETE_EXPR, current_class_ptr,
-                                     virtual_size,
-                                     /*global_p=*/false,
-                                     /*placement=*/NULL_TREE,
-                                     /*alloc_fn=*/NULL_TREE);
+      exprstmt = build_op_delete_call (DELETE_EXPR, current_class_ptr,
+                                      virtual_size,
+                                      /*global_p=*/false,
+                                      /*placement=*/NULL_TREE,
+                                      /*alloc_fn=*/NULL_TREE,
+                                      tf_warning_or_error);
 
       if_stmt = begin_if_stmt ();
       finish_if_stmt_cond (build2 (BIT_AND_EXPR, integer_type_node,
index 6fe3cce2b30ac98870bde767fd6068cbcafcedd3..2339b9ceb38c6b25c232d7c32ef9ad4ddeb7ada6 100644 (file)
@@ -424,7 +424,8 @@ initialize_handler_parm (tree decl, tree exp)
       && TYPE_PTR_P (TREE_TYPE (init_type)))
     exp = cp_build_addr_expr (exp, tf_warning_or_error);
 
-  exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
+  exp = ocp_convert (init_type, exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0,
+                    tf_warning_or_error);
 
   init = convert_from_reference (exp);
 
@@ -435,7 +436,8 @@ initialize_handler_parm (tree decl, tree exp)
       /* Generate the copy constructor call directly so we can wrap it.
         See also expand_default_init.  */
       init = ocp_convert (TREE_TYPE (decl), init,
-                         CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
+                         CONV_IMPLICIT|CONV_FORCE_TEMP, 0,
+                         tf_warning_or_error);
       /* Force cleanups now to avoid nesting problems with the
         MUST_NOT_THROW_EXPR.  */
       init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
index 5bd46cb4b0d0ed16d7e79592cfbc6d855bf1fd1c..419c13f3e61002b2312dbfada6ca5d53d1ce0198 100644 (file)
@@ -1180,7 +1180,7 @@ expand_virtual_init (tree binfo, tree decl)
   gcc_assert (vtbl_ptr != error_mark_node);
 
   /* Assign the vtable to the vptr.  */
-  vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0);
+  vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0, tf_warning_or_error);
   finish_expr_stmt (cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
                                          tf_warning_or_error));
 }
@@ -1250,7 +1250,7 @@ construct_virtual_base (tree vbase, tree arguments)
   exp = convert_to_base_statically (current_class_ref, vbase);
 
   expand_aggr_init_1 (vbase, current_class_ref, exp, arguments,
-                     LOOKUP_COMPLAIN, tf_warning_or_error);
+                     0, tf_warning_or_error);
   finish_then_clause (inner_if_stmt);
   finish_if_stmt (inner_if_stmt);
 
@@ -1598,7 +1598,8 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
           have already built up the constructor call so we could wrap it
           in an exception region.  */;
       else
-       init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
+       init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP,
+                           flags, complain);
 
       if (TREE_CODE (init) == MUST_NOT_THROW_EXPR)
        /* We need to protect the initialization of a catch parm with a
@@ -2656,7 +2657,8 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
                      size,
                      globally_qualified_p,
                      placement_allocation_fn_p ? alloc_call : NULL_TREE,
-                     alloc_fn));
+                     alloc_fn,
+                     complain));
 
          if (!cleanup)
            /* We're done.  */;
@@ -2815,7 +2817,7 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts,
             return error_mark_node;
         }
       nelts = mark_rvalue_use (nelts);
-      nelts = cp_save_expr (cp_convert (sizetype, nelts));
+      nelts = cp_save_expr (cp_convert (sizetype, nelts, complain));
     }
 
   /* ``A reference cannot be created by the new operator.  A reference
@@ -3012,12 +3014,12 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
          base_tbd = cp_build_binary_op (input_location,
                                         MINUS_EXPR,
                                         cp_convert (string_type_node,
-                                                    base),
+                                                    base, complain),
                                         cookie_size,
                                         complain);
          if (base_tbd == error_mark_node)
            return error_mark_node;
-         base_tbd = cp_convert (ptype, base_tbd);
+         base_tbd = cp_convert (ptype, base_tbd, complain);
          /* True size with header.  */
          virtual_size = size_binop (PLUS_EXPR, virtual_size, cookie_size);
        }
@@ -3026,7 +3028,8 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
                                              base_tbd, virtual_size,
                                              use_global_delete & 1,
                                              /*placement=*/NULL_TREE,
-                                             /*alloc_fn=*/NULL_TREE);
+                                             /*alloc_fn=*/NULL_TREE,
+                                             complain);
     }
 
   body = loop;
@@ -3189,14 +3192,14 @@ build_vec_init (tree base, tree maxindex, tree init,
       return stmt_expr;
     }
 
-  maxindex = cp_convert (ptrdiff_type_node, maxindex);
+  maxindex = cp_convert (ptrdiff_type_node, maxindex, complain);
   if (TREE_CODE (atype) == ARRAY_TYPE)
     {
       ptype = build_pointer_type (type);
       base = decay_conversion (base, complain);
       if (base == error_mark_node)
        return error_mark_node;
-      base = cp_convert (ptype, base);
+      base = cp_convert (ptype, base, complain);
     }
   else
     ptype = atype;
@@ -3665,7 +3668,7 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
        addr = save_expr (addr);
 
       /* Throw away const and volatile on target type of addr.  */
-      addr = convert_force (build_pointer_type (type), addr, 0);
+      addr = convert_force (build_pointer_type (type), addr, 0, complain);
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
     {
@@ -3691,7 +3694,7 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
       if (TREE_SIDE_EFFECTS (addr))
        addr = save_expr (addr);
 
-      addr = convert_force (build_pointer_type (type), addr, 0);
+      addr = convert_force (build_pointer_type (type), addr, 0, complain);
     }
 
   gcc_assert (MAYBE_CLASS_TYPE_P (type));
@@ -3705,7 +3708,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
                                   cxx_sizeof_nowarn (type),
                                   use_global_delete,
                                   /*placement=*/NULL_TREE,
-                                  /*alloc_fn=*/NULL_TREE);
+                                  /*alloc_fn=*/NULL_TREE,
+                                  complain);
     }
   else
     {
@@ -3744,7 +3748,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
                                            cxx_sizeof_nowarn (type),
                                            /*global_p=*/false,
                                            /*placement=*/NULL_TREE,
-                                           /*alloc_fn=*/NULL_TREE);
+                                           /*alloc_fn=*/NULL_TREE,
+                                           complain);
          /* Call the complete object destructor.  */
          auto_delete = sfk_complete_destructor;
        }
@@ -3756,7 +3761,8 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
          build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),
                                /*global_p=*/false,
                                /*placement=*/NULL_TREE,
-                               /*alloc_fn=*/NULL_TREE);
+                               /*alloc_fn=*/NULL_TREE,
+                               complain);
        }
 
       expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL, complain),
index 6e2952131ba5e27de370b0b338fec6475e6aa22a..0237456dcca4117f37320fb9fa9ac8378a87b9d0 100644 (file)
@@ -1228,16 +1228,9 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
 
   scope = push_scope (ctype);
 
-  if (diag)
-    {
-      flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED;
-      complain = tf_warning_or_error;
-    }
-  else
-    {
-      flags = LOOKUP_PROTECT|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED;
-      complain = tf_none;
-    }
+  flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED;
+
+  complain = diag ? tf_warning_or_error : tf_none;
 
   if (const_p)
     quals = TYPE_QUAL_CONST;
index 642f39f2628da6e91846f31ff2917a444fb4d0e2..9cc6d39fffa1a99920b635cf9e10e1213f4f9933 100644 (file)
@@ -1854,7 +1854,7 @@ identifier_type_value_1 (tree id)
     return REAL_IDENTIFIER_TYPE_VALUE (id);
   /* Have to search for it. It must be on the global level, now.
      Ask lookup_name not to return non-types.  */
-  id = lookup_name_real (id, 2, 1, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
+  id = lookup_name_real (id, 2, 1, /*block_p=*/true, 0, 0);
   if (id)
     return TREE_TYPE (id);
   return NULL_TREE;
@@ -4345,7 +4345,6 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
     {
       struct scope_binding binding = EMPTY_SCOPE_BINDING;
 
-      flags |= LOOKUP_COMPLAIN;
       if (is_type_p)
        flags |= LOOKUP_PREFER_TYPES;
       if (qualified_lookup_using_namespace (name, scope, &binding, flags))
@@ -4772,7 +4771,7 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
 tree
 lookup_name_nonclass (tree name)
 {
-  return lookup_name_real (name, 0, 1, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
+  return lookup_name_real (name, 0, 1, /*block_p=*/true, 0, 0);
 }
 
 tree
@@ -4780,22 +4779,20 @@ lookup_function_nonclass (tree name, VEC(tree,gc) *args, bool block_p)
 {
   return
     lookup_arg_dependent (name,
-                         lookup_name_real (name, 0, 1, block_p, 0,
-                                           LOOKUP_COMPLAIN),
+                         lookup_name_real (name, 0, 1, block_p, 0, 0),
                          args, false);
 }
 
 tree
 lookup_name (tree name)
 {
-  return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, LOOKUP_COMPLAIN);
+  return lookup_name_real (name, 0, 0, /*block_p=*/true, 0, 0);
 }
 
 tree
 lookup_name_prefer_type (tree name, int prefer_type)
 {
-  return lookup_name_real (name, prefer_type, 0, /*block_p=*/true,
-                          0, LOOKUP_COMPLAIN);
+  return lookup_name_real (name, prefer_type, 0, /*block_p=*/true, 0, 0);
 }
 
 /* Look up NAME for type used in elaborated name specifier in
index 5698c975a48505405370df014dc7c0c8c1cb2e34..8f0b3c0450244119056bc640e260c8d6a9fa7264 100644 (file)
@@ -138,7 +138,8 @@ build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
                                       virtual_size,
                                       /*global_p=*/false,
                                       /*placement=*/NULL_TREE,
-                                      /*alloc_fn=*/NULL_TREE);
+                                      /*alloc_fn=*/NULL_TREE,
+                                     tf_warning_or_error);
   add_stmt (call_delete);
 
   /* Return the address of the object.  */
index 5256d01555ded4697893c8aa8b58ff73efd32b3c..85e0322e43f2671b67d0d269afbde8b87623b685 100644 (file)
@@ -20320,13 +20320,9 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
                       tree *ambiguous_decls,
                       location_t name_location)
 {
-  int flags = 0;
   tree decl;
   tree object_type = parser->context->object_type;
 
-  if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
-    flags |= LOOKUP_COMPLAIN;
-
   /* Assume that the lookup will be unambiguous.  */
   if (ambiguous_decls)
     *ambiguous_decls = NULL_TREE;
@@ -20498,7 +20494,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
       /* Look it up in the enclosing context, too.  */
       decl = lookup_name_real (name, tag_type != none_type,
                               /*nonclass=*/0,
-                              /*block_p=*/true, is_namespace, flags);
+                              /*block_p=*/true, is_namespace, 0);
       parser->object_scope = object_type;
       parser->qualifying_scope = NULL_TREE;
       if (object_decl)
@@ -20508,7 +20504,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
     {
       decl = lookup_name_real (name, tag_type != none_type,
                               /*nonclass=*/0,
-                              /*block_p=*/true, is_namespace, flags);
+                              /*block_p=*/true, is_namespace, 0);
       parser->qualifying_scope = NULL_TREE;
       parser->object_scope = NULL_TREE;
     }
index 4d4e8ada80f4b24c1674a9388d2600ab0dd6fdfd..df80159cf7594b3ee11b79c30ea10ae783205a25 100644 (file)
@@ -8474,8 +8474,7 @@ tsubst_friend_class (tree friend_tmpl, tree args)
 
      both F templates are the same.  */
   tmpl = lookup_name_real (DECL_NAME (friend_tmpl), 0, 0,
-                          /*block_p=*/true, 0, 
-                          LOOKUP_COMPLAIN | LOOKUP_HIDDEN);
+                          /*block_p=*/true, 0, LOOKUP_HIDDEN);
 
   /* But, if we don't find one, it might be because we're in a
      situation like this:
index e79b02e6837fc8be01bac1f720e1445ccb7b35fd..a19a893c6647f0ff5dd70dc6389f3277249c79f0 100644 (file)
@@ -99,7 +99,7 @@ VEC(tree,gc) *unemitted_tinfo_decls;
    and are generated as needed. */
 static GTY (()) VEC(tinfo_s,gc) *tinfo_descs;
 
-static tree ifnonnull (tree, tree);
+static tree ifnonnull (tree, tree, tsubst_flags_t);
 static tree tinfo_name (tree, bool);
 static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
 static tree throw_bad_cast (void);
@@ -336,7 +336,8 @@ build_typeid (tree exp)
          This is an lvalue use of expr then.  */
       exp = mark_lvalue_use (exp);
       exp = stabilize_reference (exp);
-      cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0));
+      cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0),
+                        tf_warning_or_error);
     }
 
   exp = get_tinfo_decl_dynamic (exp);
@@ -498,12 +499,13 @@ get_typeid (tree type)
    RESULT, it must have previously had a save_expr applied to it.  */
 
 static tree
-ifnonnull (tree test, tree result)
+ifnonnull (tree test, tree result, tsubst_flags_t complain)
 {
   return build3 (COND_EXPR, TREE_TYPE (result),
                 build2 (EQ_EXPR, boolean_type_node, test,
-                        cp_convert (TREE_TYPE (test), nullptr_node)),
-                cp_convert (TREE_TYPE (result), nullptr_node),
+                        cp_convert (TREE_TYPE (test), nullptr_node,
+                                    complain)),
+                cp_convert (TREE_TYPE (result), nullptr_node, complain),
                 result);
 }
 
@@ -596,7 +598,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
 
       /* Apply trivial conversion T -> T& for dereferenced ptrs.  */
       expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
-                                  LOOKUP_NORMAL, NULL_TREE);
+                                  LOOKUP_NORMAL, NULL_TREE, complain);
     }
 
   /* The dynamic_cast operator shall not cast away constness.  */
@@ -644,7 +646,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
          expr1 = build_headof (expr);
          if (TREE_TYPE (expr1) != type)
            expr1 = build1 (NOP_EXPR, type, expr1);
-         return ifnonnull (expr, expr1);
+         return ifnonnull (expr, expr1, complain);
        }
       else
        {
@@ -752,12 +754,12 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
              neq = cp_truthvalue_conversion (result);
              return cp_convert (type,
                                 build3 (COND_EXPR, TREE_TYPE (result),
-                                        neq, result, bad));
+                                        neq, result, bad), complain);
            }
 
          /* Now back to the type we want from a void*.  */
-         result = cp_convert (type, result);
-         return ifnonnull (expr, result);
+         result = cp_convert (type, result, complain);
+         return ifnonnull (expr, result, complain);
        }
     }
   else
index 4334d4c0916ed67c5fa27ae69e306d7b3c14f114..7769bbaa36fba4babb417379d6926637e4c9e225 100644 (file)
@@ -564,7 +564,8 @@ finish_goto_stmt (tree destination)
       destination = mark_rvalue_use (destination);
       if (!processing_template_decl)
        {
-         destination = cp_convert (ptr_type_node, destination);
+         destination = cp_convert (ptr_type_node, destination,
+                                   tf_warning_or_error);
          if (error_operand_p (destination))
            return NULL_TREE;
        }
@@ -4526,7 +4527,8 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
                  if (error_operand_p (iter_incr))
                    return true;
                  incr = TREE_OPERAND (rhs, 1);
-                 incr = cp_convert (TREE_TYPE (diff), incr);
+                 incr = cp_convert (TREE_TYPE (diff), incr,
+                                    tf_warning_or_error);
                  if (TREE_CODE (rhs) == MINUS_EXPR)
                    {
                      incr = build1 (NEGATE_EXPR, TREE_TYPE (diff), incr);
@@ -4581,7 +4583,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
       return true;
     }
 
-  incr = cp_convert (TREE_TYPE (diff), incr);
+  incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error);
   for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
        && OMP_CLAUSE_DECL (c) == iter)
@@ -5130,7 +5132,7 @@ finish_static_assert (tree condition, tree message, location_t location,
 
   /* Fold the expression and convert it to a boolean value. */
   condition = fold_non_dependent_expr (condition);
-  condition = cp_convert (boolean_type_node, condition);
+  condition = cp_convert (boolean_type_node, condition, tf_warning_or_error);
   condition = maybe_constant_value (condition);
 
   if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
index bca676bbe18fe439ff8a4558971f6cd1113d685b..945266b854e9f42349f4c27bb8e1c31030e781f8 100644 (file)
@@ -52,7 +52,7 @@ static tree rationalize_conditional_expr (enum tree_code, tree,
 static int comp_ptr_ttypes_real (tree, tree, int);
 static bool comp_except_types (tree, tree, bool);
 static bool comp_array_types (const_tree, const_tree, bool);
-static tree pointer_diff (tree, tree, tree);
+static tree pointer_diff (tree, tree, tree, tsubst_flags_t);
 static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
 static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
 static bool casts_away_constness (tree, tree, tsubst_flags_t);
@@ -1906,7 +1906,7 @@ decay_conversion (tree exp, tsubst_flags_t complain)
       /* This way is better for a COMPONENT_REF since it can
         simplify the offset for a component.  */
       adr = cp_build_addr_expr (exp, complain);
-      return cp_convert (ptrtype, adr);
+      return cp_convert (ptrtype, adr, complain);
     }
 
   /* If a bitfield is used in a context where integral promotion
@@ -1950,12 +1950,12 @@ cp_default_conversion (tree exp, tsubst_flags_t complain)
   /* Check for target-specific promotions.  */
   tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
   if (promoted_type)
-    exp = cp_convert (promoted_type, exp);
+    exp = cp_convert (promoted_type, exp, complain);
   /* Perform the integral promotions first so that bitfield
      expressions (which may promote to "int", even if the bitfield is
      declared "unsigned") are promoted correctly.  */
   else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
-    exp = perform_integral_promotions (exp);
+    exp = cp_perform_integral_promotions (exp, complain);
   /* Perform the other conversions.  */
   exp = decay_conversion (exp, complain);
 
@@ -1975,7 +1975,7 @@ default_conversion (tree exp)
    converted value.  */
 
 tree
-perform_integral_promotions (tree expr)
+cp_perform_integral_promotions (tree expr, tsubst_flags_t complain)
 {
   tree type;
   tree promoted_type;
@@ -1995,10 +1995,18 @@ perform_integral_promotions (tree expr)
     return expr;
   promoted_type = type_promotes_to (type);
   if (type != promoted_type)
-    expr = cp_convert (promoted_type, expr);
+    expr = cp_convert (promoted_type, expr, complain);
   return expr;
 }
 
+/* C version.  */
+
+tree
+perform_integral_promotions (tree expr)
+{
+  return cp_perform_integral_promotions (expr, tf_warning_or_error);
+}
+
 /* Returns nonzero iff exp is a STRING_CST or the result of applying
    decay_conversion to one.  */
 
@@ -2945,7 +2953,7 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
         does not say that we should.  In fact, the natural thing would
         seem to be to convert IDX to ptrdiff_t; we're performing
         pointer arithmetic.)  */
-      idx = perform_integral_promotions (idx);
+      idx = cp_perform_integral_promotions (idx, complain);
 
       /* An array that is indexed by a non-constant
         cannot be stored in a register; we must be able to do
@@ -3867,7 +3875,8 @@ cp_build_binary_op (location_t location,
       if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
          && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
                                                        TREE_TYPE (type1)))
-       return pointer_diff (op0, op1, common_pointer_type (type0, type1));
+       return pointer_diff (op0, op1, common_pointer_type (type0, type1),
+                            complain);
       /* In all other cases except pointer - int, the usual arithmetic
         rules apply.  */
       else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
@@ -4003,7 +4012,7 @@ cp_build_binary_op (location_t location,
          /* Convert the shift-count to an integer, regardless of
             size of value being shifted.  */
          if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-           op1 = cp_convert (integer_type_node, op1);
+           op1 = cp_convert (integer_type_node, op1, complain);
          /* Avoid converting op1 to result_type later.  */
          converted = 1;
        }
@@ -4031,7 +4040,7 @@ cp_build_binary_op (location_t location,
          /* Convert the shift-count to an integer, regardless of
             size of value being shifted.  */
          if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-           op1 = cp_convert (integer_type_node, op1);
+           op1 = cp_convert (integer_type_node, op1, complain);
          /* Avoid converting op1 to result_type later.  */
          converted = 1;
        }
@@ -4062,7 +4071,7 @@ cp_build_binary_op (location_t location,
          /* Convert the shift-count to an integer, regardless of
             size of value being shifted.  */
          if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
-           op1 = cp_convert (integer_type_node, op1);
+           op1 = cp_convert (integer_type_node, op1, complain);
        }
       break;
 
@@ -4162,12 +4171,12 @@ cp_build_binary_op (location_t location,
              op0 = cp_build_binary_op (location,
                                        TRUTH_ANDIF_EXPR, e1, e2,
                                        complain);
-             op1 = cp_convert (TREE_TYPE (op0), integer_one_node); 
+             op1 = cp_convert (TREE_TYPE (op0), integer_one_node, complain); 
            }
          else 
            {
              op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
-             op1 = cp_convert (TREE_TYPE (op0), op1);
+             op1 = cp_convert (TREE_TYPE (op0), op1, complain);
            }
          result_type = TREE_TYPE (op0);
        }
@@ -4190,9 +4199,9 @@ cp_build_binary_op (location_t location,
                                         CPO_COMPARISON, complain);
 
          if (!same_type_p (TREE_TYPE (op0), type))
-           op0 = cp_convert_and_check (type, op0);
+           op0 = cp_convert_and_check (type, op0, complain);
          if (!same_type_p (TREE_TYPE (op1), type))
-           op1 = cp_convert_and_check (type, op1);
+           op1 = cp_convert_and_check (type, op1, complain);
 
          if (op0 == error_mark_node || op1 == error_mark_node)
            return error_mark_node;
@@ -4456,16 +4465,16 @@ cp_build_binary_op (location_t location,
          if (first_complex)
            {
              if (TREE_TYPE (op0) != result_type)
-               op0 = cp_convert_and_check (result_type, op0);
+               op0 = cp_convert_and_check (result_type, op0, complain);
              if (TREE_TYPE (op1) != real_type)
-               op1 = cp_convert_and_check (real_type, op1);
+               op1 = cp_convert_and_check (real_type, op1, complain);
            }
          else
            {
              if (TREE_TYPE (op0) != real_type)
-               op0 = cp_convert_and_check (real_type, op0);
+               op0 = cp_convert_and_check (real_type, op0, complain);
              if (TREE_TYPE (op1) != result_type)
-               op1 = cp_convert_and_check (result_type, op1);
+               op1 = cp_convert_and_check (result_type, op1, complain);
            }
          if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
            return error_mark_node;
@@ -4550,7 +4559,7 @@ cp_build_binary_op (location_t location,
          tree val
            = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
          if (val != 0)
-           return cp_convert (boolean_type_node, val);
+           return cp_convert (boolean_type_node, val, complain);
          op0 = xop0, op1 = xop1;
          converted = 1;
          resultcode = xresultcode;
@@ -4580,9 +4589,9 @@ cp_build_binary_op (location_t location,
   if (! converted)
     {
       if (TREE_TYPE (op0) != result_type)
-       op0 = cp_convert_and_check (result_type, op0);
+       op0 = cp_convert_and_check (result_type, op0, complain);
       if (TREE_TYPE (op1) != result_type)
-       op1 = cp_convert_and_check (result_type, op1);
+       op1 = cp_convert_and_check (result_type, op1, complain);
 
       if (op0 == error_mark_node || op1 == error_mark_node)
        return error_mark_node;
@@ -4594,7 +4603,7 @@ cp_build_binary_op (location_t location,
   result = build2 (resultcode, build_type, op0, op1);
   result = fold_if_not_in_template (result);
   if (final_type != 0)
-    result = cp_convert (final_type, result);
+    result = cp_convert (final_type, result, complain);
 
   if (TREE_OVERFLOW_P (result) 
       && !TREE_OVERFLOW_P (op0) 
@@ -4627,7 +4636,7 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
    The resulting tree has type int.  */
 
 static tree
-pointer_diff (tree op0, tree op1, tree ptrtype)
+pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
 {
   tree result;
   tree restype = ptrdiff_type_node;
@@ -4637,24 +4646,48 @@ pointer_diff (tree op0, tree op1, tree ptrtype)
     return error_mark_node;
 
   if (TREE_CODE (target_type) == VOID_TYPE)
-    permerror (input_location, "ISO C++ forbids using pointer of type %<void *%> in subtraction");
+    {
+      if (complain & tf_error)
+       permerror (input_location, "ISO C++ forbids using pointer of "
+                  "type %<void *%> in subtraction");
+      else
+       return error_mark_node;
+    }
   if (TREE_CODE (target_type) == FUNCTION_TYPE)
-    permerror (input_location, "ISO C++ forbids using pointer to a function in subtraction");
+    {
+      if (complain & tf_error)
+       permerror (input_location, "ISO C++ forbids using pointer to "
+                  "a function in subtraction");
+      else
+       return error_mark_node;
+    }
   if (TREE_CODE (target_type) == METHOD_TYPE)
-    permerror (input_location, "ISO C++ forbids using pointer to a method in subtraction");
+    {
+      if (complain & tf_error)
+       permerror (input_location, "ISO C++ forbids using pointer to "
+                  "a method in subtraction");
+      else
+       return error_mark_node;
+    }
 
   /* First do the subtraction as integers;
      then drop through to build the divide operator.  */
 
   op0 = cp_build_binary_op (input_location,
                            MINUS_EXPR,
-                           cp_convert (restype, op0),
-                           cp_convert (restype, op1),
-                           tf_warning_or_error);
+                           cp_convert (restype, op0, complain),
+                           cp_convert (restype, op1, complain),
+                           complain);
 
   /* This generates an error if op1 is a pointer to an incomplete type.  */
   if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
-    error ("invalid use of a pointer to an incomplete type in pointer arithmetic");
+    {
+      if (complain & tf_error)
+       error ("invalid use of a pointer to an incomplete type in "
+              "pointer arithmetic");
+      else
+       return error_mark_node;
+    }
 
   op1 = (TYPE_PTROB_P (ptrtype)
         ? size_in_bytes (target_type)
@@ -4662,7 +4695,8 @@ pointer_diff (tree op0, tree op1, tree ptrtype)
 
   /* Do the division.  */
 
-  result = build2 (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1));
+  result = build2 (EXACT_DIV_EXPR, restype, op0,
+                  cp_convert (restype, op1, complain));
   return fold_if_not_in_template (result);
 }
 \f
@@ -5175,7 +5209,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
        else
          {
            if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
-             arg = perform_integral_promotions (arg);
+             arg = cp_perform_integral_promotions (arg, complain);
 
            /* Make sure the result is not an lvalue: a unary plus or minus
               expression is always a rvalue.  */
@@ -5200,7 +5234,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
                                                   arg, true)))
        errstring = _("wrong type argument to bit-complement");
       else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
-       arg = perform_integral_promotions (arg);
+       arg = cp_perform_integral_promotions (arg, complain);
       break;
 
     case ABS_EXPR:
@@ -5358,7 +5392,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
        else
          inc = integer_one_node;
 
-       inc = cp_convert (argtype, inc);
+       inc = cp_convert (argtype, inc, complain);
 
        /* If 'arg' is an Objective-C PROPERTY_REF expression, then we
           need to ask Objective-C to build the increment or decrement
@@ -6074,7 +6108,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
        || SCALAR_FLOAT_TYPE_P (type))
       && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
          || SCALAR_FLOAT_TYPE_P (intype)))
-    return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL);
+    return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain);
 
   if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
       && CLASS_TYPE_P (TREE_TYPE (type))
@@ -6417,7 +6451,7 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
       return error_mark_node;
     }
 
-  return cp_convert (type, expr);
+  return cp_convert (type, expr, complain);
 }
 
 tree
@@ -7078,7 +7112,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
                                     NULL_TREE, 0, complain, LOOKUP_IMPLICIT);
 
   if (!same_type_p (lhstype, olhstype))
-    newrhs = cp_convert_and_check (lhstype, newrhs);
+    newrhs = cp_convert_and_check (lhstype, newrhs, complain);
 
   if (modifycode != INIT_EXPR)
     {
@@ -7599,7 +7633,7 @@ convert_for_assignment (tree type, tree rhs,
       if (!warn_pmf2ptr
          && TYPE_PTR_P (type)
          && TYPE_PTRMEMFUNC_P (rhstype))
-       rhs = cp_convert (strip_top_quals (type), rhs);
+       rhs = cp_convert (strip_top_quals (type), rhs, complain);
       else
        {
          if (complain & tf_error)
@@ -7723,9 +7757,7 @@ convert_for_assignment (tree type, tree rhs,
    latter (X(X&)).
 
    If using constructor make sure no conversion operator exists, if one does
-   exist, an ambiguity exists.
-
-   If flags doesn't include LOOKUP_COMPLAIN, don't complain about anything.  */
+   exist, an ambiguity exists.  */
 
 tree
 convert_for_initialization (tree exp, tree type, tree rhs, int flags,
index 688dabc7fbc9fee8dde1b203c3026ecfa2020a4f..326f602b0fdfeff0db7999d51cc16681a3aed79b 100644 (file)
@@ -1264,7 +1264,7 @@ process_init_constructor_record (tree type, tree init,
 
       /* If this is a bitfield, now convert to the lowered type.  */
       if (type != TREE_TYPE (field))
-       next = cp_convert_and_check (TREE_TYPE (field), next);
+       next = cp_convert_and_check (TREE_TYPE (field), next, complain);
       flags |= picflag_from_initializer (next);
       CONSTRUCTOR_APPEND_ELT (v, field, next);
     }
index 01d759da131dd27f98e7d78e53da6c863720f0b4..2711820f14f424a9646bb24101f2d40a5355f166 100644 (file)
@@ -1,3 +1,8 @@
+2012-06-06  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/53567
+       * g++.dg/cpp0x/alias-decl-19.C: New.
+
 2012-06-06  Steven Bosscher  <steven@gcc.gnu.org>
 
        * g++.old-deja/g++.brendan/array1.C: Remove dg-options.
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C
new file mode 100644 (file)
index 0000000..b101cb3
--- /dev/null
@@ -0,0 +1,31 @@
+// PR c++/53567
+// { dg-do compile { target c++11 } }
+
+template <unsigned int, bool> struct IntegerType { typedef unsigned type; };
+
+template <class EnumT>
+using UnderlyingEnumType = typename IntegerType<sizeof(EnumT), (EnumT(-1) > EnumT(0))>::type;
+
+template <class EnumT, class UnderlyingT = UnderlyingEnumType<EnumT>>
+struct EnumMask
+{
+  constexpr EnumMask(EnumT val) : m_val(val) {}
+  operator EnumT() { return m_val; }
+
+  EnumT m_val;
+};
+
+enum class A : unsigned { x };
+
+template <class EnumT>
+EnumMask<EnumT> operator ~(EnumT lhs)
+{
+  return EnumT(~unsigned(lhs) & unsigned(EnumT::maskAll)); // { dg-error "not a member" }
+
+}
+
+int main()
+{
+  ~A::x;
+  return 0;
+}