]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/16829 (default parameter can be not one of the last in function)
authorVolker Reichelt <reichelt@igpm.rwth-aachen.de>
Thu, 19 Jan 2006 09:51:57 +0000 (09:51 +0000)
committerVolker Reichelt <reichelt@gcc.gnu.org>
Thu, 19 Jan 2006 09:51:57 +0000 (09:51 +0000)
PR c++/16829
* decl.c (start_preparsed_function): Check default arguments
unconditionally.
* name-lookup.c (pushdecl_maybe_friend): Check default arguments
of all functions and function templates.
* parser.c (cp_parser_late_parsing_default_args): Check default
arguments.
* decl2.c (check_default_args): Set missing default arguments to
error_mark_node.

* g++.dg/other/default2.C: New test.
* g++.dg/other/default3.C: New test.

From-SVN: r109950

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/default2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/other/default3.C [new file with mode: 0644]

index b386ef4e66fd7682fb3487d958af474db7fb27e2..981976f2821bb7495ac07b7a8fa2d635dc55a2f0 100644 (file)
@@ -1,3 +1,15 @@
+2006-01-19  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+
+       PR c++/16829
+       * decl.c (start_preparsed_function): Check default arguments
+       unconditionally.
+       * name-lookup.c (pushdecl_maybe_friend): Check default arguments
+       of all functions and function templates.
+       * parser.c (cp_parser_late_parsing_default_args): Check default
+       arguments.
+       * decl2.c (check_default_args): Set missing default arguments to
+       error_mark_node.
+
 2006-01-18  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/25836
index 48e985c5f42a1218c913a910b98922c4ded1e693..ae0b7e85c4410c670515c0ba4bfde3bed1ddd389 100644 (file)
@@ -10217,6 +10217,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
      you declare a function, these types can be incomplete, but they
      must be complete when you define the function.  */
   check_function_type (decl1, current_function_parms);
+  /* Make sure no default arg is missing.  */
+  check_default_args (decl1);
 
   /* Build the return declaration for the function.  */
   restype = TREE_TYPE (fntype);
@@ -10283,8 +10285,6 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
          /* We need to set the DECL_CONTEXT.  */
          if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1))
            DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1));
-         /* And make sure we have enough default args.  */
-         check_default_args (decl1);
        }
       fntype = TREE_TYPE (decl1);
     }
index 9408c8acc8827aa3c5cd7d542eaaa649c37c5e91..637ac8c9de70ea81f003197184f0d863ee2f37e3 100644 (file)
@@ -3228,7 +3228,7 @@ check_default_args (tree x)
       else if (saw_def)
        {
          error ("default argument missing for parameter %P of %q+#D", i, x);
-         break;
+         TREE_PURPOSE (arg) = error_mark_node;
        }
     }
 }
index 02fc27277a310912c9aad7a8c20b129b434b6d3d..4a2482f588064994ec615708d576c0492df410d5 100644 (file)
@@ -602,6 +602,9 @@ pushdecl_maybe_friend (tree x, bool is_friend)
     {
       int different_binding_level = 0;
 
+      if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
+       check_default_args (x);
+
       if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
        name = TREE_OPERAND (name, 0);
 
@@ -710,8 +713,6 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                {
                  if (TREE_CODE (t) == TYPE_DECL)
                    SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
-                 else if (TREE_CODE (t) == FUNCTION_DECL)
-                   check_default_args (t);
 
                  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
                }
@@ -994,9 +995,6 @@ pushdecl_maybe_friend (tree x, bool is_friend)
            }
        }
 
-      if (TREE_CODE (x) == FUNCTION_DECL)
-       check_default_args (x);
-
       if (TREE_CODE (x) == VAR_DECL)
        maybe_register_incomplete_var (x);
     }
index ec4c2ea5bc5facb923ec3ee10ca573873025a712..d2b41e5c39d6f3141d11b72da729d8caff666a37 100644 (file)
@@ -15833,6 +15833,9 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
       cp_parser_pop_lexer (parser);
     }
 
+  /* Make sure no default arg is missing.  */
+  check_default_args (fn);
+
   /* Restore the state of local_variables_forbidden_p.  */
   parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
 
index ca243bcbd860dc4501018196864802b190515c96..5a5e470411d4fec160c9358da33989fc246034ed 100644 (file)
@@ -1,3 +1,9 @@
+2006-01-19  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+
+       PR c++/16829
+       * g++.dg/other/default2.C: New test.
+       * g++.dg/other/default3.C: New test.
+
 2006-01-19  Richard Sandiford  <richard@codesourcery.com>
 
        PR c/25805
