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
......
...@@ -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,9 +936,7 @@ convert_to_void (expr, implicit) ...@@ -936,9 +936,7 @@ 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,
implicit ? TREE_TYPE (expr) : void_type_node,
TREE_OPERAND (expr, 0), new_op1, new_op2); 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