parse.y: Add ...
* parse.y: Add ... IDENTIFIER SCOPE and ... PTYPENAME SCOPE expansions. * decl.c (make_typename_type): Handle getting a class template. * search.c (lookup_field_r): A class template is good enough for want_type. * call.c (convert_like_real): Only use cp_convert for the bad part. (standard_conversion): Also allow bad int->enum. * typeck.c (ptr_reasonably_similar): Also allow functions to interconvert. Pointers to same-size integers are reasonably similar. * cvt.c (convert_to_void): If we build a new COND_EXPR, always give it void type. From-SVN: r47060
This commit is contained in:
parent
9bddde52b4
commit
8a2b77e737
@ -1,3 +1,19 @@
|
||||
2001-11-15 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* parse.y: Add ... IDENTIFIER SCOPE and ... PTYPENAME SCOPE expansions.
|
||||
* decl.c (make_typename_type): Handle getting a class template.
|
||||
* search.c (lookup_field_r): A class template is good enough for
|
||||
want_type.
|
||||
|
||||
* call.c (convert_like_real): Only use cp_convert for the bad part.
|
||||
(standard_conversion): Also allow bad int->enum.
|
||||
* typeck.c (ptr_reasonably_similar): Also allow functions to
|
||||
interconvert. Pointers to same-size integers are reasonably
|
||||
similar.
|
||||
|
||||
* cvt.c (convert_to_void): If we build a new COND_EXPR, always
|
||||
give it void type.
|
||||
|
||||
2001-11-15 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR g++/3154
|
||||
@ -17,12 +33,12 @@
|
||||
|
||||
2001-11-14 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
* decl.c (check_initializer): Try to complete the type of an
|
||||
array element before checking whether it's complete. Don't
|
||||
complain about arrays with complete element types but an
|
||||
unknown size.
|
||||
(cp_finish_decl): Build the hierarchical constructor before
|
||||
calling maybe_deduce_size_from_array_init.
|
||||
* decl.c (check_initializer): Try to complete the type of an
|
||||
array element before checking whether it's complete. Don't
|
||||
complain about arrays with complete element types but an
|
||||
unknown size.
|
||||
(cp_finish_decl): Build the hierarchical constructor before
|
||||
calling maybe_deduce_size_from_array_init.
|
||||
|
||||
2001-11-14 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
|
@ -753,6 +753,14 @@ standard_conversion (to, from, expr)
|
||||
conv = build_conv (STD_CONV, to, conv);
|
||||
ICS_BAD_FLAG (conv) = 1;
|
||||
}
|
||||
else if (tcode == ENUMERAL_TYPE && fcode == INTEGER_TYPE
|
||||
&& TYPE_PRECISION (to) == TYPE_PRECISION (from))
|
||||
{
|
||||
/* For backwards brain damage compatibility, allow interconversion of
|
||||
enums and integers with a pedwarn. */
|
||||
conv = build_conv (STD_CONV, to, conv);
|
||||
ICS_BAD_FLAG (conv) = 1;
|
||||
}
|
||||
else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)
|
||||
{
|
||||
enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
|
||||
@ -3748,7 +3756,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
|
||||
tree t = convs;
|
||||
for (; t; t = TREE_OPERAND (t, 0))
|
||||
{
|
||||
if (TREE_CODE (t) == USER_CONV)
|
||||
if (TREE_CODE (t) == USER_CONV || !ICS_BAD_FLAG (t))
|
||||
{
|
||||
expr = convert_like_real (t, expr, fn, argnum, 1);
|
||||
break;
|
||||
|
@ -936,10 +936,8 @@ convert_to_void (expr, implicit)
|
||||
tree new_op1 = convert_to_void (op1, implicit);
|
||||
tree new_op2 = convert_to_void (op2, implicit);
|
||||
|
||||
if (new_op1 != op1 || new_op2 != op2)
|
||||
expr = build (COND_EXPR,
|
||||
implicit ? TREE_TYPE (expr) : void_type_node,
|
||||
TREE_OPERAND (expr, 0), new_op1, new_op2);
|
||||
expr = build (COND_EXPR, void_type_node,
|
||||
TREE_OPERAND (expr, 0), new_op1, new_op2);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -5652,6 +5652,11 @@ make_typename_type (context, name, complain)
|
||||
if (TREE_CODE (name) == TEMPLATE_DECL)
|
||||
name = TREE_OPERAND (fullname, 0) = DECL_NAME (name);
|
||||
}
|
||||
if (TREE_CODE (name) == TEMPLATE_DECL)
|
||||
{
|
||||
cp_error ("`%D' used without template parameters", name);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (name) != IDENTIFIER_NODE)
|
||||
my_friendly_abort (2000);
|
||||
|
||||
|
@ -513,6 +513,9 @@ use_thunk (thunk_fndecl, emit_p)
|
||||
referenced. */
|
||||
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (thunk_fndecl)) = 1;
|
||||
|
||||
/* But we don't want debugging information about it. */
|
||||
DECL_IGNORED_P (thunk_fndecl) = 1;
|
||||
|
||||
expand_body (finish_function (0));
|
||||
}
|
||||
|
||||
|
@ -3021,6 +3021,13 @@ nested_name_specifier:
|
||||
| nested_name_specifier TEMPLATE explicit_template_type SCOPE
|
||||
{ got_scope = $$
|
||||
= make_typename_type ($1, $3, /*complain=*/1); }
|
||||
/* Error handling per Core 125. */
|
||||
| nested_name_specifier IDENTIFIER SCOPE
|
||||
{ got_scope = $$
|
||||
= make_typename_type ($1, $2, /*complain=*/1); }
|
||||
| nested_name_specifier PTYPENAME SCOPE
|
||||
{ got_scope = $$
|
||||
= make_typename_type ($1, $2, /*complain=*/1); }
|
||||
;
|
||||
|
||||
/* Why the @#$%^& do type_name and notype_identifier need to be expanded
|
||||
@ -3050,16 +3057,6 @@ nested_name_specifier_1:
|
||||
}
|
||||
| template_type SCOPE
|
||||
{ got_scope = $$ = complete_type (TREE_TYPE ($1)); }
|
||||
/* These break 'const i;'
|
||||
| IDENTIFIER SCOPE
|
||||
{
|
||||
failed_scope:
|
||||
cp_error ("`%D' is not an aggregate typedef",
|
||||
lastiddecl ? lastiddecl : $$);
|
||||
$$ = error_mark_node;
|
||||
}
|
||||
| PTYPENAME SCOPE
|
||||
{ goto failed_scope; } */
|
||||
;
|
||||
|
||||
typename_sub:
|
||||
|
@ -1367,7 +1367,8 @@ lookup_field_r (binfo, data)
|
||||
|
||||
/* If we're looking up a type (as with an elaborated type specifier)
|
||||
we ignore all non-types we find. */
|
||||
if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL)
|
||||
if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL
|
||||
&& !DECL_CLASS_TEMPLATE_P (nval))
|
||||
{
|
||||
if (lfi->name == TYPE_IDENTIFIER (type))
|
||||
{
|
||||
@ -1727,9 +1728,9 @@ lookup_fnfields_1 (type, name)
|
||||
}
|
||||
|
||||
/* Walk the class hierarchy dominated by TYPE. FN is called for each
|
||||
type in the hierarchy, in a breadth-first preorder traversal. .
|
||||
type in the hierarchy, in a breadth-first preorder traversal.
|
||||
If it ever returns a non-NULL value, that value is immediately
|
||||
returned and the walk is terminated. At each node FN, is passed a
|
||||
returned and the walk is terminated. At each node, FN is passed a
|
||||
BINFO indicating the path from the curently visited base-class to
|
||||
TYPE. Before each base-class is walked QFN is called. If the
|
||||
value returned is non-zero, the base-class is walked; otherwise it
|
||||
|
@ -6822,6 +6822,13 @@ ptr_reasonably_similar (to, from)
|
||||
COMPARE_BASE | COMPARE_RELAXED))
|
||||
continue;
|
||||
|
||||
if (TREE_CODE (to) == INTEGER_TYPE
|
||||
&& TYPE_PRECISION (to) == TYPE_PRECISION (from))
|
||||
return 1;
|
||||
|
||||
if (TREE_CODE (to) == FUNCTION_TYPE)
|
||||
return 1;
|
||||
|
||||
if (TREE_CODE (to) != POINTER_TYPE)
|
||||
return comptypes
|
||||
(TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
|
||||
|
@ -13,4 +13,7 @@ int main ()
|
||||
f (i);
|
||||
f (v);
|
||||
g (v);
|
||||
enum { a } b = i;
|
||||
void (*p2)(int) = p;
|
||||
unsigned *ip = &i;
|
||||
}
|
||||
|
24
gcc/testsuite/g++.dg/overload/cond1.C
Normal file
24
gcc/testsuite/g++.dg/overload/cond1.C
Normal file
@ -0,0 +1,24 @@
|
||||
// Test that converting a COND_EXPR to void doesn't result in trying to
|
||||
// bitwise copy a class with a nontrivial copy constructor (and thus a
|
||||
// compiler abort).
|
||||
|
||||
// { dg-options "-O" }
|
||||
|
||||
struct A {
|
||||
virtual ~A() { }
|
||||
};
|
||||
|
||||
A a1, a2;
|
||||
inline A& one () { return a1; }
|
||||
inline A& two () { return a2; }
|
||||
|
||||
inline void f (int i)
|
||||
{
|
||||
i ? a1 : a2;
|
||||
i ? one() : two();
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
f (1);
|
||||
}
|
8
gcc/testsuite/g++.dg/template/type1.C
Normal file
8
gcc/testsuite/g++.dg/template/type1.C
Normal file
@ -0,0 +1,8 @@
|
||||
// Test for helpful error messages on invalid nested-name-specifiers.
|
||||
|
||||
struct A {
|
||||
template <class T> struct B { static int c; };
|
||||
};
|
||||
|
||||
int A::B::c; // { dg-error "parameters" }
|
||||
int A::C::d; // { dg-error "no type" }
|
Loading…
Reference in New Issue
Block a user