]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/11946
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Aug 2003 07:06:47 +0000 (07:06 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Aug 2003 07:06:47 +0000 (07:06 +0000)
* convert.c (convert_to_integer): Use CONVERT_EXPR (instead of
NOP_EXPR) when necessary.
* c-common.c (c_common_signed_or_unsigned_type): Correctly handle
types with precisions other than those given by native machine
modes.

PR c++/11684
* cp-tree.h (grok_op_properties): Change prototype.
* decl.c (grok_op_properties): Add complain parameter.
(grokfndecl): Pass it.
* pt.c (tsubst_decl): Adjust accordingly.

PR c++/10926
* decl.c (start_method): Return immediately if push_template_decl
does not like the declaration.
* pt.c (push_template_decl_real): Disallow member template
destructors.

PR c++/11036.C
* cp-tree.h (add_binding): Add prototype.
* class.c (add_method): Set TYPE_HAS_DESTRUCTOR if appropriate.
(maybe_warn_about_overly_private_class): Use
CLASSTYPE_DESTRUCTORS.
(pushclass): Adjust call to set_identifier_type_value.
* decl.c (add_binding): Give it external linkage.
(push_local_binding): Adjust call to add_binding.
(push_class_binding): Likewise.
(set_identifier_type_value_with_scope): Change prototype.  Use
add_binding for global bindings.
(set_identifier_type_value): Adjust accordingly.
(pushtag): Likewise.
(pushdecl): Use set_identifier_type_value, not
set_identifier_type_value_with_scope.
(pushdecl_namespace_level): Adjust calls to
SET_IDENTIFIER_TYPE_VALUE to pass a DECL.
(pushdecl_class_level): Likewise.
(lookup_tag): Use select_decl.
(select_decl): Improve comment.
(record_builtin_type): Do not call pushdecl.
(cxx_init_decl_processing): Do not call xref_tag for bad_alloc.
(cp_finish_decl): Adjust call to set_identifier_type_value.
(check_elaborated_type_specifier): Improve checks for invalid uses
of typedefs.
(xref_tag): Adjust call to check_elaborated_type_specifier.
* decl2.c (grokclassfn): Do not set TYPE_HAS_DESTRUCTOR.
* name-lookup.c (set_namespace_binding): Use add_binding.
* parser.c (cp_parser_simple_type_specifier): Return a TYPE_DECL,
rather than an IDENTIFIER_NODE, to represent built-in types, if
requested by the caller.
(cp_parser_postfix_expression): Adjust call.
(cp_parser_type_specifier): Likewise.
(cp_parser_elaborated_type_specifier): Adjust call to
check_elaborated_type_specifier.
* typeck2.c (build_functional_cast): Do not perform name lookups.

PR c++/10717
* decl.c (expand_static_init): Remove unncessary code.

PR c++/10926
* g++.dg/template/dtor2.C: New test.

PR c++/11684
* g++.dg/template/operator1.C: New test.
* g++.dg/parse/operator4.C: New test.

PR c++/11946.C
* g++.dg/expr/enum1.C: New test.
* gcc.dg/c99-bool-1.c: Remove bogus warning.

PR c++/11036.C
* g++.dg/parse/elab2.C: New test.
* g++.dg/parse/typedef4.C: Change error message.
* g++.old-deja/g++.robertl/eb133.C: Remove bogus error markers.
* g++.old-deja/g++.robertl/eb133a.C: Remove bogus error markers.
* g++.old-deja/g++.robertl/eb133b.C: Remove bogus error markers.

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

24 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/config/pa/pa.h
gcc/convert.c
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/enum1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/elab2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/operator4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/typedef4.C
gcc/testsuite/g++.dg/template/dtor2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/operator1.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.robertl/eb133.C
gcc/testsuite/g++.old-deja/g++.robertl/eb133a.C
gcc/testsuite/g++.old-deja/g++.robertl/eb133b.C
gcc/testsuite/gcc.dg/c99-bool-1.c

index ee82ca1e5e5ec58eef88f4fef2ea3d6f4e11a8f3..bd92e1966de6fa45055ecacd4d95057e2c39d197 100644 (file)
@@ -1,3 +1,12 @@
+2003-08-19  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/11946
+       * convert.c (convert_to_integer): Use CONVERT_EXPR (instead of
+       NOP_EXPR) when necessary.
+       * c-common.c (c_common_signed_or_unsigned_type): Correctly handle
+       types with precisions other than those given by native machine
+       modes.
+
 2003-08-19  Geoffrey Keating  <geoffk@apple.com>
 
        * cpppch.c (cpp_valid_state): Re-add warning about PCH not used
index 3089e5dbed8ab40b0bc393e558771111f172d20e..8f9e0bfb5fcd76ebe462428f75a97318f4d84109 100644 (file)
@@ -1969,6 +1969,8 @@ c_common_signed_type (tree type)
 tree
 c_common_signed_or_unsigned_type (int unsignedp, tree type)
 {
+  tree new_type;
+
   if (! INTEGRAL_TYPE_P (type)
       || TREE_UNSIGNED (type) == unsignedp)
     return type;
@@ -2001,7 +2003,14 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
   if (TYPE_PRECISION (type) == TYPE_PRECISION (intQI_type_node))
     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
 
-  return type;
+  new_type = (unsignedp 
+             ? make_unsigned_type (TYPE_PRECISION (type))
+             : make_signed_type (TYPE_PRECISION (type)));
+  TYPE_SIZE (new_type) = TYPE_SIZE (type);
+  TYPE_SIZE_UNIT (new_type) = TYPE_SIZE_UNIT (type);
+  TYPE_MODE (new_type) = TYPE_MODE (type);
+
+  return new_type;
 }
 \f
 /* Return the minimum number of bits needed to represent VALUE in a
index 5293c7cbc219ead3023bfb3f672ce2c11a611a62..1f281d5ba1b96249a16d460cd2237308a63d485a 100644 (file)
@@ -654,10 +654,14 @@ extern struct rtx_def *hppa_pic_save_rtx PARAMS ((void));
     && REGNO (IN) < FIRST_PSEUDO_REGISTER)                     \
    ? NO_REGS : secondary_reload_class (CLASS, MODE, IN))
 
+#define MAYBE_FP_REG_CLASS_P(CLASS) \
+  reg_classes_intersect_p ((CLASS), FP_REGS)
+
 /* On the PA it is not possible to directly move data between
    GENERAL_REGS and FP_REGS.  */
-#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE)  \
-  (FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2))
+#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE)          \
+  (MAYBE_FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2)    \
+   || MAYBE_FP_REG_CLASS_P (CLASS2) != FP_REG_CLASS_P (CLASS1))
 
 /* Return the stack location to use for secondary memory needed reloads.  */
 #define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
