diff options
author | Jason Merrill <jason@redhat.com> | 2014-03-05 12:53:28 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2014-03-05 12:53:28 -0500 |
commit | 5d264d62dc6d381510bea36469d50175fa6a39c2 (patch) | |
tree | e3868b266a6078ee25388808cfde2edd0ca93c82 /gcc | |
parent | 047023865e1edc63c708fb0f4475958119955928 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 7 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/ambig7.C | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/parameter-declaration-2.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/typename7.C | 6 |
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" } }; |