init.c (build_value_init_noctor): Handle REFERENCE_TYPE at top level.
authorJason Merrill <jason@redhat.com>
Thu, 7 Apr 2011 21:47:17 +0000 (17:47 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 7 Apr 2011 21:47:17 +0000 (17:47 -0400)
* init.c (build_value_init_noctor): Handle REFERENCE_TYPE at top
level.
(perform_member_init): Not here.
* typeck2.c (build_functional_cast): Limit REFERENCE_TYPE special
case to templates.
(abstract_virtuals_error_sfinae): Remove RESULT_DECL special case.

From-SVN: r172142

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/cp/typeck2.c

index 7e0a596884afa848e57a8354de61d47be5a30829..ca7a79088c2afe27f0e5669d2d752b408174efcb 100644 (file)
@@ -1,5 +1,12 @@
 2011-04-07  Jason Merrill  <jason@redhat.com>
 
+       * init.c (build_value_init_noctor): Handle REFERENCE_TYPE at top
+       level.
+       (perform_member_init): Not here.
+       * typeck2.c (build_functional_cast): Limit REFERENCE_TYPE special
+       case to templates.
+       (abstract_virtuals_error_sfinae): Remove RESULT_DECL special case.
+
        PR c++/48449
        * typeck2.c (build_functional_cast): Check complain consistently.
        Use build_value_init and abstract_virtuals_error_sfinae.
index 2e9eb68079948d40c5b64358023a5aaf87deebcf..005f8d6dfe22230bcfa7de1a9d5c50659ae2caff 100644 (file)
@@ -388,14 +388,6 @@ build_value_init_noctor (tree type, tsubst_flags_t complain)
 
              ftype = TREE_TYPE (field);
 
-             if (TREE_CODE (ftype) == REFERENCE_TYPE)
-               {
-                 if (complain & tf_error)
-                   error ("value-initialization of reference");
-                 else
-                   return error_mark_node;
-               }
-
              /* We could skip vfields and fields of types with
                 user-defined constructors, but I think that won't improve
                 performance at all; it should be simpler in general just
@@ -408,6 +400,9 @@ build_value_init_noctor (tree type, tsubst_flags_t complain)
                 all of the subobjects.  */
              value = build_value_init (ftype, complain);
 
+             if (value == error_mark_node)
+               return error_mark_node;
+
              if (value)
                CONSTRUCTOR_APPEND_ELT(v, field, value);
            }
@@ -450,6 +445,9 @@ build_value_init_noctor (tree type, tsubst_flags_t complain)
 
          ce->value = build_value_init (TREE_TYPE (type), complain);
 
+         if (ce->value == error_mark_node)
+           return error_mark_node;
+
          /* The gimplifier can't deal with a RANGE_EXPR of TARGET_EXPRs.  */
          gcc_assert (TREE_CODE (ce->value) != TARGET_EXPR
                      && TREE_CODE (ce->value) != AGGR_INIT_EXPR);
@@ -464,6 +462,12 @@ build_value_init_noctor (tree type, tsubst_flags_t complain)
        error ("value-initialization of function type %qT", type);
       return error_mark_node;
     }
+  else if (TREE_CODE (type) == REFERENCE_TYPE)
+    {
+      if (complain & tf_error)
+       error ("value-initialization of reference type %qT", type);
+      return error_mark_node;
+    }
 
   return build_zero_init (type, NULL_TREE, /*static_storage_p=*/false);
 }
@@ -504,16 +508,9 @@ perform_member_init (tree member, tree init)
        }
       else
        {
-         if (TREE_CODE (type) == REFERENCE_TYPE)
-           permerror (DECL_SOURCE_LOCATION (current_function_decl),
-                      "value-initialization of %q#D, which has reference type",
-                      member);
-         else
-           {
-             init = build2 (INIT_EXPR, type, decl,
-                            build_value_init (type, tf_warning_or_error));
-             finish_expr_stmt (init);
-           }
+         init = build2 (INIT_EXPR, type, decl,
+                        build_value_init (type, tf_warning_or_error));
+         finish_expr_stmt (init);
        }
     }
   /* Deal with this here, as we will get confused if we try to call the
index f2046f7e221bf855dcb82af7f09ea1f37611c9c1..f3a0079015070db8c697128458b5754e2309b124 100644 (file)
@@ -301,9 +301,6 @@ abstract_virtuals_error_sfinae (tree decl, tree type, tsubst_flags_t complain)
   if (!pure)
     return 0;
 
-  if (decl && TREE_CODE (decl) == RESULT_DECL)
-    return 0;
-
   if (!(complain & tf_error))
     return 1;
 
@@ -1536,16 +1533,21 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
   else
     type = exp;
 
-  if (TREE_CODE (type) == REFERENCE_TYPE && !parms)
-    {
-      if (complain & tf_error)
-       error ("invalid value-initialization of reference type");
-      return error_mark_node;
-    }
-
   if (processing_template_decl)
     {
-      tree t = build_min (CAST_EXPR, type, parms);
+      tree t;
+
+      /* Diagnose this even in a template.  We could also try harder
+        to give all the usual errors when the type and args are
+        non-dependent...  */
+      if (TREE_CODE (type) == REFERENCE_TYPE && !parms)
+       {
+         if (complain & tf_error)
+           error ("invalid value-initialization of reference type");
+         return error_mark_node;
+       }
+
+      t = build_min (CAST_EXPR, type, parms);
       /* We don't know if it will or will not have side effects.  */
       TREE_SIDE_EFFECTS (t) = 1;
       return t;