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