]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backport:
authorGiovanni Bajo <giovannibajo@gcc.gnu.org>
Thu, 28 Jul 2005 10:22:22 +0000 (10:22 +0000)
committerGiovanni Bajo <giovannibajo@gcc.gnu.org>
Thu, 28 Jul 2005 10:22:22 +0000 (10:22 +0000)
2004-09-16  Mark Mitchell  <mark@codesourcery.com>
PR c++/16002
* parser.c (cp_parser_simple_declaration): Commit to tentative
parses after seeing a decl-specifier.
(cp_parser_simple_declaration): Eliminate spurious message.
(cp_parser_init_declarator): Adjust error message.

2005-06-17  Geoffrey Keating  <geoffk@apple.com>
PR c++/17413
* pt.c (type_unification_real): Apply template type deduction even
to procedure parameters that are not dependent on a template
parameter.

2004-11-02  Mark Mitchell  <mark@codesourcery.com>
PR c++/18124
* parser.c (cp_parser_type_parameter): Robustify.
PR c++/18155
* parser.c (cp_parser_single_declaration): Disallow template
typedefs.
(cp_parser_typedef_p): New function.

2004-12-21  Mark Mitchell  <mark@codesourcery.com>
PR c++/18378
* call.c (convert_like_real): Do not permit the use of a copy
constructor to copy a packed field.

Backport:

2004-09-16  Mark Mitchell  <mark@codesourcery.com>
PR c++/16002
* g++.dg/parse/error18.C: New test.
* g++.dg/parse/crash11.C: Adjust error markers.

2005-06-17  Geoffrey Keating  <geoffk@apple.com>
PR c++/17413
* g++.dg/template/local5.C: New.

2004-11-02  Mark Mitchell  <mark@codesourcery.com>
PR c++/18124
* g++.dg/template/crash25.C: New test.
PR c++/18155
* g++.dg/template/typedef2.C: New test.
* g++.dg/parse/crash13.C: Adjust error markers.

2004-12-21  Mark Mitchell  <mark@codesourcery.com>
PR c++/18378
* g++.dg/ext/packed8.C: New test.

From-SVN: r102477

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/crash11.C
gcc/testsuite/g++.dg/parse/crash13.C
gcc/testsuite/g++.dg/parse/error18.C [new file with mode: 0644]

index 676dbcc2d08da81e124cd1202ababe2b9f0476ad..d10e55cf623856e5cc322e6da94b5f0bcacea76a 100644 (file)
@@ -1,3 +1,33 @@
+2005-07-28  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
+
+       Backport:
+
+       2004-09-16  Mark Mitchell  <mark@codesourcery.com>
+       PR c++/16002
+       * parser.c (cp_parser_simple_declaration): Commit to tentative
+       parses after seeing a decl-specifier.
+       (cp_parser_simple_declaration): Eliminate spurious message.
+       (cp_parser_init_declarator): Adjust error message.
+
+       2005-06-17  Geoffrey Keating  <geoffk@apple.com>        
+       PR c++/17413
+       * pt.c (type_unification_real): Apply template type deduction even
+       to procedure parameters that are not dependent on a template
+       parameter.
+
+       2004-11-02  Mark Mitchell  <mark@codesourcery.com>
+       PR c++/18124
+       * parser.c (cp_parser_type_parameter): Robustify.
+       PR c++/18155
+       * parser.c (cp_parser_single_declaration): Disallow template
+       typedefs.
+       (cp_parser_typedef_p): New function.
+
+       2004-12-21  Mark Mitchell  <mark@codesourcery.com>
+       PR c++/18378
+       * call.c (convert_like_real): Do not permit the use of a copy
+       constructor to copy a packed field.
+
 2005-07-25  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
 
        PR c++/19208
index aeed3155df4b6c7ab716ce4d8aa6d0fcd406a275..404c2ad12318dfc5d380455dda04d44311436810 100644 (file)
@@ -4080,13 +4080,12 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
        if (NEED_TEMPORARY_P (convs) || !lvalue_p (expr))
          {
            tree type = TREE_TYPE (TREE_OPERAND (convs, 0));
+           cp_lvalue_kind lvalue = real_lvalue_p (expr);
 
            if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
              {
                /* If the reference is volatile or non-const, we
                   cannot create a temporary.  */
-               cp_lvalue_kind lvalue = real_lvalue_p (expr);
-               
                if (lvalue & clk_bitfield)
                  error ("cannot bind bitfield `%E' to `%T'",
                         expr, ref_type);
@@ -4097,6 +4096,20 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
                  error ("cannot bind rvalue `%E' to `%T'", expr, ref_type);
                return error_mark_node;
              }
+           /* If the source is a packed field, and we must use a copy
+              constructor, then building the target expr will require
+              binding the field to the reference parameter to the
+              copy constructor, and we'll end up with an infinite
+              loop.  If we can use a bitwise copy, then we'll be
+              OK.  */
+           if ((lvalue & clk_packed) 
+               && CLASS_TYPE_P (type) 
+               && !TYPE_HAS_TRIVIAL_INIT_REF (type))
+             {
+               error ("cannot bind packed field `%E' to `%T'",
+                      expr, ref_type);
+               return error_mark_node;
+             }
            expr = build_target_expr_with_type (expr, type);
          }
 