index 5bab1c19d3561b0224bfcf46a51946bd205cd660..0d3a46c05d4bb86068856d41fb183d34146058d6 100644 (file)
@@ -349,7 +349,27 @@ convert_to_integer (tree type, tree expr)
         we are truncating EXPR.  */
 
       else if (outprec >= inprec)
-       return build1 (NOP_EXPR, type, expr);
+       {
+         enum tree_code code;
+
+         /* If the precision of the EXPR's type is K bits and the
+            destination mode has more bits, and the sign is changing,
+            it is not safe to use a NOP_EXPR.  For example, suppose
+            that EXPR's type is a 3-bit unsigned integer type, the
+            TYPE is a 3-bit signed integer type, and the machine mode
+            for the types is 8-bit QImode.  In that case, the
+            conversion necessitates an explicit sign-extension.  In
+            the signed-to-unsigned case the high-order bits have to
+            be cleared.  */
+         if (TREE_UNSIGNED (type) != TREE_UNSIGNED (TREE_TYPE (expr))
+             && (TYPE_PRECISION (TREE_TYPE (expr))
+                 != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
+           code = CONVERT_EXPR;
+         else
+           code = NOP_EXPR;
+
+         return build1 (code, type, expr);
+       }
 
       /* If TYPE is an enumeral type or a type with a precision less
         than the number of bits in its mode, do the conversion to the
index b5ed58ff1853ef34d3da2a574fa1c5a3a83764aa..fbb96a806e902d80a73815ff6e96ea0ebb0db633 100644 (file)
@@ -1,3 +1,57 @@
+2003-08-19  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/11684
+       * cp-tree.h (grok_op_properties): Change prototype.
+       * decl.c (grok_op_properties): Add complain parameter.
+       (grokfndecl): Pass it.
+       * pt.c (tsubst_decl): Adjust accordingly.
+
+       PR c++/10926
+       * decl.c (start_method): Return immediately if push_template_decl
+       does not like the declaration.
+       * pt.c (push_template_decl_real): Disallow member template
+       destructors.
+
+       PR c++/11036.C
+       * cp-tree.h (add_binding): Add prototype.
+       * class.c (add_method): Set TYPE_HAS_DESTRUCTOR if appropriate.
+       (maybe_warn_about_overly_private_class): Use
+       CLASSTYPE_DESTRUCTORS.
+       (pushclass): Adjust call to set_identifier_type_value.
+       * decl.c (add_binding): Give it external linkage.
+       (push_local_binding): Adjust call to add_binding.
+       (push_class_binding): Likewise.
+       (set_identifier_type_value_with_scope): Change prototype.  Use
+       add_binding for global bindings.
+       (set_identifier_type_value): Adjust accordingly.
+       (pushtag): Likewise.
+       (pushdecl): Use set_identifier_type_value, not
+       set_identifier_type_value_with_scope.
+       (pushdecl_namespace_level): Adjust calls to
+       SET_IDENTIFIER_TYPE_VALUE to pass a DECL.
+       (pushdecl_class_level): Likewise.
+       (lookup_tag): Use select_decl.
+       (select_decl): Improve comment.
+       (record_builtin_type): Do not call pushdecl.
+       (cxx_init_decl_processing): Do not call xref_tag for bad_alloc.
+       (cp_finish_decl): Adjust call to set_identifier_type_value.
+       (check_elaborated_type_specifier): Improve checks for invalid uses
+       of typedefs.
+       (xref_tag): Adjust call to check_elaborated_type_specifier.
+       * decl2.c (grokclassfn): Do not set TYPE_HAS_DESTRUCTOR.
+       * name-lookup.c (set_namespace_binding): Use add_binding.
+       * parser.c (cp_parser_simple_type_specifier): Return a TYPE_DECL,
+       rather than an IDENTIFIER_NODE, to represent built-in types, if
+       requested by the caller.
+       (cp_parser_postfix_expression): Adjust call.
+       (cp_parser_type_specifier): Likewise.
+       (cp_parser_elaborated_type_specifier): Adjust call to
+       check_elaborated_type_specifier.
+       * typeck2.c (build_functional_cast): Do not perform name lookups.
+       
+       PR c++/10717
+       * decl.c (expand_static_init): Remove unncessary code.
+
 2003-08-19  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR c++/10538, PR c/5582
index a224676ea957abe2b0bb122f1bbb8efc52139fa6..302b714f30c0a719fa2934155419d04e79b1daa8 100644 (file)
@@ -750,7 +750,10 @@ add_method (tree type, tree method, int error_p)
   if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method))
     slot = CLASSTYPE_CONSTRUCTOR_SLOT;
   else if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
-    slot = CLASSTYPE_DESTRUCTOR_SLOT;
+    {
+      slot = CLASSTYPE_DESTRUCTOR_SLOT;
+      TYPE_HAS_DESTRUCTOR (type) = 1;
+    }
   else
     {
       int have_template_convs_p = 0;
@@ -1646,16 +1649,12 @@ maybe_warn_about_overly_private_class (tree t)
   /* Even if some of the member functions are non-private, the class
      won't be useful for much if all the constructors or destructors
      are private: such an object can never be created or destroyed.  */
-  if (TYPE_HAS_DESTRUCTOR (t))
+  if (TYPE_HAS_DESTRUCTOR (t)
+      && TREE_PRIVATE (CLASSTYPE_DESTRUCTORS (t)))
     {
-      tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1);
-
-      if (TREE_PRIVATE (dtor))
-       {
-         warning ("`%#T' only defines a private destructor and has no friends",
-                     t);
-         return;
-       }
+      warning ("`%#T' only defines a private destructor and has no friends",
+              t);
+      return;
     }
 
   if (TYPE_HAS_CONSTRUCTOR (t))
@@ -5485,7 +5484,7 @@ pushclass (tree type)
          
          push_class_binding (id, decl);
          if (TREE_CODE (decl) == TYPE_DECL)
-           set_identifier_type_value (id, TREE_TYPE (decl));
+           set_identifier_type_value (id, decl);
        }
       unuse_fields (type);
     }
