diff options
Diffstat (limited to 'gcc')
-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 45bec17..ff3518e 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 ee80bee..c38bdd3 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 ea39a5d..7b983d8 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 0000000..8c6684d --- /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 0000000..1b66f60 --- /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>(); |