parse.y: Add ...
authorJason Merrill <jason@gcc.gnu.org>
Thu, 15 Nov 2001 15:09:43 +0000 (10:09 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 15 Nov 2001 15:09:43 +0000 (10:09 -0500)
        * 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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/search.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/ext/conv1.C
gcc/testsuite/g++.dg/overload/cond1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/type1.C [new file with mode: 0644]

index 025defa26b90d5bba98450a13cc09201c31e1d59..59cb2af715886a5c59153ac7e60c3b8e5f41ad0f 100644 (file)
@@ -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
 
 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>
 
index 43d2baf1fb1dc0e6d427353d8e523f90db38264a..91bc0978ad2c24c090c03354d40a8023e176d765 100644 (file)
@@ -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;
index 81d05777308fc846c29f641a9968d1efb2cbebce..960552c8e6a63bcde5a6577db82c6ddcd90dec50 100644 (file)
@@ -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;
       }
     
index 5098b576055f77368375340f74ab752eedb1ec06..ed6b6bf90b5452c0390f456957e46211b0a3e934 100644 (file)
@@ -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);
 
index 4a12823dea252b24735ba75ebd8e0b83f74c25f8..24fd379933aa6a98f274a048afa1807b9fb0161f 100644 (file)
@@ -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));
   }
 
index 12e8e2634b57e7663a1b750cd5599a33438e1ab7..449ea9830d0ccb9ed6dddcec365bb43f144016b7 100644 (file)
@@ -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:
index e7076f5f9ecb23ee04775ac596c4df1c37fcfac0..e09aa23ff3ba54138e3dbd8a7913dfd14831f8dd 100644 (file)
@@ -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)
 }
 \f
 /* 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
index dda76fe2fcdca2932ea1bf5fc35dd4668a3dc308..85dc1d38e14ed1fe188f759b31ab8adc4a569658 100644 (file)
@@ -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), 
index 4c0d848c8cc76248a8006d45c4e4d8ed03dc6c3e..6c16fe484189f097afc149f884d3387b92323ecb 100644 (file)
@@ -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 (file)
index 0000000..74f0f3c
--- /dev/null
@@ -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 (file)
index 0000000..cd5cf5f
--- /dev/null
@@ -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" }