index 43655b570f4ab505511b270cb52703d141ce0ad6..396dc0fe0d4982b9fcbc92a8e751bf35baf08d7f 100644 (file)
@@ -3695,7 +3695,7 @@ extern int copy_fn_p                              (tree);
 extern tree get_scope_of_declarator             (tree);
 extern void grok_special_member_properties     (tree);
 extern int grok_ctor_properties                        (tree, tree);
-extern void grok_op_properties                 (tree, int);
+extern bool grok_op_properties                 (tree, int, bool);
 extern tree xref_tag                           (enum tag_types, tree, tree, bool, bool);
 extern tree xref_tag_from_type                 (tree, tree, int);
 extern void xref_basetypes                     (tree, tree);
@@ -3744,6 +3744,7 @@ extern void register_dtor_fn                    (tree);
 extern tmpl_spec_kind current_tmpl_spec_kind    (int);
 extern tree cp_fname_init                      (const char *);
 extern tree check_elaborated_type_specifier     (enum tag_types, tree, bool);
+extern int add_binding                          (cxx_binding *, tree);
 extern bool have_extern_spec;
 
 /* in decl2.c */
index 5593796773c7f6ab3f1682efa54ca00a14338d55..1a4dcb2537f4246abf5d015e2b9268d14ce71b96 100644 (file)
@@ -92,7 +92,6 @@ static void check_for_uninitialized_const_var (tree);
 static hashval_t typename_hash (const void *);
 static int typename_compare (const void *, const void *);
 static void push_binding (tree, tree, struct cp_binding_level*);
-static int add_binding (tree, tree);
 static void pop_binding (tree, tree);
 static tree local_variable_p_walkfn (tree *, int *, void *);
 static tree select_decl (cxx_binding *, int);
@@ -918,10 +917,10 @@ push_binding (tree id, tree decl, cxx_scope* level)
    bound at the same level as some other kind of entity.  It's the
    responsibility of the caller to check that inserting this name is
    valid here.  Returns nonzero if the new binding was successful.  */
