]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/cp/typeck2.c
typeck2.c (add_exception_specifier): Only require complete type if not in processing...
[gcc.git] / gcc / cp / typeck2.c
index d8143f88b9bc2742120a460e4c0e32e1efe76d28..5ba46111cc06a4bf3bf0ebd16f3be800552f24be 100644 (file)
@@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA.  */
 #include "flags.h"
 #include "toplev.h"
 #include "output.h"
+#include "diagnostic.h"
 
 static tree process_init_constructor PARAMS ((tree, tree, tree *));
 
@@ -261,11 +262,15 @@ friendly_abort (where, file, line, func)
      int line;
      const char *func;
 {
-  if (where > 0)
-    error ("Internal error #%d.", where);
+  if (errorcount > 0 || sorrycount > 0)
+    /* Say nothing.  */;
+  else if (where > 0)
+    {
+      error ("Internal error #%d.", where);
 
-  /* Uncount this error, so finish_abort will do the right thing.  */
-  --errorcount;
+      /* Uncount this error, so internal_error will do the right thing.  */
+      --errorcount;
+    }
 
   fancy_abort (file, line, func);
 }
@@ -466,6 +471,11 @@ digest_init (type, init, tail)
                                  && TREE_VALUE (init) == error_mark_node))
     return error_mark_node;
 
+  if (TREE_CODE (init) == ERROR_MARK)
+    /* __PRETTY_FUNCTION__'s initializer is a bogus expression inside
+       a template function. This gets substituted during instantiation. */
+    return init;
+  
   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
   if (TREE_CODE (init) == NON_LVALUE_EXPR)
     init = TREE_OPERAND (init, 0);
@@ -545,7 +555,7 @@ digest_init (type, init, tail)
 
   if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
       || code == ENUMERAL_TYPE || code == REFERENCE_TYPE
-      || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
+      || code == BOOLEAN_TYPE || code == COMPLEX_TYPE || code == VECTOR_TYPE
       || TYPE_PTRMEMFUNC_P (type))
     {
       if (raw_constructor)
@@ -581,7 +591,8 @@ digest_init (type, init, tail)
 
   if (code == ARRAY_TYPE || IS_AGGR_TYPE_CODE (code))
     {
-      if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type))
+      if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type)
+         && TREE_HAS_CONSTRUCTOR (init))
        {
          cp_error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
                    type, init);
@@ -809,12 +820,18 @@ process_init_constructor (type, init, elts)
                next1 = build_functional_cast (TREE_TYPE (field),
                                               NULL_TREE);
              else
-               next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE,
-                              NULL_TREE);
+               {
+                 next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE,
+                                NULL_TREE);
+                  if (init)
+                    TREE_HAS_CONSTRUCTOR (next1)
+                       = TREE_HAS_CONSTRUCTOR (init);
+                }
              next1 = digest_init (TREE_TYPE (field), next1, 0);
 
              /* Warn when some struct elements are implicitly initialized.  */
-             if (extra_warnings)
+             if (extra_warnings
+                 && (!init || TREE_HAS_CONSTRUCTOR (init)))
                cp_warning ("missing initializer for member `%D'", field);
            }
          else
@@ -830,7 +847,8 @@ process_init_constructor (type, init, elts)
 
              /* Warn when some struct elements are implicitly initialized
                 to zero.  */
-             if (extra_warnings)
+             if (extra_warnings
+                 && (!init || TREE_HAS_CONSTRUCTOR (init)))
                cp_warning ("missing initializer for member `%D'", field);
 
              /* The default zero-initialization is fine for us; don't
@@ -957,9 +975,10 @@ process_init_constructor (type, init, elts)
    the A part of the C object named by X.  In this case,
    DATUM would be x, and BASETYPE would be A.
 
-   Note that this is nonconformant; the standard specifies that first
-   we look up ii in A, then convert x to an L& and pull out the ii part.
-   But narrowing seems to be standard practice, so let's do it anyway.  */
+   I used to think that this was nonconformant, that the standard specified
+   that first we look up ii in A, then convert x to an L& and pull out the
+   ii part.  But in fact, it does say that we convert x to an A&; A here
+   is known as the "naming class".  (jason 2000-12-19) */
 
 tree
 build_scoped_ref (datum, basetype)
