aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-03-05 12:53:28 -0500
committerJason Merrill <jason@gcc.gnu.org>2014-03-05 12:53:28 -0500
commit5d264d62dc6d381510bea36469d50175fa6a39c2 (patch)
treee3868b266a6078ee25388808cfde2edd0ca93c82 /gcc
parent047023865e1edc63c708fb0f4475958119955928 (diff)
downloadgcc-5d264d62dc6d381510bea36469d50175fa6a39c2.zip
gcc-5d264d62dc6d381510bea36469d50175fa6a39c2.tar.gz
gcc-5d264d62dc6d381510bea36469d50175fa6a39c2.tar.bz2
re PR c++/60361 (unexpected 'use of parameter outside function body' error)
PR c++/60361 * parser.c (cp_parser_template_id): Don't set up a CPP_TEMPLATE_ID if re-parsing might succeed. * semantics.c (finish_id_expression): Use of a parameter outside the function body is a parse error. From-SVN: r208351
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c7
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/testsuite/g++.dg/parse/ambig7.C16
-rw-r--r--gcc/testsuite/g++.dg/parse/parameter-declaration-2.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/typename7.C6
6 files changed, 32 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 379ac73..9e7b9b7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2014-03-05 Jason Merrill <jason@redhat.com>
+ PR c++/60361
+ * parser.c (cp_parser_template_id): Don't set up a CPP_TEMPLATE_ID
+ if re-parsing might succeed.
+ * semantics.c (finish_id_expression): Use of a parameter outside
+ the function body is a parse error.
+
* parser.c (cp_parser_mem_initializer): Set input_location
properly for init-list warning.
(cp_parser_postfix_open_square_expression): Likewise.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 5b3e489..b56870d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -13466,7 +13466,12 @@ cp_parser_template_id (cp_parser *parser,
the effort required to do the parse, nor will we issue duplicate
error messages about problems during instantiation of the
template. */
- if (start_of_id)
+ if (start_of_id
+ /* Don't do this if we had a parse error in a declarator; re-parsing
+ might succeed if a name changes meaning (60361). */
+ && !(cp_parser_error_occurred (parser)
+ && cp_parser_parsing_tentatively (parser)
+ && parser->in_declarator_p))
{
cp_token *token = cp_lexer_token_at (parser->lexer, start_of_id);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 787eab8..4081e0e 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3246,7 +3246,7 @@ finish_id_expression (tree id_expression,
&& DECL_CONTEXT (decl) == NULL_TREE
&& !cp_unevaluated_operand)
{
- error ("use of parameter %qD outside function body", decl);
+ *error_msg = "use of parameter outside function body";
return error_mark_node;
}
}
diff --git a/gcc/testsuite/g++.dg/parse/ambig7.C b/gcc/testsuite/g++.dg/parse/ambig7.C
new file mode 100644
index 0000000..9a5b879
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/ambig7.C
@@ -0,0 +1,16 @@
+// PR c++/60361
+
+struct Helper
+{
+ Helper(int a, void (*pfunc)());
+};
+
+template <int I> void function();
+
+const int A = 1;
+const int B = 2;
+
+Helper testOk(A, function<A>);
+Helper testOk2(int(A), function<B>);
+Helper testOk3((int(A)), function<A>);
+Helper testFail(int(A), function<A>);
diff --git a/gcc/testsuite/g++.dg/parse/parameter-declaration-2.C b/gcc/testsuite/g++.dg/parse/parameter-declaration-2.C
index 6116630..3c983cc 100644
--- a/gcc/testsuite/g++.dg/parse/parameter-declaration-2.C
+++ b/gcc/testsuite/g++.dg/parse/parameter-declaration-2.C
@@ -1,2 +1,2 @@
-void f (int i, int p[i]); // { dg-error "use of parameter .i. outside function body" }
+void f (int i, int p[i]); // { dg-error "use of parameter.*outside function body" }
// { dg-prune-output "array bound" }
diff --git a/gcc/testsuite/g++.dg/parse/typename7.C b/gcc/testsuite/g++.dg/parse/typename7.C
index 6ec7696..e49a1ec 100644
--- a/gcc/testsuite/g++.dg/parse/typename7.C
+++ b/gcc/testsuite/g++.dg/parse/typename7.C
@@ -7,10 +7,9 @@
struct A
{
- template<typename> void foo(int); // { dg-message "note" }
- template<typename T> void bar(T t) { // { dg-message "note" }
+ template<typename> void foo(int);
+ template<typename T> void bar(T t) {
this->foo<typename T>(t); } // { dg-error "expected|parse error|no matching" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 12 }
template<typename T> void bad(T t) {
foo<typename T>(t); } // { dg-error "expected|parse error|no matching" }
};
@@ -20,7 +19,6 @@ struct B
{
void bar(T t) {
A().bar<typename T>(t); } // { dg-error "expected|parse error|no matching" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 22 }
void bad(T t) {
B<typename T>::bar(t); } // { dg-error "invalid|qualified-id|not a template" }
};