-static int
-add_binding (tree id, tree decl)
+
+int
+add_binding (cxx_binding *binding, tree decl)
 {
-  cxx_binding *binding = IDENTIFIER_BINDING (id);
   tree bval = BINDING_VALUE (binding);
   int ok = 1;
 
@@ -1041,7 +1040,7 @@ push_local_binding (tree id, tree decl, int flags)
   if (lookup_name_current_level (id))
     {
       /* Supplement the existing binding.  */
-      if (!add_binding (id, decl))
+      if (!add_binding (IDENTIFIER_BINDING (id), decl))
        /* It didn't work.  Something else must be bound at this
           level.  Do not add DECL to the list of things to pop
           later.  */
@@ -1080,7 +1079,7 @@ push_class_binding (tree id, tree decl)
 
   if (binding && BINDING_SCOPE (binding) == class_binding_level)
     /* Supplement the existing binding.  */
-    result = add_binding (id, decl);
+    result = add_binding (IDENTIFIER_BINDING (id), decl);
   else
     /* Create a new binding.  */
     push_binding (id, decl, class_binding_level);
@@ -2310,24 +2309,17 @@ pop_from_top_level (void)
   timevar_pop (TV_NAME_LOOKUP);
 }
 \f
-/* Push a definition of struct, union or enum tag "name".
-   into binding_level "b".   "type" should be the type node,
-   We assume that the tag "name" is not already defined.
-
-   Note that the definition may really be just a forward reference.
-   In that case, the TYPE_SIZE will be a NULL_TREE.
-
-   C++ gratuitously puts all these tags in the name space.  */
-
-/* When setting the IDENTIFIER_TYPE_VALUE field of an identifier ID,
-   record the shadowed value for this binding contour.  TYPE is
-   the type that ID maps to.  */
+/* Push a definition of struct, union or enum tag named ID.  into
+   binding_level B.  DECL is a TYPE_DECL for the type.  We assume that
+   the tag ID is not already defined.  */
 
 static void
 set_identifier_type_value_with_scope (tree id, 
-                                      tree type, 
+                                      tree decl,
                                       struct cp_binding_level* b)
 {
+  tree type;
+
   if (!b->namespace_p)
     {
       /* Shadow the marker, not the real thing, so that the marker
@@ -2335,12 +2327,21 @@ set_identifier_type_value_with_scope (tree id,
       tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
       b->type_shadowed
        = tree_cons (id, old_type_value, b->type_shadowed);
+      type = decl ? TREE_TYPE (decl) : NULL_TREE;
     }
   else
     {
       cxx_binding *binding =
-         binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
-      BINDING_TYPE (binding) = type;
+       binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
+      if (decl)
+       {
+         if (BINDING_VALUE (binding))
+           add_binding (binding, decl);
+         else
+           BINDING_VALUE (binding) = decl;
+       }
+      else
+       abort ();
       /* Store marker instead of real type.  */
       type = global_type_node;
     }
@@ -2350,9 +2351,9 @@ set_identifier_type_value_with_scope (tree id,
 /* As set_identifier_type_value_with_scope, but using current_binding_level.  */
 
 void
-set_identifier_type_value (tree id, tree type)
+set_identifier_type_value (tree id, tree decl)
 {
-  set_identifier_type_value_with_scope (id, type, current_binding_level);
+  set_identifier_type_value_with_scope (id, decl, current_binding_level);
 }
 
 /* Return the type associated with id.  */
@@ -2586,7 +2587,7 @@ pushtag (tree name, tree type, int globalize)
          d = create_implicit_typedef (name, type);
          DECL_CONTEXT (d) = FROB_CONTEXT (context);
          if (! in_class)
-           set_identifier_type_value_with_scope (name, type, b);
+           set_identifier_type_value_with_scope (name, d, b);
 
          d = maybe_process_template_type_declaration (type,
                                                       globalize, b);
@@ -3852,9 +3853,7 @@ pushdecl (tree x)
          if (type != error_mark_node
              && TYPE_NAME (type)
              && TYPE_IDENTIFIER (type))
-            set_identifier_type_value_with_scope (DECL_NAME (x), type,
-                                                 current_binding_level);
-
+            set_identifier_type_value (DECL_NAME (x), x);
        }
 
       /* Multiple external decls of the same identifier ought to match.
@@ -3944,15 +3943,13 @@ pushdecl (tree x)
 
          /* If this is a TYPE_DECL, push it into the type value slot.  */
          if (TREE_CODE (x) == TYPE_DECL)
-           set_identifier_type_value_with_scope (name, TREE_TYPE (x),
-                                                 current_binding_level);
+           set_identifier_type_value (name, x);
 
          /* Clear out any TYPE_DECL shadowed by a namespace so that
             we won't think this is a type.  The C struct hack doesn't
             go through namespaces.  */
          if (TREE_CODE (x) == NAMESPACE_DECL)
-           set_identifier_type_value_with_scope (name, NULL_TREE,
-                                                 current_binding_level);
+           set_identifier_type_value (name, NULL_TREE);
 
          if (oldlocal)
            {
@@ -4133,7 +4130,7 @@ pushdecl_namespace_level (tree x)
         {
           /* @@ This shouldn't be needed.  My test case "zstring.cc" trips
              up here if this is changed to an assertion.  --KR  */
-         SET_IDENTIFIER_TYPE_VALUE (name, newval);
+         SET_IDENTIFIER_TYPE_VALUE (name, x);
        }
       else
         {
@@ -4196,7 +4193,7 @@ pushdecl_class_level (tree x)
     {
       is_valid = push_class_level_binding (name, x);
       if (TREE_CODE (x) == TYPE_DECL)
-       set_identifier_type_value (name, TREE_TYPE (x));
+       set_identifier_type_value (name, x);
     }
   else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))
     {
@@ -5192,9 +5189,9 @@ lookup_tag (enum tree_code form, tree name,
            if (thislevel_only && !allow_template_parms_p
                && binding && BINDING_VALUE (binding)
                && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (binding)))
-             old = TREE_TYPE (BINDING_VALUE (binding));
+             old = BINDING_VALUE (binding);
            else if (binding)
-             old = BINDING_TYPE (binding);
+             old = select_decl (binding, LOOKUP_PREFER_TYPES);
             else
               old = NULL_TREE;
 
@@ -5203,6 +5200,7 @@ lookup_tag (enum tree_code form, tree name,
                /* We've found something at this binding level.  If it is
                   a typedef, extract the tag it refers to.  Lookup fails
                   if the typedef doesn't refer to a taggable type.  */
+               old = TREE_TYPE (old);
                old = follow_tag_typedef (old);
                if (!old)
                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
@@ -5645,12 +5643,11 @@ select_decl (cxx_binding *binding, int flags)
       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
     }
 
-  /* If we could have a type and
-     we have nothing or we need a type and have none.  */
-  if (BINDING_TYPE (binding)
-      && (!val || ((flags & LOOKUP_PREFER_TYPES)
-                   && TREE_CODE (val) != TYPE_DECL)))
-    val = TYPE_STUB_DECL (BINDING_TYPE (binding));
+  /* If looking for a type, or if there is no non-type binding, select
+     the value binding.  */
+  if (BINDING_TYPE (binding) 
+      && (!val || (flags & LOOKUP_PREFER_TYPES)))
+    val = BINDING_TYPE (binding);
   /* Don't return non-types if we really prefer types.  */
   else if (val && LOOKUP_TYPES_ONLY (flags)  && TREE_CODE (val) != TYPE_DECL
           && (TREE_CODE (val) != TEMPLATE_DECL
@@ -6045,9 +6042,9 @@ lookup_type_current_level (tree name)
 
 \f
 /* Push the declarations of builtin types into the namespace.
-   RID_INDEX is the index of the builtin type
-   in the array RID_POINTERS.  NAME is the name used when looking
-   up the builtin type.  TYPE is the _TYPE node for the builtin type.  */
+   RID_INDEX is the index of the builtin type in the array
+   RID_POINTERS.  NAME is the name used when looking up the builtin
+   type.  TYPE is the _TYPE node for the builtin type.  */
 
 void
 record_builtin_type (enum rid rid_index, 
@@ -6062,27 +6059,30 @@ record_builtin_type (enum rid rid_index,
   if (name)
     tname = get_identifier (name);
 
+  /* The calls to SET_IDENTIFIER_GLOBAL_VALUE below should be
+     eliminated.  Built-in types should not be looked up name; their
+     names are keywords that the parser can recognize.  However, there
+     is code in c-common.c that uses identifier_global_value to look
+     up built-in types by name.  */
   if (tname)
     {
-      tdecl = pushdecl (build_decl (TYPE_DECL, tname, type));
-      set_identifier_type_value (tname, NULL_TREE);
-      if ((int) rid_index < (int) RID_MAX)
-       /* Built-in types live in the global namespace.  */
+      tdecl = build_decl (TYPE_DECL, tname, type);
+      DECL_ARTIFICIAL (tdecl) = 1;
+      if (tname)
        SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl);
     }
-  if (rname != NULL_TREE)
+  if (rname)
     {
-      if (tname != NULL_TREE)
-       {
-         set_identifier_type_value (rname, NULL_TREE);
-         SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl);
-       }
-      else
+      if (!tdecl)
        {
-         tdecl = pushdecl (build_decl (TYPE_DECL, rname, type));
-         set_identifier_type_value (rname, NULL_TREE);
+         tdecl = build_decl (TYPE_DECL, rname, type);
+         DECL_ARTIFICIAL (tdecl) = 1;
        }
+      SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl);
     }
+
+  if (!TYPE_NAME (type))
+    TYPE_NAME (type) = tdecl;
 }
 
 /* Record one of the standard Java types.
@@ -6334,14 +6334,22 @@ cxx_init_decl_processing (void)
   current_lang_name = lang_name_cplusplus;
 
   {
-    tree bad_alloc_type_node, newtype, deltype;
+    tree bad_alloc_id;
+    tree bad_alloc_type_node;
+    tree bad_alloc_decl;
+    tree newtype, deltype;
     tree ptr_ftype_sizetype;
 
     push_namespace (std_identifier);
-    bad_alloc_type_node 
-      = xref_tag (class_type, get_identifier ("bad_alloc"), 
-                 /*attributes=*/NULL_TREE, true, false);
+    bad_alloc_id = get_identifier ("bad_alloc");
+    bad_alloc_type_node = make_aggr_type (RECORD_TYPE);
+    TYPE_CONTEXT (bad_alloc_type_node) = current_namespace;
+    bad_alloc_decl 
+      = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node);
+    DECL_CONTEXT (bad_alloc_decl) = current_namespace;
+    TYPE_STUB_DECL (bad_alloc_type_node) = bad_alloc_decl;
     pop_namespace ();
     ptr_ftype_sizetype 
       = build_function_type (ptr_type_node,
                             tree_cons (NULL_TREE,
@@ -8064,7 +8072,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
        {
          if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type)
            warning ("shadowing previous type declaration of `%#D'", decl);
-         set_identifier_type_value (DECL_NAME (decl), type);
+         set_identifier_type_value (DECL_NAME (decl), decl);
        }
 
       /* If we have installed this as the canonical typedef for this
@@ -8495,8 +8503,6 @@ register_dtor_fn (tree decl)
 static void
 expand_static_init (tree decl, tree init)
 {
-  tree oldstatic;
-
   my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 20021010);
   my_friendly_assert (TREE_STATIC (decl), 20021010);
 
@@ -8506,14 +8512,7 @@ expand_static_init (tree decl, tree init)
       && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
     return;
 
-  oldstatic = value_member (decl, static_aggregates);
-
-  if (oldstatic)
-    {
-      if (TREE_PURPOSE (oldstatic) && init != NULL_TREE)
-       error ("multiple initializations given for `%D'", decl);
-    }
-  else if (! toplevel_bindings_p ())
+  if (! toplevel_bindings_p ())
     {
       /* Emit code to perform this initialization but once.  */
       tree if_stmt;
@@ -8901,7 +8900,7 @@ grokfndecl (tree ctype,
     }
 
   if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)))
