aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-08-29 23:11:14 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-08-29 23:11:14 +0000
commitfc2b84778bb51750c841f53b1ba30950935cc901 (patch)
tree9804609df286984088c3db599152fdef7af2c07f
parentd560a41c5c43524d82795ac4421eab2df6764e30 (diff)
downloadgcc-fc2b84778bb51750c841f53b1ba30950935cc901.zip
gcc-fc2b84778bb51750c841f53b1ba30950935cc901.tar.gz
gcc-fc2b84778bb51750c841f53b1ba30950935cc901.tar.bz2
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
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/semantics.c18
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/ext/label1.C8
-rw-r--r--gcc/testsuite/g++.dg/ext/label2.C11
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>();