re PR c++/44267 (SFINAE does not handle down static_cast over virtual inheritance)
[gcc.git] / gcc / cp / typeck.c
index d87c107ab762ac33a1cc73ee4e8a4f74569d5d16..955e37a28893d596c9e05defa8b252ac3ab7234a 100644 (file)
@@ -1331,8 +1331,8 @@ structural_comptypes (tree t1, tree t2, int strict)
           != DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t2)
          || (DECLTYPE_FOR_LAMBDA_CAPTURE (t1)
              != DECLTYPE_FOR_LAMBDA_CAPTURE (t2))
-         || (DECLTYPE_FOR_LAMBDA_RETURN (t1)
-             != DECLTYPE_FOR_LAMBDA_RETURN (t2))
+         || (DECLTYPE_FOR_LAMBDA_PROXY (t1)
+             != DECLTYPE_FOR_LAMBDA_PROXY (t2))
           || !cp_tree_equal (DECLTYPE_TYPE_EXPR (t1), 
                              DECLTYPE_TYPE_EXPR (t2)))
         return false;
@@ -2221,7 +2221,7 @@ build_class_member_access_expr (tree object, tree member,
 
          /* Convert to the base.  */
          object = build_base_path (PLUS_EXPR, object, binfo,
-                                   /*nonnull=*/1);
+                                   /*nonnull=*/1, complain);
          /* If we found the base successfully then we should be able
             to convert to it successfully.  */
          gcc_assert (object != error_mark_node);
@@ -3073,13 +3073,12 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
          basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
                                  basetype, ba_check, NULL);
          instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype,
-                                         1);
+                                         1, tf_warning_or_error);
          if (instance_ptr == error_mark_node)
            return error_mark_node;
        }
       /* ...and then the delta in the PMF.  */
-      instance_ptr = build2 (POINTER_PLUS_EXPR, TREE_TYPE (instance_ptr),
-                            instance_ptr, fold_convert (sizetype, delta));
+      instance_ptr = fold_build_pointer_plus (instance_ptr, delta);
 
       /* Hand back the adjusted 'this' argument to our caller.  */
       *instance_ptrptr = instance_ptr;
@@ -3094,9 +3093,7 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
       TREE_NO_WARNING (vtbl) = 1;
 
       /* Finally, extract the function pointer from the vtable.  */
-      e2 = fold_build2_loc (input_location,
-                       POINTER_PLUS_EXPR, TREE_TYPE (vtbl), vtbl,
-                       fold_convert (sizetype, idx));
+      e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
       e2 = cp_build_indirect_ref (e2, RO_NULL, tf_warning_or_error);
       TREE_CONSTANT (e2) = 1;
 
@@ -4841,8 +4838,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
     {
       tree type = build_pointer_type (argtype);
       tree op0 = fold_convert (type, TREE_OPERAND (val, 0));
-      tree op1 = fold_convert (sizetype, fold_offsetof (arg, val));
-      return fold_build2 (POINTER_PLUS_EXPR, type, op0, op1);
+      tree op1 = fold_offsetof (arg, val);
+      return fold_build_pointer_plus (op0, op1);
     }
 
   /* Handle complex lvalues (when permitted)
@@ -5223,6 +5220,9 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
              }
            val = boolean_increment (code, arg);
          }
+       else if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
+         /* An rvalue has no cv-qualifiers.  */
+         val = build2 (code, cv_unqualified (TREE_TYPE (arg)), arg, inc);
        else
          val = build2 (code, TREE_TYPE (arg), arg, inc);
 
@@ -5470,6 +5470,16 @@ build_x_compound_expr_from_list (tree list, expr_list_kind exp,
 {
   tree expr = TREE_VALUE (list);
 
+  if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+      && !CONSTRUCTOR_IS_DIRECT_INIT (expr))
+    {
+      if (complain & tf_error)
+       pedwarn (EXPR_LOC_OR_HERE (expr), 0, "list-initializer for "
+                "non-class type must not be parenthesized");
+      else
+       return error_mark_node;
+    }
+
   if (TREE_CHAIN (list))
     {
       if (complain & tf_error)
@@ -5762,7 +5772,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
       /* Convert from "B*" to "D*".  This function will check that "B"
         is not a virtual base of "D".  */
       expr = build_base_path (MINUS_EXPR, build_address (expr),
-                             base, /*nonnull=*/false);
+                             base, /*nonnull=*/false, complain);
       /* Convert the pointer to a reference -- but then remember that
         there are no expressions with reference type in C++.
 
@@ -5864,7 +5874,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
       base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
                          c_cast_p ? ba_unique : ba_check,
                          NULL);
-      expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false);
+      expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false,
+                             complain);
       return cp_fold_convert(type, expr);
     }
 
@@ -6682,6 +6693,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
             side effect associated with any single compound assignment
             operator. -- end note ]  */
          lhs = stabilize_reference (lhs);
+         if (TREE_SIDE_EFFECTS (rhs))
+           rhs = mark_rvalue_use (rhs);
          rhs = stabilize_expr (rhs, &init);
          newrhs = cp_build_binary_op (input_location,
                                       modifycode, lhs, rhs,
@@ -6756,6 +6769,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
          if (check_array_initializer (lhs, lhstype, newrhs))
            return error_mark_node;
          newrhs = digest_init (lhstype, newrhs, complain);
+         if (newrhs == error_mark_node)
+           return error_mark_node;
        }
 
       else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
@@ -7496,7 +7511,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
       if (fndecl)
        savew = warningcount, savee = errorcount;
       rhs = initialize_reference (type, rhs, /*decl=*/NULL_TREE,
-                                 /*cleanup=*/NULL, complain);
+                                 /*cleanup=*/NULL, flags, complain);
       if (fndecl)
        {
          if (warningcount > savew)
@@ -7643,15 +7658,14 @@ check_return_expr (tree retval, bool *no_warning)
          tree type = lambda_return_type (retval);
          tree oldtype = LAMBDA_EXPR_RETURN_TYPE (lambda);
 
-         if (VOID_TYPE_P (type))
-           { /* Nothing.  */ }
-         else if (oldtype == NULL_TREE)
-           {
-             pedwarn (input_location, OPT_pedantic, "lambda return type "
-                      "can only be deduced when the return statement is "
-                      "the only statement in the function body");
-             apply_lambda_return_type (lambda, type);
-           }
+         if (oldtype == NULL_TREE)
+           apply_lambda_return_type (lambda, type);
+         /* If one of the answers is type-dependent, we can't do any
+            better until instantiation time.  */
+         else if (oldtype == dependent_lambda_return_type_node)
+           /* Leave it.  */;
+         else if (type == dependent_lambda_return_type_node)
+           apply_lambda_return_type (lambda, type);
          else if (!same_type_p (type, oldtype))
            error ("inconsistent types %qT and %qT deduced for "
                   "lambda return type", type, oldtype);