-    grok_op_properties (decl, friendp);
+    grok_op_properties (decl, friendp, /*complain=*/true);
 
   if (ctype && decl_function_context (decl))
     DECL_NO_STATIC_CHAIN (decl) = 1;
@@ -12184,10 +12183,12 @@ unary_op_p (enum tree_code code)
          || code == TYPE_EXPR);
 }
 
-/* Do a little sanity-checking on how they declared their operator.  */
+/* DECL is a declaration for an overloaded operator.  Returns true if
+   the declaration is valid; false otherwise.  If COMPLAIN is true,
+   errors are issued for invalid declarations.  */
 
-void
-grok_op_properties (tree decl, int friendp)
+bool
+grok_op_properties (tree decl, int friendp, bool complain)
 {
   tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
   tree argtype;
@@ -12195,6 +12196,10 @@ grok_op_properties (tree decl, int friendp)
   tree name = DECL_NAME (decl);
   enum tree_code operator_code;
   int arity;
+  bool ok;
+
+  /* Assume that the declaration is valid.  */
+  ok = true;
 
   /* Count the number of arguments.  */
   for (argtype = argtypes, arity = 0;
@@ -12288,33 +12293,38 @@ grok_op_properties (tree decl, int friendp)
            error ("`%D' must be a nonstatic member function", decl);
          else
            {
-             tree p = argtypes;
+             tree p;
 
              if (DECL_STATIC_FUNCTION_P (decl))
                error ("`%D' must be either a non-static member function or a non-member function", decl);
 
-             if (p)
-               for (; TREE_CODE (TREE_VALUE (p)) != VOID_TYPE ; p = TREE_CHAIN (p))
-                 {
-                   tree arg = non_reference (TREE_VALUE (p));
-
-                   /* This lets bad template code slip through.  */
-                   if (IS_AGGR_TYPE (arg)
-                       || TREE_CODE (arg) == ENUMERAL_TYPE
-                       || TREE_CODE (arg) == TEMPLATE_TYPE_PARM
-                       || TREE_CODE (arg) == BOUND_TEMPLATE_TEMPLATE_PARM)
-                     goto foundaggr;
-                 }
-             error
-               ("`%D' must have an argument of class or enumerated type",
-                decl);
-           foundaggr:
-             ;
+             for (p = argtypes; p && p != void_list_node; p = TREE_CHAIN (p))
+               {
+                 tree arg = non_reference (TREE_VALUE (p));
+                 /* IS_AGGR_TYPE, rather than CLASS_TYPE_P, is used
+                    because these checks are performed even on
+                    template functions.  */
+                 if (IS_AGGR_TYPE (arg) || TREE_CODE (arg) == ENUMERAL_TYPE)
+                   break;
+               }
+
+             if (!p || p == void_list_node)
+               {
+                 if (!complain)
+                   return false;
+
+                 error ("`%D' must have an argument of class or "
+                        "enumerated type",
+                        decl);
+                 ok = false;
+               }
            }
        }
 
+      /* There are no restrictions on the arguments to an overloaded
+        "operator ()".  */
       if (operator_code == CALL_EXPR)
-       return;                 /* No restrictions on args.  */
+       return ok;
 
       if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
        {
@@ -12497,6 +12507,8 @@ grok_op_properties (tree decl, int friendp)
           }
 
     }
+
+  return ok;
 }
 \f
 static const char *
