re PR c++/11946 (fun and merriment with enums as function arguments)
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. 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. From-SVN: r70593
This commit is contained in:
parent
ccc014442a
commit
4b0d3cbe3e
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* Return the minimum number of bits needed to represent VALUE in a
|
||||
|
@ -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) \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
260
gcc/cp/decl.c
260
gcc/cp/decl.c
@ -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);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
|
||||
|
||||
/* 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)
|
||||
if (!tdecl)
|
||||
{
|
||||
set_identifier_type_value (rname, NULL_TREE);
|
||||
SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl);
|
||||
}
|
||||
else
|
||||
{
|
||||
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));
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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:
|
||||
;
|
||||
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;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)));
|
||||
|
||||
|
12
gcc/cp/pt.c
12
gcc/cp/pt.c
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
10
gcc/testsuite/g++.dg/expr/enum1.C
Normal file
10
gcc/testsuite/g++.dg/expr/enum1.C
Normal file
@ -0,0 +1,10 @@
|
||||
// { dg-do run }
|
||||
|
||||
void abort();
|
||||
int main()
|
||||
{
|
||||
enum { shelf = 4 } t = shelf;
|
||||
if (!(t & shelf))
|
||||
abort ();
|
||||
}
|
||||
|
7
gcc/testsuite/g++.dg/parse/elab2.C
Normal file
7
gcc/testsuite/g++.dg/parse/elab2.C
Normal file
@ -0,0 +1,7 @@
|
||||
struct A {};
|
||||
|
||||
struct B
|
||||
{
|
||||
typedef A T;
|
||||
friend struct T; // { dg-error "" }
|
||||
};
|
1
gcc/testsuite/g++.dg/parse/operator4.C
Normal file
1
gcc/testsuite/g++.dg/parse/operator4.C
Normal file
@ -0,0 +1 @@
|
||||
int operator *(int, ...); // { dg-error "class" }
|
@ -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" }
|
||||
};
|
||||
|
10
gcc/testsuite/g++.dg/template/dtor2.C
Normal file
10
gcc/testsuite/g++.dg/template/dtor2.C
Normal file
@ -0,0 +1,10 @@
|
||||
struct Foo
|
||||
{
|
||||
template <int i>
|
||||
~Foo() {} // { dg-error "" }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Foo f;
|
||||
}
|
49
gcc/testsuite/g++.dg/template/operator1.C
Normal file
49
gcc/testsuite/g++.dg/template/operator1.C
Normal file
@ -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;
|
||||
}
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user