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
This commit is contained in:
Mark Mitchell 2004-10-10 05:02:54 +00:00 committed by Mark Mitchell
parent c69c9b36a9
commit 17a27b4f0c
10 changed files with 140 additions and 44 deletions

View File

@ -1,5 +1,22 @@
2004-10-09 Mark Mitchell <mark@codesourcery.com>
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 ...

View File

@ -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);
}

View File

@ -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,

View File

@ -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

View File

@ -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)

View File

@ -1,3 +1,17 @@
2004-10-09 Mark Mitchell <mark@codesourcery.com>
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 <jsm@polyomino.org.uk>
PR c/17301

View File

@ -0,0 +1,21 @@
// PR c++/17670
// { dg-do run }
#include <cstdlib>
#include <new>
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);
}

View File

@ -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" }
}

View File

@ -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;
}

View File

@ -0,0 +1,14 @@
// PR c++/17826
struct A
{
template<typename> static int foo();
};
template<int> struct B {};
template<typename T> void bar()
{
B<sizeof A::foo<T>()> b1;
B<sizeof A::foo<T>()> b2;
}