aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog23
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/decl2.c16
-rw-r--r--gcc/cp/parser.c104
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/overload/prom1.C9
-rw-r--r--gcc/testsuite/g++.dg/parse/dtor2.C4
-rw-r--r--gcc/testsuite/g++.dg/parse/using2.C8
8 files changed, 127 insertions, 50 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8ef1aeb..ec4f444 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,26 @@
+2003-08-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11551
+ * parser.c (cp_parser_id_expression): Add declarator_p parameter.
+ (cp_parser_primary_expression): Adjust call to
+ cp_parser_id_expression.
+ (cp_parser_unqualified_id): Complain about the use of
+ typedef-names in a destructor declarator.
+ (cp_parser_postfix_expression): Adjust call to
+ cp_parser_id_expression.
+ (cp_parser_type_parameter): Likewise.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_declarator_id): Likewise.
+
+ PR c++/11919
+ * call.c (standard_conversion): Use same_type_p, not pointer
+ equality, to compare types.
+
+ PR c++/10762
+ * parser.c (cp_parser_using_declaration): Check for invalid uses
+ of template-ids here...
+ * decl2.c (do_class_using_decl): ... rather than here.
+
2003-08-20 Mark Mitchell <mark@codesourcery.com>
PR c++/11834
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index afdc291..a76d2ac 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -795,7 +795,7 @@ standard_conversion (tree to, tree from, tree expr)
conv = build_conv (STD_CONV, to, conv);
/* Give this a better rank if it's a promotion. */
- if (to == type_promotes_to (from)
+ if (same_type_p (to, type_promotes_to (from))
&& ICS_STD_RANK (TREE_OPERAND (conv, 0)) <= PROMO_RANK)
ICS_STD_RANK (conv) = PROMO_RANK;
}
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a38d993..4eb5c0e 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -4091,27 +4091,13 @@ do_class_using_decl (tree decl)
error ("using-declaration cannot name destructor");
return NULL_TREE;
}
- else if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- {
- template_id_error:;
-
- error ("a using-declaration cannot specify a template-id");
- return NULL_TREE;
- }
if (TREE_CODE (name) == TYPE_DECL)
- {
- if (CLASSTYPE_USE_TEMPLATE (TREE_TYPE (name)))
- goto template_id_error;
- name = DECL_NAME (name);
- }
+ name = DECL_NAME (name);
else if (TREE_CODE (name) == TEMPLATE_DECL)
name = DECL_NAME (name);
else if (BASELINK_P (name))
{
tree fns = BASELINK_FUNCTIONS (name);
-
- if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
- goto template_id_error;
name = DECL_NAME (get_first_fn (fns));
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b2a1113..c177a6c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1296,9 +1296,9 @@ static bool cp_parser_translation_unit
static tree cp_parser_primary_expression
(cp_parser *, cp_id_kind *, tree *);
static tree cp_parser_id_expression
- (cp_parser *, bool, bool, bool *);
+ (cp_parser *, bool, bool, bool *, bool);
static tree cp_parser_unqualified_id
- (cp_parser *, bool, bool);
+ (cp_parser *, bool, bool, bool);
static tree cp_parser_nested_name_specifier_opt
(cp_parser *, bool, bool, bool);
static tree cp_parser_nested_name_specifier
@@ -2398,7 +2398,8 @@ cp_parser_primary_expression (cp_parser *parser,
= cp_parser_id_expression (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/true,
- /*template_p=*/NULL);
+ /*template_p=*/NULL,
+ /*declarator_p=*/false);
if (id_expression == error_mark_node)
return error_mark_node;
/* If we have a template-id, then no further lookup is
@@ -2495,13 +2496,17 @@ cp_parser_primary_expression (cp_parser *parser,
If *TEMPLATE_P is non-NULL, it is set to true iff the
`template' keyword is used to explicitly indicate that the entity
- named is a template. */
+ named is a template.
+
+ If DECLARATOR_P is true, the id-expression is appearing as part of
+ a declarator, rather than as part of an exprsesion. */
static tree
cp_parser_id_expression (cp_parser *parser,
bool template_keyword_p,
bool check_dependency_p,
- bool *template_p)
+ bool *template_p,
+ bool declarator_p)
{
bool global_scope_p;
bool nested_name_specifier_p;
@@ -2542,7 +2547,8 @@ cp_parser_id_expression (cp_parser *parser,
saved_qualifying_scope = parser->qualifying_scope;
/* Process the final unqualified-id. */
unqualified_id = cp_parser_unqualified_id (parser, *template_p,
- check_dependency_p);
+ check_dependency_p,
+ declarator_p);
/* Restore the SAVED_SCOPE for our caller. */
parser->scope = saved_scope;
parser->object_scope = saved_object_scope;
@@ -2597,7 +2603,8 @@ cp_parser_id_expression (cp_parser *parser,
}
else
return cp_parser_unqualified_id (parser, template_keyword_p,
- /*check_dependency_p=*/true);
+ /*check_dependency_p=*/true,
+ declarator_p);
}
/* Parse an unqualified-id.
@@ -2618,12 +2625,15 @@ cp_parser_id_expression (cp_parser *parser,
BIT_NOT_EXPR is an IDENTIFIER_NODE for the class-name. For the
other productions, see the documentation accompanying the
corresponding parsing functions. If CHECK_DEPENDENCY_P is false,
- names are looked up in uninstantiated templates. */
+ names are looked up in uninstantiated templates. If DECLARATOR_P
+ is true, the unqualified-id is appearing as part of a declarator,
+ rather than as part of an expression. */
static tree
cp_parser_unqualified_id (cp_parser* parser,
bool template_keyword_p,
- bool check_dependency_p)
+ bool check_dependency_p,
+ bool declarator_p)
{
cp_token *token;
@@ -2781,6 +2791,16 @@ cp_parser_unqualified_id (cp_parser* parser,
else if (type_decl == error_mark_node)
return error_mark_node;
+ /* [class.dtor]
+
+ A typedef-name that names a class shall not be used as the
+ identifier in the declarator for a destructor declaration. */
+ if (declarator_p
+ && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
+ && !DECL_SELF_REFERENCE_P (type_decl))
+ error ("typedef-name `%D' used as destructor declarator",
+ type_decl);
+
return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
}
@@ -3625,7 +3645,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
name = cp_parser_id_expression (parser,
template_p,
/*check_dependency_p=*/true,
- /*template_p=*/NULL);
+ /*template_p=*/NULL,
+ /*declarator_p=*/false);
/* In general, build a SCOPE_REF if the member name is
qualified. However, if the name was not dependent
and has already been resolved; there is no need to
@@ -7386,7 +7407,8 @@ cp_parser_type_parameter (cp_parser* parser)
= cp_parser_id_expression (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/true,
- /*template_p=*/NULL);
+ /*template_p=*/NULL,
+ /*declarator_p=*/false);
/* Look up the name. */
default_argument
= cp_parser_lookup_name_simple (parser, default_argument);
@@ -7805,7 +7827,8 @@ cp_parser_template_argument (cp_parser* parser)
argument = cp_parser_id_expression (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/true,
- &template_p);
+ &template_p,
+ /*declarator_p=*/false);
/* If the next token isn't a `,' or a `>', then this argument wasn't
really finished. */
if (!cp_parser_next_token_ends_template_argument_p (parser))
@@ -8992,35 +9015,47 @@ cp_parser_using_declaration (cp_parser* parser)
/* Parse the unqualified-id. */
identifier = cp_parser_unqualified_id (parser,
/*template_keyword_p=*/false,
- /*check_dependency_p=*/true);
+ /*check_dependency_p=*/true,
+ /*declarator_p=*/true);
/* The function we call to handle a using-declaration is different
depending on what scope we are in. */
- scope = current_scope ();
- if (scope && TYPE_P (scope))
- {
- /* Create the USING_DECL. */
- decl = do_class_using_decl (build_nt (SCOPE_REF,
- parser->scope,
- identifier));
- /* Add it to the list of members in this class. */
- finish_member_declaration (decl);
- }
+ if (identifier == error_mark_node)
+ ;
+ else if (TREE_CODE (identifier) != IDENTIFIER_NODE
+ && TREE_CODE (identifier) != BIT_NOT_EXPR)
+ /* [namespace.udecl]
+
+ A using declaration shall not name a template-id. */
+ error ("a template-id may not appear in a using-declaration");
else
{
- decl = cp_parser_lookup_name_simple (parser, identifier);
- if (decl == error_mark_node)
+ scope = current_scope ();
+ if (scope && TYPE_P (scope))
{
- if (parser->scope && parser->scope != global_namespace)
- error ("`%D::%D' has not been declared",
- parser->scope, identifier);
- else
- error ("`::%D' has not been declared", identifier);
+ /* Create the USING_DECL. */
+ decl = do_class_using_decl (build_nt (SCOPE_REF,
+ parser->scope,
+ identifier));
+ /* Add it to the list of members in this class. */
+ finish_member_declaration (decl);
}
- else if (scope)
- do_local_using_decl (decl);
else
- do_toplevel_using_decl (decl);
+ {
+ decl = cp_parser_lookup_name_simple (parser, identifier);
+ if (decl == error_mark_node)
+ {
+ if (parser->scope && parser->scope != global_namespace)
+ error ("`%D::%D' has not been declared",
+ parser->scope, identifier);
+ else
+ error ("`::%D' has not been declared", identifier);
+ }
+ else if (scope)
+ do_local_using_decl (decl);
+ else
+ do_toplevel_using_decl (decl);
+ }
}
/* Look for the final `;'. */
@@ -10119,7 +10154,8 @@ cp_parser_declarator_id (cp_parser* parser)
id_expression = cp_parser_id_expression (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/false,
- /*template_p=*/NULL);
+ /*template_p=*/NULL,
+ /*declarator_p=*/true);
/* If the name was qualified, create a SCOPE_REF to represent
that. */
if (parser->scope)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 65d0308..6aa9a0a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2003-08-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11919
+ * g++.dg/overload/prom1.C: New test.
+
+ PR c++/11551
+ * g++.dg/parse/dtor2.C: New test.
+
+ PR c++/10762
+ * g++.dg/parse/using2.C: New test.
+
2003-08-21 Kazu Hirata <kazu@cs.umass.edu>
PR target/11805
diff --git a/gcc/testsuite/g++.dg/overload/prom1.C b/gcc/testsuite/g++.dg/overload/prom1.C
new file mode 100644
index 0000000..9eb387d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/prom1.C
@@ -0,0 +1,9 @@
+void foo(signed char) {}
+typedef int bar;
+void foo(bar) {}
+
+int main (int, char **) {
+ char c;
+ foo(c);
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/parse/dtor2.C b/gcc/testsuite/g++.dg/parse/dtor2.C
new file mode 100644
index 0000000..60e132b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/dtor2.C
@@ -0,0 +1,4 @@
+struct A {
+ typedef A A2;
+ ~A2(); // { dg-error "" }
+};
diff --git a/gcc/testsuite/g++.dg/parse/using2.C b/gcc/testsuite/g++.dg/parse/using2.C
new file mode 100644
index 0000000..bfdb09f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/using2.C
@@ -0,0 +1,8 @@
+namespace N {
+ template <typename T>
+ struct foo {};
+}
+
+int main() {
+ using N::foo<double>; // { dg-error "" }
+}