From: Jakub Jelinek Date: Sat, 12 Nov 2005 20:42:23 +0000 (+0100) Subject: re PR c++/24761 (templates and inline-asm and "+") X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f74dcfb70183a037feaefaa9e6d491249cbafc2f;p=gcc.git re PR c++/24761 (templates and inline-asm and "+") PR c++/24761 * pt.c (tsubst_copy_asm_operands): New function. (tsubst_expr) : Use it. * g++.dg/template/asm1.C: New test. From-SVN: r106831 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bcbddc7fbd9..5736a0d2445 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2005-11-12 Jakub Jelinek + + PR c++/24761 + * pt.c (tsubst_copy_asm_operands): New function. + (tsubst_expr) : Use it. + 2005-11-08 Jakub Jelinek PR c++/19450 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c2fc36f2dfd..63123c47f97 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8136,6 +8136,39 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) } } +/* Like tsubst_copy_and_build, but unshare TREE_LIST nodes. */ + +static tree +tsubst_copy_asm_operands (tree t, tree args, tsubst_flags_t complain, + tree in_decl) +{ +#define RECUR(t) tsubst_copy_asm_operands (t, args, complain, in_decl) + + tree purpose, value, chain; + + if (t == NULL) + return t; + + if (TREE_CODE (t) != TREE_LIST) + return tsubst_copy_and_build (t, args, complain, in_decl, + /*function_p=*/false); + + if (t == void_list_node) + return t; + + purpose = TREE_PURPOSE (t); + if (purpose) + purpose = RECUR (purpose); + value = TREE_VALUE (t); + if (value) + value = RECUR (value); + chain = TREE_CHAIN (t); + if (chain && chain != void_type_node) + chain = RECUR (chain); + return tree_cons (purpose, value, chain); +#undef RECUR +} + /* Like tsubst_copy for expressions, etc. but also does semantic processing. */ @@ -8353,9 +8386,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) tmp = finish_asm_stmt (ASM_VOLATILE_P (t), tsubst_expr (ASM_STRING (t), args, complain, in_decl), - tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl), - tsubst_expr (ASM_INPUTS (t), args, complain, in_decl), - tsubst_expr (ASM_CLOBBERS (t), args, complain, in_decl)); + tsubst_copy_asm_operands (ASM_OUTPUTS (t), args, complain, in_decl), + tsubst_copy_asm_operands (ASM_INPUTS (t), args, complain, in_decl), + tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl)); { tree asm_expr = tmp; if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9545e764afb..5500af19e5f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-11-12 Jakub Jelinek + + PR c++/24761 + * g++.dg/template/asm1.C: New test. + 2005-11-12 Steven G. Kargl PR libgfortran/24787 diff --git a/gcc/testsuite/g++.dg/template/asm1.C b/gcc/testsuite/g++.dg/template/asm1.C new file mode 100644 index 00000000000..741759fd2f4 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/asm1.C @@ -0,0 +1,14 @@ +// PR c++/24761 +// { dg-do compile } + +template +int f (int i) +{ + asm ("# %0 %1" : "+r" (i)); + return i; +} + +int main () +{ + return f<0> (0) + f<1> (0); +}