From 0eb004033027f53a641f56c869669cee5656d892 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Fri, 29 Aug 2003 23:11:14 +0000 Subject: [PATCH] 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 --- gcc/cp/pt.c | 2 ++ gcc/cp/semantics.c | 18 +++++++++++------- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/ext/label1.C | 8 ++++++++ gcc/testsuite/g++.dg/ext/label2.C | 11 +++++++++++ 5 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/label1.C create mode 100644 gcc/testsuite/g++.dg/ext/label2.C 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 + + PR c++/6196 + * g++.dg/ext/label1.C: New test. + * g++.dg/ext/label2.C: Likewise. + 2003-08-28 Mark Mitchell * 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 +void f() { + l: + void *p[] = { &&l }; + + goto *p; +} + +template void f(); -- 2.11.4.GIT