From: Mark Mitchell Date: Fri, 29 Aug 2003 23:11:14 +0000 (+0000) Subject: re PR middle-end/6196 (ICE in copy_to_mode_reg, at explow.c:711) X-Git-Tag: releases/gcc-3.4.0~3985 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fc2b84778bb51750c841f53b1ba30950935cc901;p=thirdparty%2Fgcc.git re PR middle-end/6196 (ICE in copy_to_mode_reg, at explow.c:711) 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. From-SVN: r70932 --- diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 45bec17520c3..ff3518e069a3 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 ee80beefad6a..c38bdd3681a0 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 ea39a5d6cacf..7b983d8e743b 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 000000000000..8c6684dce0e7 --- /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 000000000000..1b66f603fe46 --- /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();