aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVolker Reichelt <reichelt@igpm.rwth-aachen.de>2006-01-19 09:51:57 +0000
committerVolker Reichelt <reichelt@gcc.gnu.org>2006-01-19 09:51:57 +0000
commit607c855eb7fbf6b876250fe3e580125e7bf438d6 (patch)
treeb6b738bfc0105ccb758373d329ad2bae1de1c072 /gcc
parent1f0f7cebf9eccfa3c9bac5c2602a261c487c86d2 (diff)
downloadgcc-607c855eb7fbf6b876250fe3e580125e7bf438d6.zip
gcc-607c855eb7fbf6b876250fe3e580125e7bf438d6.tar.gz
gcc-607c855eb7fbf6b876250fe3e580125e7bf438d6.tar.bz2
re PR c++/16829 (default parameter can be not one of the last in function)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/decl.c4
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/name-lookup.c8
-rw-r--r--gcc/cp/parser.c3
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/other/default2.C9
-rw-r--r--gcc/testsuite/g++.dg/other/default3.C109
8 files changed, 145 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b386ef4..981976f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 48e985c..ae0b7e8 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
}
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 9408c8a..637ac8c 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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;
}
}
}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 02fc272..4a2482f 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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);
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ec4c2ea..d2b41e5 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ca243bc..5a5e470 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..be0e5c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/default2.C
@@ -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
index 0000000..324ba71
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/default3.C
@@ -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" }