diff options
| author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-08-29 23:11:14 +0000 |
|---|---|---|
| committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-08-29 23:11:14 +0000 |
| commit | 0eb004033027f53a641f56c869669cee5656d892 (patch) | |
| tree | 9804609df286984088c3db599152fdef7af2c07f | |
| parent | 9197503feb1ae04f7e5b952003aa94aeb0390419 (diff) | |
| download | ppe42-gcc-0eb004033027f53a641f56c869669cee5656d892.tar.gz ppe42-gcc-0eb004033027f53a641f56c869669cee5656d892.zip | |
PR c++/6196
* pt.c (tsubst_copy_and_build): Correct handling of
address-of-label extension.
* semantics.c (finish_goto_stmt): The address of a label must go
through the lvalue-to-rvalue conversion.
PR c++/6196
* g++.dg/ext/label1.C: New test.
* g++.dg/ext/label2.C: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70932 138bc75d-0d04-0410-961f-82ee72b054a4
| -rw-r--r-- | gcc/cp/pt.c | 2 | ||||
| -rw-r--r-- | gcc/cp/semantics.c | 18 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
| -rw-r--r-- | gcc/testsuite/g++.dg/ext/label1.C | 8 | ||||
| -rw-r--r-- | gcc/testsuite/g++.dg/ext/label2.C | 11 |
5 files changed, 38 insertions, 7 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 45bec17520c..ff3518e069a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7972,6 +7972,8 @@ tsubst_copy_and_build (tree t, else op1 = tsubst_non_call_postfix_expression (op1, args, complain, in_decl); + if (TREE_CODE (op1) == LABEL_DECL) + return finish_label_address_expr (DECL_NAME (op1)); return build_x_unary_op (ADDR_EXPR, op1); case PLUS_EXPR: diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index ee80beefad6..c38bdd3681a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -378,13 +378,17 @@ finish_goto_stmt (tree destination) mark the used labels as used. */ if (TREE_CODE (destination) == LABEL_DECL) TREE_USED (destination) = 1; - - if (TREE_CODE (destination) != LABEL_DECL) - /* We don't inline calls to functions with computed gotos. - Those functions are typically up to some funny business, - and may be depending on the labels being at particular - addresses, or some such. */ - DECL_UNINLINABLE (current_function_decl) = 1; + else + { + /* The DESTINATION is being used as an rvalue. */ + if (!processing_template_decl) + destination = decay_conversion (destination); + /* We don't inline calls to functions with computed gotos. + Those functions are typically up to some funny business, + and may be depending on the labels being at particular + addresses, or some such. */ + DECL_UNINLINABLE (current_function_decl) = 1; + } check_goto (destination); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ea39a5d6cac..7b983d8e743 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2003-08-29 Mark Mitchell <mark@codesourcery.com> + + PR c++/6196 + * g++.dg/ext/label1.C: New test. + * g++.dg/ext/label2.C: Likewise. + 2003-08-28 Mark Mitchell <mark@codesourcery.com> * g++.dg/expr/cond3.C: New test. diff --git a/gcc/testsuite/g++.dg/ext/label1.C b/gcc/testsuite/g++.dg/ext/label1.C new file mode 100644 index 00000000000..8c6684dce0e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label1.C @@ -0,0 +1,8 @@ +// { dg-options "" } + +int main(void) { + static const void* lbls[2][2] = {{&&lbl0, &&lbl0}, {&&lbl0, &&lbl0}}; + goto *lbls[0]; + lbl0: + ; +} diff --git a/gcc/testsuite/g++.dg/ext/label2.C b/gcc/testsuite/g++.dg/ext/label2.C new file mode 100644 index 00000000000..1b66f603fe4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/label2.C @@ -0,0 +1,11 @@ +// { dg-options "" } + +template <typename T> +void f() { + l: + void *p[] = { &&l }; + + goto *p; +} + +template void f<int>(); |