@@ -967,16 +986,10 @@ build_scoped_ref (datum, basetype)
      tree basetype;
 {
   tree ref;
-  tree type = TREE_TYPE (datum);
 
   if (datum == error_mark_node)
     return error_mark_node;
 
-  /* Don't do this if it would cause an error or if we're being pedantic.  */
-  if (! ACCESSIBLY_UNIQUELY_DERIVED_P (basetype, type)
-      || pedantic)
-    return datum;
-
   ref = build_unary_op (ADDR_EXPR, datum, 0);
   ref = convert_pointer_to (basetype, ref);
 
@@ -1051,7 +1064,7 @@ build_x_arrow (datum)
     last_rval = default_conversion (rval);
 
   if (TREE_CODE (TREE_TYPE (last_rval)) == POINTER_TYPE)
-    return build_indirect_ref (last_rval, NULL_PTR);
+    return build_indirect_ref (last_rval, NULL);
 
   if (types_memoized)
     error ("result of `operator->()' yields non-pointer result");
@@ -1086,6 +1099,10 @@ build_m_component_ref (datum, component)
     return build_min_nt (DOTSTAR_EXPR, datum, component);
 
   datum = decay_conversion (datum);
+
+  if (datum == error_mark_node || component == error_mark_node)
+    return error_mark_node;
+
   objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));  
 
   if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
@@ -1093,18 +1110,15 @@ build_m_component_ref (datum, component)
       type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component)));
       field_type = type;
     }
-  else
+  else if (TYPE_PTRMEM_P (TREE_TYPE (component)))
     {
       type = TREE_TYPE (TREE_TYPE (component));
       field_type = TREE_TYPE (type);
     }
-
-  if (datum == error_mark_node || component == error_mark_node)
-    return error_mark_node;
-
-  if (TREE_CODE (type) != OFFSET_TYPE && TREE_CODE (type) != METHOD_TYPE)
+  else
     {
-      cp_error ("`%E' cannot be used as a member pointer, since it is of type `%T'", component, type);
+      cp_error ("`%E' cannot be used as a member pointer, since it is of type `%T'", 
+               component, TREE_TYPE (component));
       return error_mark_node;
     }
 
@@ -1279,9 +1293,11 @@ add_exception_specifier (list, spec, complain)
     ok = is_ptr;
   else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)
     ok = 1;
+  else if (processing_template_decl)
+    ok = 1;
   else
     ok = COMPLETE_TYPE_P (complete_type (core));
-  
+
   if (ok)
     {
       tree probe;
@@ -1300,3 +1316,39 @@ add_exception_specifier (list, spec, complain)
     incomplete_type_error (NULL_TREE, core);
   return list;
 }
+
+/* Combine the two exceptions specifier lists LIST and ADD, and return
+   their union. */
+
+tree
+merge_exception_specifiers (list, add)
+     tree list, add;
+{
+  if (!list || !add)
+    return NULL_TREE;
+  else if (!TREE_VALUE (list))
+    return add;
+  else if (!TREE_VALUE (add))
+    return list;
+  else
+    {
+      tree orig_list = list;
+      
+      for (; add; add = TREE_CHAIN (add))
+        {
+          tree spec = TREE_VALUE (add);
+          tree probe;
+          
+          for (probe = orig_list; probe; probe = TREE_CHAIN (probe))
+            if (same_type_p (TREE_VALUE (probe), spec))
+              break;
+          if (!probe)
+            {
+              spec = build_tree_list (NULL_TREE, spec);
+              TREE_CHAIN (spec) = list;
+              list = spec;
+            }
+        }
+    }
+  return list;
+}
This page took 0.034223 seconds and 5 git commands to generate.