@@ -12518,45 +12530,61 @@ tag_name (enum tag_types code)
 }
 
 /* Name lookup in an elaborated-type-specifier (after the keyword
-   indicated by TAG_CODE) has found TYPE.  If the
+   indicated by TAG_CODE) has found the TYPE_DECL DECL.  If the
    elaborated-type-specifier is invalid, issue a diagnostic and return
-   error_mark_node; otherwise, return TYPE itself.  
+   error_mark_node; otherwise, return the *_TYPE to which it referred.
    If ALLOW_TEMPLATE_P is true, TYPE may be a class template.  */
 
 tree
 check_elaborated_type_specifier (enum tag_types tag_code,
-                                tree type,
+                                tree decl,
                                 bool allow_template_p)
 {
-  tree t = follow_tag_typedef (type);
+  tree type;
 
-  /* [dcl.type.elab] If the identifier resolves to a typedef-name or a
-     template type-parameter, the elaborated-type-specifier is
-     ill-formed.  */
-  if (!t)
+  /* In the case of:
+
+       struct S { struct S *p; };
+
+     name lookup will find the TYPE_DECL for the implicit "S::S"
+     typedef.  Adjust for that here.  */
+  if (DECL_SELF_REFERENCE_P (decl))
+    decl = TYPE_NAME (TREE_TYPE (decl));
+
+  type = TREE_TYPE (decl);
+
+  /*   [dcl.type.elab] 
+
+       If the identifier resolves to a typedef-name or a template
+       type-parameter, the elaborated-type-specifier is ill-formed.
+
+     In other words, the only legitimate declaration to use in the
+     elaborated type specifier is the implicit typedef created when
+     the type is declared.  */
+  if (!DECL_IMPLICIT_TYPEDEF_P (decl))
     {
-      error ("using typedef-name `%T' after `%s'",
-            type, tag_name (tag_code));
-      t = error_mark_node;
+      error ("using typedef-name `%D' after `%s'", decl, tag_name (tag_code));
+      return IS_AGGR_TYPE (type) ? type : error_mark_node;
     }
-  else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+    
+  if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
     {
       error ("using template type parameter `%T' after `%s'",
             type, tag_name (tag_code));
-      t = error_mark_node;
+      return error_mark_node;
     }
   else if (TREE_CODE (type) != RECORD_TYPE
           && TREE_CODE (type) != UNION_TYPE
           && tag_code != enum_type)
     {
       error ("`%T' referred to as `%s'", type, tag_name (tag_code));
-      t = error_mark_node;
+      return error_mark_node;
     }
   else if (TREE_CODE (type) != ENUMERAL_TYPE
           && tag_code == enum_type)
     {
       error ("`%T' referred to as enum", type);
-      t = error_mark_node;
+      return error_mark_node;
     }
   else if (!allow_template_p
           && TREE_CODE (type) == RECORD_TYPE
@@ -12573,10 +12601,10 @@ check_elaborated_type_specifier (enum tag_types tag_code,
       error ("template argument required for `%s %T'",
             tag_name (tag_code),
             DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)));
-      t = error_mark_node;
+      return error_mark_node;
     }
 
-  return t;
+  return type;
 }
 
 /* Get the struct, enum or union (TAG_CODE says which) with tag NAME.
@@ -12653,8 +12681,8 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
                 class C *c2;           // DECL_SELF_REFERENCE_P is true
               };  */
 
-         t = check_elaborated_type_specifier (tag_code, 
-                                              TREE_TYPE (decl),
+         t = check_elaborated_type_specifier (tag_code,
+                                              decl,
                                               template_header_p
                                               | DECL_SELF_REFERENCE_P (decl));
          if (t == error_mark_node)
@@ -14216,7 +14244,11 @@ start_method (tree declspecs, tree declarator, tree attrlist)
 
   /* We process method specializations in finish_struct_1.  */
   if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl))
-    fndecl = push_template_decl (fndecl);
+    {
+      fndecl = push_template_decl (fndecl);
+      if (fndecl == error_mark_node)
+       return fndecl;
+    }
 
   if (! DECL_FRIEND_P (fndecl))
     {
index ace4313f337bb4637d96a9a96ee4c47161532393..a38d993e0670b98aee60bf345041476e964f5d9e 100644 (file)
@@ -387,12 +387,6 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags, tree quals)
 
   if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))
     maybe_retrofit_in_chrg (function);
-
-  if (flags == DTOR_FLAG)
-    {
-      DECL_DESTRUCTOR_P (function) = 1;
-      TYPE_HAS_DESTRUCTOR (ctype) = 1;
-    }
 }
 
 /* Create an ARRAY_REF, checking for the user doing things backwards
index 1a1a431c7888aa1054e3f2bb2afd354cbb86b0bd..c07b5ff56bb0efa9a904564f2cbaba2e4921efb3 100644 (file)
@@ -377,7 +377,12 @@ set_namespace_binding (tree name, tree scope, tree val)
   if (scope == NULL_TREE)
     scope = global_namespace;
   b = binding_for_name (NAMESPACE_LEVEL (scope), name);
-  BINDING_VALUE (b) = val;
+  if (!BINDING_VALUE (b)
+      || TREE_CODE (val) == OVERLOAD 
+      || val == error_mark_node)
+    BINDING_VALUE (b) = val;
+  else
+    add_binding (b, val);
   timevar_pop (TV_NAME_LOOKUP);
 }
 
index 2e5e4dd54abb755de1be019c3cbe0c9e62a2a298..b2a111314634e15d1191b27d11e63ca25dae85b8 100644 (file)
@@ -1413,7 +1413,7 @@ static tree cp_parser_function_specifier_opt
 static tree cp_parser_type_specifier
   (cp_parser *, cp_parser_flags, bool, bool, int *, bool *);
 static tree cp_parser_simple_type_specifier
-  (cp_parser *, cp_parser_flags);
+  (cp_parser *, cp_parser_flags, bool);
 static tree cp_parser_type_name
   (cp_parser *);
 static tree cp_parser_elaborated_type_specifier
@@ -3361,7 +3361,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
        cp_parser_parse_tentatively (parser);
        /* Look for the simple-type-specifier.  */
        type = cp_parser_simple_type_specifier (parser, 
-                                               CP_PARSER_FLAGS_NONE);
+                                               CP_PARSER_FLAGS_NONE,
+                                               /*identifier_p=*/false);
        /* Parse the cast itself.  */
        if (!cp_parser_error_occurred (parser))
          postfix_expression 
