aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>2001-11-15 10:09:43 -0500
committerJason Merrill <jason@gcc.gnu.org>2001-11-15 10:09:43 -0500
commit8a2b77e7376a10b62a023843a64d4998fde5b5da (patch)
tree3a2e64bbd40a3c54769c05fc7a160ad65a8d29fc
parent9bddde52b4cf9c9a4609e2288893c57a1da0abd7 (diff)
downloadgcc-8a2b77e7376a10b62a023843a64d4998fde5b5da.zip
gcc-8a2b77e7376a10b62a023843a64d4998fde5b5da.tar.gz
gcc-8a2b77e7376a10b62a023843a64d4998fde5b5da.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog28
-rw-r--r--gcc/cp/call.c10
-rw-r--r--gcc/cp/cvt.c6
-rw-r--r--gcc/cp/decl.c5
-rw-r--r--gcc/cp/method.c3
-rw-r--r--gcc/cp/parse.y17
-rw-r--r--gcc/cp/search.c7
-rw-r--r--gcc/cp/typeck.c7
-rw-r--r--gcc/testsuite/g++.dg/ext/conv1.C3
-rw-r--r--gcc/testsuite/g++.dg/overload/cond1.C24
-rw-r--r--gcc/testsuite/g++.dg/template/type1.C8
11 files changed, 94 insertions, 24 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 025defa..59cb2af 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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>
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 43d2baf..91bc097 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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;
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 81d0577..960552c8 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -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;
}
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5098b57..ed6b6bf 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 4a12823..24fd379 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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));
}
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 12e8e26..449ea98 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -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:
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index e7076f5..e09aa23 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -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
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index dda76fe..85dc1d3 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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),
diff --git a/gcc/testsuite/g++.dg/ext/conv1.C b/gcc/testsuite/g++.dg/ext/conv1.C
index 4c0d848..6c16fe4 100644
--- a/gcc/testsuite/g++.dg/ext/conv1.C
+++ b/gcc/testsuite/g++.dg/ext/conv1.C
@@ -13,4 +13,7 @@ int main ()
f (i);
f (v);
g (v);
+ enum { a } b = i;
+ void (*p2)(int) = p;
+ unsigned *ip = &i;
}
diff --git a/gcc/testsuite/g++.dg/overload/cond1.C b/gcc/testsuite/g++.dg/overload/cond1.C
new file mode 100644
index 0000000..74f0f3c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/cond1.C
@@ -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);
+}
diff --git a/gcc/testsuite/g++.dg/template/type1.C b/gcc/testsuite/g++.dg/template/type1.C
new file mode 100644
index 0000000..cd5cf5f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/type1.C
@@ -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" }