From 17a27b4f0c4ce1f151263c1919dba4fd2231eedc Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sun, 10 Oct 2004 05:02:54 +0000 Subject: [PATCH] re PR c++/17867 ("void" instead of class name in error message) PR c++/17867 * error.c (dump_expr): Correct handling of AGGR_INIT_EXPRs using a constructor. PR c++/17670 * init.c (build_new): Correct comments. * parser.c (cp_parser_new_expression): Use NULL_TREE for nelts in the non-array case. PR c++/17821 * parser.c (cp_parser_postfix_dot_deref_expression): If the pseduo-destructor-name production does not work, fall back to the ordinary production. PR c++/17826 * tree.c (cp_tree_equal): Handle a BASELINK. PR c++/17687 * g++.dg/parse/error19.C: New test. PR c++/17670 * g++.dg/init/new11.C: New test. PR c++/17821 * g++.dg/parse/error20.C: New test. PR c++/17826 * g++.dg/template/crash24.C: New test. From-SVN: r88836 --- gcc/cp/ChangeLog | 17 +++++++++ gcc/cp/error.c | 2 +- gcc/cp/init.c | 33 +++++------------ gcc/cp/parser.c | 47 +++++++++++++++---------- gcc/cp/tree.c | 6 ++++ gcc/testsuite/ChangeLog | 14 ++++++++ gcc/testsuite/g++.dg/init/new11.C | 21 +++++++++++ gcc/testsuite/g++.dg/parse/error19.C | 13 +++++++ gcc/testsuite/g++.dg/parse/error20.C | 17 +++++++++ gcc/testsuite/g++.dg/template/crash24.C | 14 ++++++++ 10 files changed, 140 insertions(+), 44 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/new11.C create mode 100644 gcc/testsuite/g++.dg/parse/error19.C create mode 100644 gcc/testsuite/g++.dg/parse/error20.C create mode 100644 gcc/testsuite/g++.dg/template/crash24.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5c4c7c84681..6084f5175de 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,22 @@ 2004-10-09 Mark Mitchell + PR c++/17867 + * error.c (dump_expr): Correct handling of AGGR_INIT_EXPRs using a + constructor. + + PR c++/17670 + * init.c (build_new): Correct comments. + * parser.c (cp_parser_new_expression): Use NULL_TREE for nelts in + the non-array case. + + PR c++/17821 + * parser.c (cp_parser_postfix_dot_deref_expression): If the + pseduo-destructor-name production does not work, fall back to the + ordinary production. + + PR c++/17826 + * tree.c (cp_tree_equal): Handle a BASELINK. + PR c++/17524 * cp-tree.h (check_var_type): New function. * decl.c (check_var_type): New function, split out from ... diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 8ac6e2b6904..af973d60a2c 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1343,7 +1343,7 @@ dump_expr (tree t, int flags) if (fn && TREE_CODE (fn) == FUNCTION_DECL) { if (DECL_CONSTRUCTOR_P (fn)) - pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (TREE_TYPE (t))); + dump_type (DECL_CONTEXT (fn), flags); else dump_decl (fn, 0); } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index ceb6d690a6a..2d04334e153 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1606,31 +1606,14 @@ build_builtin_delete_call (tree addr) return build_call (global_delete_fndecl, build_tree_list (NULL_TREE, addr)); } -/* Generate a C++ "new" expression. DECL is either a TREE_LIST - (which needs to go through some sort of groktypename) or it - is the name of the class we are newing. INIT is an initialization value. - It is either an EXPRLIST, an EXPR_NO_COMMAS, or something in braces. - If INIT is void_type_node, it means do *not* call a constructor - for this instance. - - For types with constructors, the data returned is initialized - by the appropriate constructor. - - Whether the type has a constructor or not, if it has a pointer - to a virtual function table, then that pointer is set up - here. - - Unless I am mistaken, a call to new () will return initialized - data regardless of whether the constructor itself is private or - not. NOPE; new fails if the constructor is private (jcm). - - Note that build_new does nothing to assure that any special - alignment requirements of the type are met. Rather, it leaves - it up to malloc to do the right thing. Otherwise, folding to - the right alignment cal cause problems if the user tries to later - free the memory returned by `new'. - - PLACEMENT is the `placement' list for user-defined operator new (). */ +/* Generate a representation for a C++ "new" expression. PLACEMENT is + a TREE_LIST of placement-new arguments (or NULL_TREE if none). If + NELTS is NULL, TYPE is the type of the storage to be allocated. If + NELTS is not NULL, then this is an array-new allocation; TYPE is + the type of the elements in the array and NELTS is the number of + elements in the array. INIT, if non-NULL, is the initializer for + the new object. If USE_GLOBAL_NEW is true, then the user + explicitly wrote "::new" rather than just "new". */ tree build_new (tree placement, tree type, tree nelts, tree init, diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 9bd3f1805b6..7fb9d9631fa 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4274,6 +4274,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, tree name; bool dependent_p; bool template_p; + bool pseudo_destructor_p; tree scope = NULL_TREE; /* If this is a `->' operator, dereference the pointer. */ @@ -4315,11 +4316,34 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, postfix_expression = error_mark_node; } - /* If the SCOPE is not a scalar type, we are looking at an - ordinary class member access expression, rather than a - pseudo-destructor-name. */ - if (!scope || !SCALAR_TYPE_P (scope)) + /* Assume this expression is not a pseudo-destructor access. */ + pseudo_destructor_p = false; + + /* If the SCOPE is a scalar type, then, if this is a valid program, + we must be looking at a pseudo-destructor-name. */ + if (scope && SCALAR_TYPE_P (scope)) { + tree s; + tree type; + + cp_parser_parse_tentatively (parser); + /* Parse the pseudo-destructor-name. */ + s = NULL_TREE; + cp_parser_pseudo_destructor_name (parser, &s, &type); + if (cp_parser_parse_definitely (parser)) + { + pseudo_destructor_p = true; + postfix_expression + = finish_pseudo_destructor_expr (postfix_expression, + s, TREE_TYPE (type)); + } + } + + if (!pseudo_destructor_p) + { + /* If the SCOPE is not a scalar type, we are looking at an + ordinary class member access expression, rather than a + pseudo-destructor-name. */ template_p = cp_parser_optional_template_keyword (parser); /* Parse the id-expression. */ name = cp_parser_id_expression (parser, template_p, @@ -4354,19 +4378,6 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, postfix_expression = finish_class_member_access_expr (postfix_expression, name); } - /* Otherwise, try the pseudo-destructor-name production. */ - else - { - tree s = NULL_TREE; - tree type; - - /* Parse the pseudo-destructor-name. */ - cp_parser_pseudo_destructor_name (parser, &s, &type); - /* Form the call. */ - postfix_expression - = finish_pseudo_destructor_expr (postfix_expression, - s, TREE_TYPE (type)); - } /* We no longer need to look up names in the scope of the object on the left-hand side of the `.' or `->' operator. */ @@ -4862,7 +4873,7 @@ cp_parser_new_expression (cp_parser* parser) inform ("try removing the parentheses around the type-id"); cp_parser_direct_new_declarator (parser); } - nelts = integer_one_node; + nelts = NULL_TREE; } /* Otherwise, there must be a new-type-id. */ else diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index a8cea232c27..a4b7cf9c0d4 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1500,6 +1500,12 @@ cp_tree_equal (tree t1, tree t2) case IDENTIFIER_NODE: return false; + case BASELINK: + return (BASELINK_BINFO (t1) == BASELINK_BINFO (t2) + && BASELINK_ACCESS_BINFO (t1) == BASELINK_ACCESS_BINFO (t2) + && cp_tree_equal (BASELINK_FUNCTIONS (t1), + BASELINK_FUNCTIONS (t2))); + case TEMPLATE_PARM_INDEX: return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2) && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b983c01ffd5..2c476166b4c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2004-10-09 Mark Mitchell + + PR c++/17687 + * g++.dg/parse/error19.C: New test. + + PR c++/17670 + * g++.dg/init/new11.C: New test. + + PR c++/17821 + * g++.dg/parse/error20.C: New test. + + PR c++/17826 + * g++.dg/template/crash24.C: New test. + 2004-10-10 Joseph S. Myers PR c/17301 diff --git a/gcc/testsuite/g++.dg/init/new11.C b/gcc/testsuite/g++.dg/init/new11.C new file mode 100644 index 00000000000..bf06aa4e757 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/new11.C @@ -0,0 +1,21 @@ +// PR c++/17670 +// { dg-do run } + +#include +#include + +bool abort_new; +void *operator new[](size_t bytes) throw (std::bad_alloc) { + if (abort_new) + abort(); + return operator new (bytes); +} + + +struct X {}; +int main () { + // Do not abort until main is running in case startup code uses + // operator new[]. + abort_new = true; + new (X); +} diff --git a/gcc/testsuite/g++.dg/parse/error19.C b/gcc/testsuite/g++.dg/parse/error19.C new file mode 100644 index 00000000000..24a66affdae --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/error19.C @@ -0,0 +1,13 @@ +// PR C++/17867 + +struct A +{ // { dg-error "candidate" } + A(int); +}; + +const A& foo(); + +void bar() +{ + foo()=A(0); // { dg-error "A" } +} diff --git a/gcc/testsuite/g++.dg/parse/error20.C b/gcc/testsuite/g++.dg/parse/error20.C new file mode 100644 index 00000000000..ee7390a633c --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/error20.C @@ -0,0 +1,17 @@ +// PR c++/17821 + +struct A { + A(int i) {} +}; +struct B { + int i; +}; +struct C { + B* p; +}; +int main() { + C c; + A(c.p.i); // { dg-error "member.*non-class" } + return 0; +} + diff --git a/gcc/testsuite/g++.dg/template/crash24.C b/gcc/testsuite/g++.dg/template/crash24.C new file mode 100644 index 00000000000..49b8c7e718d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash24.C @@ -0,0 +1,14 @@ +// PR c++/17826 + +struct A +{ + template static int foo(); +}; + +template struct B {}; + +template void bar() +{ + B()> b1; + B()> b2; +}