@@ -8181,7 +8182,8 @@ cp_parser_type_specifier (cp_parser* parser,
 
   /* If we do not already have a type-specifier, assume we are looking
      at a simple-type-specifier.  */
-  type_spec = cp_parser_simple_type_specifier (parser, flags);
+  type_spec = cp_parser_simple_type_specifier (parser, flags, 
+                                              /*identifier_p=*/true);
 
   /* If we didn't find a type-specifier, and a type-specifier was not
      optional in this context, issue an error message.  */
@@ -8218,11 +8220,13 @@ cp_parser_type_specifier (cp_parser* parser,
      __typeof__ ( type-id )
 
    For the various keywords, the value returned is simply the
-   TREE_IDENTIFIER representing the keyword.  For the first two
-   productions, the value returned is the indicated TYPE_DECL.  */
+   TREE_IDENTIFIER representing the keyword if IDENTIFIER_P is true.
+   For the first two productions, and if IDENTIFIER_P is false, the
+   value returned is the indicated TYPE_DECL.  */
 
 static tree
-cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags)
+cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags,
+                                bool identifier_p)
 {
   tree type = NULL_TREE;
   cp_token *token;
@@ -8234,18 +8238,38 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags)
   switch (token->keyword)
     {
     case RID_CHAR:
+      type = char_type_node;
+      break;
     case RID_WCHAR:
+      type = wchar_type_node;
+      break;
     case RID_BOOL:
+      type = boolean_type_node;
+      break;
     case RID_SHORT:
+      type = short_integer_type_node;
+      break;
     case RID_INT:
+      type = integer_type_node;
+      break;
     case RID_LONG:
+      type = long_integer_type_node;
+      break;
     case RID_SIGNED:
+      type = integer_type_node;
+      break;
     case RID_UNSIGNED:
+      type = unsigned_type_node;
+      break;
     case RID_FLOAT:
+      type = float_type_node;
+      break;
     case RID_DOUBLE:
+      type = double_type_node;
+      break;
     case RID_VOID:
-      /* Consume the token.  */
-      return cp_lexer_consume_token (parser->lexer)->value;
+      type = void_type_node;
+      break;
 
     case RID_TYPEOF:
       {
@@ -8266,6 +8290,16 @@ cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags)
       break;
     }
 
+  /* If the type-specifier was for a built-in type, we're done.  */
+  if (type)
+    {
+      tree id;
+
+      /* Consume the token.  */
+      id = cp_lexer_consume_token (parser->lexer)->value;
+      return identifier_p ? id : TYPE_NAME (type);
+    }
+
   /* The type-specifier must be a user-defined type.  */
   if (!(flags & CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES)) 
     {
@@ -8549,8 +8583,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
 
          if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE)
            check_elaborated_type_specifier 
-             (tag_type, 
-              TREE_TYPE (decl),
+             (tag_type, decl,
               (parser->num_template_parameter_lists
                || DECL_SELF_REFERENCE_P (decl)));
 
index 083060329d26e2db6eb32893b7b63c852e9cdf6e..863ab86ad19b0810d6af49519f0287270f289226 100644 (file)
@@ -2674,6 +2674,15 @@ push_template_decl_real (tree decl, int is_friend)
       else if (TREE_CODE (decl) == TYPE_DECL 
               && ANON_AGGRNAME_P (DECL_NAME (decl))) 
        error ("template class without a name");
+      else if (TREE_CODE (decl) == FUNCTION_DECL
+              && DECL_DESTRUCTOR_P (decl))
+       {
+         /* [temp.mem]
+            
+             A destructor shall not be a member template.  */
+         error ("destructor `%D' declared as member template", decl);
+         return error_mark_node;
+       }
       else if ((DECL_IMPLICIT_TYPEDEF_P (decl)
                && CLASS_TYPE_P (TREE_TYPE (decl)))
               || (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx))
@@ -5996,7 +6005,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
              clone_function_decl (r, /*update_method_vec_p=*/0);
          }
        else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
-         grok_op_properties (r, DECL_FRIEND_P (r));
+         grok_op_properties (r, DECL_FRIEND_P (r),
+                             (complain & tf_error) != 0);
       }
       break;
 
index eac8dc156980f73a6224fd15d9b81bcc5eaaac7a..8b5af5ef4af7efa0974587e352f39bec08b15556 100644 (file)
@@ -1114,23 +1114,7 @@ build_functional_cast (tree exp, tree parms)
   if (exp == error_mark_node || parms == error_mark_node)
     return error_mark_node;
 
-  if (TREE_CODE (exp) == IDENTIFIER_NODE)
-    {
-      if (IDENTIFIER_HAS_TYPE_VALUE (exp))
-       /* Either an enum or an aggregate type.  */
-       type = IDENTIFIER_TYPE_VALUE (exp);
-      else
-       {
-         type = lookup_name (exp, 1);
-         if (!type || TREE_CODE (type) != TYPE_DECL)
-           {
-             error ("`%T' fails to be a typedef or built-in type", exp);
-             return error_mark_node;
-           }
-         type = TREE_TYPE (type);
-       }
-    }
-  else if (TREE_CODE (exp) == TYPE_DECL)
+  if (TREE_CODE (exp) == TYPE_DECL)
     type = TREE_TYPE (exp);
   else
     type = exp;
