Commit 8a2b77e7 by Jason Merrill

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
parent 9bddde52
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> 2001-11-15 Nathan Sidwell <nathan@codesourcery.com>
PR g++/3154 PR g++/3154
...@@ -17,12 +33,12 @@ ...@@ -17,12 +33,12 @@
2001-11-14 Richard Sandiford <rsandifo@redhat.com> 2001-11-14 Richard Sandiford <rsandifo@redhat.com>
* decl.c (check_initializer): Try to complete the type of an * decl.c (check_initializer): Try to complete the type of an
array element before checking whether it's complete. Don't array element before checking whether it's complete. Don't
complain about arrays with complete element types but an complain about arrays with complete element types but an
unknown size. unknown size.
(cp_finish_decl): Build the hierarchical constructor before (cp_finish_decl): Build the hierarchical constructor before
calling maybe_deduce_size_from_array_init. calling maybe_deduce_size_from_array_init.
2001-11-14 Joseph S. Myers <jsm28@cam.ac.uk> 2001-11-14 Joseph S. Myers <jsm28@cam.ac.uk>
......
...@@ -753,6 +753,14 @@ standard_conversion (to, from, expr) ...@@ -753,6 +753,14 @@ standard_conversion (to, from, expr)
conv = build_conv (STD_CONV, to, conv); conv = build_conv (STD_CONV, to, conv);
ICS_BAD_FLAG (conv) = 1; 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) else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)
{ {
enum tree_code ufcode = TREE_CODE (TREE_TYPE (from)); enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
...@@ -3748,7 +3756,7 @@ convert_like_real (convs, expr, fn, argnum, inner) ...@@ -3748,7 +3756,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
tree t = convs; tree t = convs;
for (; t; t = TREE_OPERAND (t, 0)) 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); expr = convert_like_real (t, expr, fn, argnum, 1);
break; break;
......
...@@ -936,10 +936,8 @@ convert_to_void (expr, implicit) ...@@ -936,10 +936,8 @@ convert_to_void (expr, implicit)
tree new_op1 = convert_to_void (op1, implicit); tree new_op1 = convert_to_void (op1, implicit);
tree new_op2 = convert_to_void (op2, implicit); tree new_op2 = convert_to_void (op2, implicit);
if (new_op1 != op1 || new_op2 != op2) expr = build (COND_EXPR, void_type_node,
expr = build (COND_EXPR, TREE_OPERAND (expr, 0), new_op1, new_op2);
implicit ? TREE_TYPE (expr) : void_type_node,
TREE_OPERAND (expr, 0), new_op1, new_op2);
break; break;
} }
......
...@@ -5652,6 +5652,11 @@ make_typename_type (context, name, complain) ...@@ -5652,6 +5652,11 @@ make_typename_type (context, name, complain)
if (TREE_CODE (name) == TEMPLATE_DECL) if (TREE_CODE (name) == TEMPLATE_DECL)
name = TREE_OPERAND (fullname, 0) = DECL_NAME (name); 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) if (TREE_CODE (name) != IDENTIFIER_NODE)
my_friendly_abort (2000); my_friendly_abort (2000);
......
...@@ -513,6 +513,9 @@ use_thunk (thunk_fndecl, emit_p) ...@@ -513,6 +513,9 @@ use_thunk (thunk_fndecl, emit_p)
referenced. */ referenced. */
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (thunk_fndecl)) = 1; 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)); expand_body (finish_function (0));
} }
......
...@@ -3021,6 +3021,13 @@ nested_name_specifier: ...@@ -3021,6 +3021,13 @@ nested_name_specifier:
| nested_name_specifier TEMPLATE explicit_template_type SCOPE | nested_name_specifier TEMPLATE explicit_template_type SCOPE
{ got_scope = $$ { got_scope = $$
= make_typename_type ($1, $3, /*complain=*/1); } = 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 /* Why the @#$%^& do type_name and notype_identifier need to be expanded
...@@ -3050,16 +3057,6 @@ nested_name_specifier_1: ...@@ -3050,16 +3057,6 @@ nested_name_specifier_1:
} }
| template_type SCOPE | template_type SCOPE
{ got_scope = $$ = complete_type (TREE_TYPE ($1)); } { 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: typename_sub:
......
...@@ -1367,7 +1367,8 @@ lookup_field_r (binfo, data) ...@@ -1367,7 +1367,8 @@ lookup_field_r (binfo, data)
/* If we're looking up a type (as with an elaborated type specifier) /* If we're looking up a type (as with an elaborated type specifier)
we ignore all non-types we find. */ 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)) if (lfi->name == TYPE_IDENTIFIER (type))
{ {
...@@ -1727,9 +1728,9 @@ lookup_fnfields_1 (type, name) ...@@ -1727,9 +1728,9 @@ lookup_fnfields_1 (type, name)
} }
/* Walk the class hierarchy dominated by TYPE. FN is called for each /* 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 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 BINFO indicating the path from the curently visited base-class to
TYPE. Before each base-class is walked QFN is called. If the TYPE. Before each base-class is walked QFN is called. If the
value returned is non-zero, the base-class is walked; otherwise it value returned is non-zero, the base-class is walked; otherwise it
......
...@@ -6822,6 +6822,13 @@ ptr_reasonably_similar (to, from) ...@@ -6822,6 +6822,13 @@ ptr_reasonably_similar (to, from)
COMPARE_BASE | COMPARE_RELAXED)) COMPARE_BASE | COMPARE_RELAXED))
continue; 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) if (TREE_CODE (to) != POINTER_TYPE)
return comptypes return comptypes
(TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
......
...@@ -13,4 +13,7 @@ int main () ...@@ -13,4 +13,7 @@ int main ()
f (i); f (i);
f (v); f (v);
g (v); g (v);
enum { a } b = i;
void (*p2)(int) = p;
unsigned *ip = &i;
} }
// 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);
}
// 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" }
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