mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 18:20:51 +08:00
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:
parent
c69c9b36a9
commit
17a27b4f0c
@ -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 ...
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
21
gcc/testsuite/g++.dg/init/new11.C
Normal file
21
gcc/testsuite/g++.dg/init/new11.C
Normal 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);
|
||||
}
|
13
gcc/testsuite/g++.dg/parse/error19.C
Normal file
13
gcc/testsuite/g++.dg/parse/error19.C
Normal 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" }
|
||||
}
|
17
gcc/testsuite/g++.dg/parse/error20.C
Normal file
17
gcc/testsuite/g++.dg/parse/error20.C
Normal 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;
|
||||
}
|
||||
|
14
gcc/testsuite/g++.dg/template/crash24.C
Normal file
14
gcc/testsuite/g++.dg/template/crash24.C
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user