index 5554668228b7654be897e0f87a7826eb54f28d87..1020020022bffc2c93f576d82e5c2633f82e36cd 100644 (file)
@@ -1,3 +1,23 @@
+2003-08-19  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/10926
+       * g++.dg/template/dtor2.C: New test.
+
+       PR c++/11684
+       * g++.dg/template/operator1.C: New test.
+       * g++.dg/parse/operator4.C: New test.
+
+       PR c++/11946.C
+       * g++.dg/expr/enum1.C: New test.
+       * gcc.dg/c99-bool-1.c: Remove bogus warning.
+
+       PR c++/11036.C
+       * g++.dg/parse/elab2.C: New test.
+       * g++.dg/parse/typedef4.C: Change error message.
+       * g++.old-deja/g++.robertl/eb133.C: Remove bogus error markers.
+       * g++.old-deja/g++.robertl/eb133a.C: Remove bogus error markers.
+       * g++.old-deja/g++.robertl/eb133b.C: Remove bogus error markers.
+
 2003-08-19  Geoffrey Keating  <geoffk@apple.com>
 
        * gcc.dg/pch/warn-1.c: New.
diff --git a/gcc/testsuite/g++.dg/expr/enum1.C b/gcc/testsuite/g++.dg/expr/enum1.C
new file mode 100644 (file)
index 0000000..df2a823
--- /dev/null
@@ -0,0 +1,10 @@
+// { dg-do run }
+
+void abort();
+int main()
+{
+    enum { shelf = 4 } t = shelf;
+    if (!(t & shelf))
+       abort ();
+}
+
diff --git a/gcc/testsuite/g++.dg/parse/elab2.C b/gcc/testsuite/g++.dg/parse/elab2.C
new file mode 100644 (file)
index 0000000..69273a3
--- /dev/null
@@ -0,0 +1,7 @@
+struct A {};
+
+struct B
+{
+  typedef A T;
+  friend struct T; // { dg-error "" }
+};
diff --git a/gcc/testsuite/g++.dg/parse/operator4.C b/gcc/testsuite/g++.dg/parse/operator4.C
new file mode 100644 (file)
index 0000000..9395ccd
--- /dev/null
@@ -0,0 +1 @@
+int operator *(int, ...); // { dg-error "class" }
index 42d2f44d9200c6e557d063d578f9f3a1cfca4e67..03f709a184d17c05602d028226450328634c6a61 100644 (file)
@@ -8,5 +8,5 @@ template<class T> class smart_ptr2 {
     T* real_ptr;
  public:
     typedef typename T::subT  td;
-    friend class td; // { dg-error "typename|not name a class" }
+    friend class td; // { dg-error "typedef" }
 };
diff --git a/gcc/testsuite/g++.dg/template/dtor2.C b/gcc/testsuite/g++.dg/template/dtor2.C
new file mode 100644 (file)
index 0000000..04bea9c
--- /dev/null
@@ -0,0 +1,10 @@
+struct Foo
+{
+    template <int i>
+    ~Foo() {} // { dg-error "" }
+};
+
+int main()
+{
+   Foo f;
+}
diff --git a/gcc/testsuite/g++.dg/template/operator1.C b/gcc/testsuite/g++.dg/template/operator1.C
new file mode 100644 (file)
index 0000000..402e607
--- /dev/null
@@ -0,0 +1,49 @@
+class test
+{
+public:
+ float operator[]( int index )
+ {
+  return testFloat[index];
+ }
+private:
+ float testFloat[3];
+};
+
+template < class typeA > float
+operator*(
+ typeA a,
+ float b
+)
+{
+ return a[0] * b;
+}
+
+template < class typeB > float
+operator*(
+ float a,
+ typeB b
+)
+{
+ return a * b[0];
+}
+
+template < class typeA, class typeB > float
+operator*(
+ typeA a,
+ typeB b
+)
+{
+ return a[0] * b[0];
+}
+
+int main( void )
+{
+ test aTest;
+ float bTest;
+ float result;
+
+ result = aTest * bTest;
+ result = bTest * aTest;
+
+ return 0;
+}
index b6002248d558f01d3ee94a80d34fd3f2218c6f8f..419a36efd4be2052b8c80be8ba51c0f1eac6b32e 100644 (file)
@@ -3,15 +3,13 @@
 // From: Klaus-Georg Adams <Klaus-Georg.Adams@chemie.uni-karlsruhe.de> 
 // Reported against EGCS snaps 98/06/28.
 
-// { dg-error "forward declaration" "" { target *-*-* } 0 }
-
 using namespace std;
 
 int main()
 {
        try {
        }
-       catch (bad_alloc) { // { dg-error "invalid use" }
+       catch (bad_alloc) { // { dg-error "" }
                return 1;
        }
        return 0;
index f9265851d11c8b50edc23d19832f5e25703fe039..eb6c72d20a606fe709619ab92cb4d466dff7c366 100644 (file)
@@ -3,8 +3,6 @@
 // From: Klaus-Georg Adams <Klaus-Georg.Adams@chemie.uni-karlsruhe.de> 
 // Reported against EGCS snaps 98/06/28.
 
-// { dg-error "forward declaration" "" { target *-*-* } 0 }
-
 int main()
 {
        try {
index 82605146a191cb50e1f61b8fb78ea85911a9ecd3..9885031004b91e0c7ccc9cadd649b8e688cd3258 100644 (file)
@@ -3,15 +3,13 @@
 // From: Klaus-Georg Adams <Klaus-Georg.Adams@chemie.uni-karlsruhe.de> 
 // Reported against EGCS snaps 98/06/28.
 
-// { dg-error "forward declaration" "" { target *-*-* } 0 }
-
 using namespace std;
 
 int main()
 {
        try {
        }
-       catch (bad_alloc) { // { dg-error "invalid use" }
+       catch (bad_alloc) { // { dg-error "" }
                return 1;
        }
        return 0;
index 1037eb55173a8d843e19817aa99336375c0da55c..710219620b7e334b86ef12980be9fe13b14cbdd5 100644 (file)
@@ -228,9 +228,7 @@ main (void)
     abort ();
   if ((u |= 2) != 1)
     abort ();
-  /* ??? A bit queer, since this gets optimized to ((u = (u != 3)) != 1)
-     early in semantic analysis, which then yields the warning below.  */
-  if ((u ^= 3) != 1)   /* { dg-warning "always true due to limited range" } */
+  if ((u ^= 3) != 1)
     abort ();
   /* Test comma expressions.  */
   u = 1;