index d4ca762aba74b1544ab730eed6792269a1763f40..c59d40992b37ea41402b4a69b35d9a592fd4ca53 100644 (file)
@@ -1672,6 +1672,8 @@ static bool cp_parser_declares_only_class_p
   (cp_parser *);
 static bool cp_parser_friend_p
   (tree);
+static bool cp_parser_typedef_p
+  (tree);
 static cp_token *cp_parser_require
   (cp_parser *, enum cpp_ttype, const char *);
 static cp_token *cp_parser_require_keyword
@@ -6523,6 +6525,13 @@ cp_parser_simple_declaration (cp_parser* parser,
       /* Give up.  */
       goto done;
     }
+  
+  /* If we have seen at least one decl-specifier, and the next token
+     is not a parenthesis, then we must be looking at a declaration.
+     (After "int (" we might be looking at a functional cast.)  */
+  if (decl_specifiers
+      && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
+    cp_parser_commit_to_tentative_parse (parser);
 
   /* Keep going until we hit the `;' at the end of the simple
      declaration.  */
@@ -6576,7 +6585,12 @@ cp_parser_simple_declaration (cp_parser* parser,
       /* Anything else is an error.  */
       else
        {
-         cp_parser_error (parser, "expected `,' or `;'");
+         /* If we have already issued an error message we don't need
+            to issue another one.  */
+         if (decl != error_mark_node
+             || (cp_parser_parsing_tentatively (parser)
+                 && !cp_parser_committed_to_tentative_parse (parser)))
+           cp_parser_error (parser, "expected `,' or `;'");
          /* Skip tokens until we reach the end of the statement.  */
          cp_parser_skip_to_end_of_statement (parser);
          /* If the next token is now a `;', consume it.  */
@@ -7802,9 +7816,15 @@ cp_parser_type_parameter (cp_parser* parser)
        if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
            && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
            && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
-         identifier = cp_parser_identifier (parser);
+         {
+           identifier = cp_parser_identifier (parser);
+           /* Treat invalid names as if the parameter were nameless. */
+           if (identifier == error_mark_node)
+             identifier = NULL_TREE;
+         }
        else
          identifier = NULL_TREE;
+
        /* Create the template parameter.  */
        parameter = finish_template_template_parm (class_type_node,
                                                   identifier);
@@ -7846,15 +7866,13 @@ cp_parser_type_parameter (cp_parser* parser)
 
        /* Create the combined representation of the parameter and the
           default argument.  */
-       parameter =  build_tree_list (default_argument, parameter);
+       parameter = build_tree_list (default_argument, parameter);
       }
       break;
 
     default:
-      /* Anything else is an error.  */
-      cp_parser_error (parser,
-                      "expected `class', `typename', or `template'");
-      parameter = error_mark_node;
+      abort ();
+      break;
     }
   
   return parameter;
@@ -10069,7 +10087,7 @@ cp_parser_init_declarator (cp_parser* parser,
       && token->type != CPP_COMMA
       && token->type != CPP_SEMICOLON)
     {
-      cp_parser_error (parser, "expected init-declarator");
+      cp_parser_error (parser, "expected initializer");
       return error_mark_node;
     }
 
@@ -14511,6 +14529,12 @@ cp_parser_single_declaration (cp_parser* parser,
   tree attributes;
   bool function_definition_p = false;
 
+  /* This function is only used when processing a template
+     declaration.  */
+  if (innermost_scope_kind () != sk_template_parms
+      && innermost_scope_kind () != sk_template_spec)
+    abort ();
+
   /* Defer access checks until we know what is being declared.  */
   push_deferring_access_checks (dk_deferred);
 
@@ -14523,6 +14547,14 @@ cp_parser_single_declaration (cp_parser* parser,
                                    &declares_class_or_enum);
   if (friend_p)
     *friend_p = cp_parser_friend_p (decl_specifiers);
+
+  /* There are no template typedefs.  */
+  if (cp_parser_typedef_p (decl_specifiers))
+    {
+      error ("template declaration of `typedef'");
+      decl = error_mark_node;
+    }
+
   /* Gather up the access checks that occurred the
      decl-specifier-seq.  */
   stop_deferring_access_checks ();
@@ -14539,8 +14571,6 @@ cp_parser_single_declaration (cp_parser* parser,
            decl = error_mark_node;
        }
     }
-  else
-    decl = NULL_TREE;
   /* If it's not a template class, try for a template function.  If
      the next token is a `;', then this declaration does not declare
      anything.  But, if there were errors in the decl-specifiers, then
@@ -14566,7 +14596,8 @@ cp_parser_single_declaration (cp_parser* parser,
   parser->object_scope = NULL_TREE;
   /* Look for a trailing `;' after the declaration.  */
   if (!function_definition_p
-      && !cp_parser_require (parser, CPP_SEMICOLON, "`;'"))
+      && (decl == error_mark_node
+         || !cp_parser_require (parser, CPP_SEMICOLON, "`;'")))
     cp_parser_skip_to_end_of_block_or_statement (parser);
 
   return decl;
@@ -15032,6 +15063,27 @@ cp_parser_friend_p (tree decl_specifiers)
   return false;
 }
 
+/* DECL_SPECIFIERS is the representation of a decl-specifier-seq.
+   Returns TRUE iff `typedef' appears among the DECL_SPECIFIERS.  */
+
+static bool
+cp_parser_typedef_p (tree decl_specifiers)
+{
+  while (decl_specifiers)
+    {
+      /* See if this decl-specifier is `typedef'.  */
+      if (TREE_CODE (TREE_VALUE (decl_specifiers)) == IDENTIFIER_NODE
+         && C_RID_CODE (TREE_VALUE (decl_specifiers)) == RID_TYPEDEF)
+       return true;
+
+      /* Go on to the next decl-specifier.  */
+      decl_specifiers = TREE_CHAIN (decl_specifiers);
+    }
+
+  return false;
+}
+
+
 /* If the next token is of the indicated TYPE, consume it.  Otherwise,
    issue an error message indicating that TOKEN_DESC was expected.
    
index c61b26b4134e792398ab1a01244f6e3c0fb292ce..25e512e0608899c01b49ac3ab2a6f9a75cef03d9 100644 (file)
@@ -9166,17 +9166,12 @@ type_unification_real (tree tparms,
          else
            type = arg;
 
-         if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER)
-           {
-             if (same_type_p (parm, type))
-               continue;
-           }
-         else
-           /* It might work; we shouldn't check now, because we might
-              get into infinite recursion.  Overload resolution will
-              handle it.  */
+         if (same_type_p (parm, type))
            continue;
-
+         if (strict != DEDUCE_EXACT
+             && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg))
+           continue;
+         
          return 1;
        }
        
index f15fe793cb6c54a9f8c26f4f7bd1bfeeaf08a370..696d97664c3978c81534771d5589f387fd95c844 100644 (file)
@@ -1,3 +1,27 @@
+2005-07-28  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
+
+       Backport:
+
+       2004-09-16  Mark Mitchell  <mark@codesourcery.com>
+       PR c++/16002
+       * g++.dg/parse/error18.C: New test.
+       * g++.dg/parse/crash11.C: Adjust error markers.
+       
+       2005-06-17  Geoffrey Keating  <geoffk@apple.com>        
+       PR c++/17413
+       * g++.dg/template/local5.C: New.
+
+       2004-11-02  Mark Mitchell  <mark@codesourcery.com>
+       PR c++/18124
+       * g++.dg/template/crash25.C: New test.
+       PR c++/18155
+       * g++.dg/template/typedef2.C: New test.
+       * g++.dg/parse/crash13.C: Adjust error markers.
+
+       2004-12-21  Mark Mitchell  <mark@codesourcery.com>
+       PR c++/18378
+       * g++.dg/ext/packed8.C: New test.
+
 2005-07-28  Richard Sandiford  <richard@codesourcery.com>
 
        PR c/22589
index 4893678d46f27d02a9344f7cc46ab75acc573b20..f988fa8a0bda70f78789671e10ceedf4e6a3b302 100644 (file)
@@ -30,5 +30,5 @@ struct C
 };
 int main()
 {
-  typedef B<C>::Template<void>::Type Type; // { dg-error "init-declarator|;" }
+  typedef B<C>::Template<void>::Type Type; // { dg-error "initializer" }
 }
index d81b6a55e7a6108b04d5be7d35f17d2f026efb93..bd96bd1d6f12516fab7b82c87f1d599ee6fd3bc4 100644 (file)
@@ -13,7 +13,7 @@ struct A
 
 template <typename T> 
 void func(A<T>::B* )   // { dg-error "variable|template|expression" }
-{                      // { dg-error ";" }
+{
 }
 
 int main() 
diff --git a/gcc/testsuite/g++.dg/parse/error18.C b/gcc/testsuite/g++.dg/parse/error18.C
new file mode 100644 (file)
index 0000000..363aae9
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/16002
+
+void f()
+{
+  double Q *= 5.0; // { dg-error "initializer" }
+}
+