diff --git a/gcc/testsuite/g++.dg/other/default2.C b/gcc/testsuite/g++.dg/other/default2.C
new file mode 100644 (file)
index 0000000..be0e5c3
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/16829
+// { dg-do "compile" }
+
+template<typename T> void foo(T, int = 0, int) {}  // { dg-error "default" }
+
+void bar()
+{
+  foo(0);
+}
diff --git a/gcc/testsuite/g++.dg/other/default3.C b/gcc/testsuite/g++.dg/other/default3.C
new file mode 100644 (file)
index 0000000..324ba71
--- /dev/null
@@ -0,0 +1,109 @@
+// PR c++/16829
+// { dg-do "compile" }
+
+void f1(int = 0, int);                       // { dg-error "default" }
+
+void f2(int = 0, int) {}                     // { dg-error "default" }
+
+void f3(int, int);
+void f3(int = 0, int);                       // { dg-error "default" }
+
+void f4(int, int);
+void f4(int = 0, int) {}                     // { dg-error "default" }
+
+void f5();
+void f5(int = 0, int);                       // { dg-error "default" }
+
+void f6();
+void f6(int = 0, int) {}                     // { dg-error "default" }
+
+template<typename> void g1(int = 0, int);    // { dg-error "default" }
+
+template<typename> void g2(int = 0, int) {}  // { dg-error "default" }
+
+template<typename> void g3(int, int);
+template<typename> void g3(int = 0, int);    // { dg-error "default" }
+
+template<typename> void g4(int, int);
+template<typename> void g4(int = 0, int) {}  // { dg-error "default" }
+
+template<typename> void g5();
+template<typename> void g5(int = 0, int);    // { dg-error "default" }
+
+template<typename> void g6();
+template<typename> void g6(int = 0, int) {}  // { dg-error "default" }
+
+template<typename T> void g7(T, T)   {}
+template<typename T> void g7(T* = 0, T*) {}  // { dg-error "default" }
+
+
+struct A
+{
+  void F1(int = 0, int);                       // { dg-error "default" }
+
+  void F2(int = 0, int) {}                     // { dg-error "default" }
+
+  void F3(int, int);
+
+  void F4();
+  void F4(int = 0, int);                       // { dg-error "default" }
+
+  void F5();
+  void F5(int = 0, int) {}                     // { dg-error "default" }
+
+  template<typename> void G1(int = 0, int);    // { dg-error "default" }
+
+  template<typename> void G2(int = 0, int) {}  // { dg-error "default" }
+
+  template<typename> void G3(int, int);
+
+  template<typename> void G4();
+  template<typename> void G4(int = 0, int);    // { dg-error "default" }
+
+  template<typename> void G5();
+  template<typename> void G5(int = 0, int) {}  // { dg-error "default" }
+
+  template<typename T> void G6(T, T)   {}
+  template<typename T> void G6(T* = 0, T*) {}  // { dg-error "default" }
+};
+
+void A::F3(int = 0, int) {}                     // { dg-error "default" }
+
+template<typename> void A::G3(int = 0, int) {}  // { dg-error "default" }
+
+
+template<typename> struct B
+{
+  void F1(int = 0, int);                       // { dg-error "default" }
+
+  void F2(int = 0, int) {}                     // { dg-error "default" }
+
+  void F3(int, int);
+
+  void F4();
+  void F4(int = 0, int);                       // { dg-error "default" }
+
+  void F5();
+  void F5(int = 0, int) {}                     // { dg-error "default" }
+
+  template<typename> void G1(int = 0, int);    // { dg-error "default" }
+
+  template<typename> void G2(int = 0, int) {}  // { dg-error "default" }
+
+  template<typename> void G3(int, int);
+
+  template<typename> void G4();
+  template<typename> void G4(int = 0, int);    // { dg-error "default" }
+
+  template<typename> void G5();
+  template<typename> void G5(int = 0, int) {}  // { dg-error "default" }
+
+  template<typename T> void G6(T, T)   {}
+  template<typename T> void G6(T* = 0, T*) {}  // { dg-error "default" }
+};
+
+template<typename T>
+void B<T>::F3(int = 0, int) {}  // { dg-error "default" }
+
+template<typename T> template<typename>
+void B<T>::G3(int = 0, int) {}  // { dg-error "default" }