Commit 17a27b4f by Mark Mitchell Committed by Mark Mitchell

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
parent c69c9b36
2004-10-09 Mark Mitchell <mark@codesourcery.com> 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 PR c++/17524
* cp-tree.h (check_var_type): New function. * cp-tree.h (check_var_type): New function.
* decl.c (check_var_type): New function, split out from ... * decl.c (check_var_type): New function, split out from ...
......
...@@ -1343,7 +1343,7 @@ dump_expr (tree t, int flags) ...@@ -1343,7 +1343,7 @@ dump_expr (tree t, int flags)
if (fn && TREE_CODE (fn) == FUNCTION_DECL) if (fn && TREE_CODE (fn) == FUNCTION_DECL)
{ {
if (DECL_CONSTRUCTOR_P (fn)) if (DECL_CONSTRUCTOR_P (fn))
pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (TREE_TYPE (t))); dump_type (DECL_CONTEXT (fn), flags);
else else
dump_decl (fn, 0); dump_decl (fn, 0);
} }
......
...@@ -1606,31 +1606,14 @@ build_builtin_delete_call (tree addr) ...@@ -1606,31 +1606,14 @@ build_builtin_delete_call (tree addr)
return build_call (global_delete_fndecl, build_tree_list (NULL_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 /* Generate a representation for a C++ "new" expression. PLACEMENT is
(which needs to go through some sort of groktypename) or it a TREE_LIST of placement-new arguments (or NULL_TREE if none). If
is the name of the class we are newing. INIT is an initialization value. NELTS is NULL, TYPE is the type of the storage to be allocated. If
It is either an EXPRLIST, an EXPR_NO_COMMAS, or something in braces. NELTS is not NULL, then this is an array-new allocation; TYPE is
If INIT is void_type_node, it means do *not* call a constructor the type of the elements in the array and NELTS is the number of
for this instance. elements in the array. INIT, if non-NULL, is the initializer for
the new object. If USE_GLOBAL_NEW is true, then the user
For types with constructors, the data returned is initialized explicitly wrote "::new" rather than just "new". */
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 (). */
tree tree
build_new (tree placement, tree type, tree nelts, tree init, build_new (tree placement, tree type, tree nelts, tree init,
......
...@@ -4274,6 +4274,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ...@@ -4274,6 +4274,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
tree name; tree name;
bool dependent_p; bool dependent_p;
bool template_p; bool template_p;
bool pseudo_destructor_p;
tree scope = NULL_TREE; tree scope = NULL_TREE;
/* If this is a `->' operator, dereference the pointer. */ /* If this is a `->' operator, dereference the pointer. */
...@@ -4315,11 +4316,34 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ...@@ -4315,11 +4316,34 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
postfix_expression = error_mark_node; postfix_expression = error_mark_node;
} }
/* 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 /* If the SCOPE is not a scalar type, we are looking at an
ordinary class member access expression, rather than a ordinary class member access expression, rather than a
pseudo-destructor-name. */ pseudo-destructor-name. */
if (!scope || !SCALAR_TYPE_P (scope))
{
template_p = cp_parser_optional_template_keyword (parser); template_p = cp_parser_optional_template_keyword (parser);
/* Parse the id-expression. */ /* Parse the id-expression. */
name = cp_parser_id_expression (parser, template_p, name = cp_parser_id_expression (parser, template_p,
...@@ -4354,19 +4378,6 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ...@@ -4354,19 +4378,6 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
postfix_expression postfix_expression
= finish_class_member_access_expr (postfix_expression, name); = 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 /* We no longer need to look up names in the scope of the object on
the left-hand side of the `.' or `->' operator. */ the left-hand side of the `.' or `->' operator. */
...@@ -4862,7 +4873,7 @@ cp_parser_new_expression (cp_parser* parser) ...@@ -4862,7 +4873,7 @@ cp_parser_new_expression (cp_parser* parser)
inform ("try removing the parentheses around the type-id"); inform ("try removing the parentheses around the type-id");
cp_parser_direct_new_declarator (parser); cp_parser_direct_new_declarator (parser);
} }
nelts = integer_one_node; nelts = NULL_TREE;
} }
/* Otherwise, there must be a new-type-id. */ /* Otherwise, there must be a new-type-id. */
else else
......
...@@ -1500,6 +1500,12 @@ cp_tree_equal (tree t1, tree t2) ...@@ -1500,6 +1500,12 @@ cp_tree_equal (tree t1, tree t2)
case IDENTIFIER_NODE: case IDENTIFIER_NODE:
return false; 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: case TEMPLATE_PARM_INDEX:
return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2) return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
&& TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2) && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
......
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> 2004-10-10 Joseph S. Myers <jsm@polyomino.org.uk>
PR c/17301 PR c/17301
......
// 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);
}
// PR C++/17867
struct A
{ // { dg-error "candidate" }
A(int);
};
const A& foo();
void bar()
{
foo()=A(0); // { dg-error "A" }
}
// 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;
}
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment