aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2007-03-12 16:24:18 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2007-03-12 16:24:18 +0000
commit3026f2dfd9cc61191297488551c287f321375205 (patch)
tree088268aba264edcd21878f750aced0e277f47c33 /gcc
parent6d4817e3740f021599e620067452c223f7b3b397 (diff)
downloadgcc-3026f2dfd9cc61191297488551c287f321375205.zip
gcc-3026f2dfd9cc61191297488551c287f321375205.tar.gz
gcc-3026f2dfd9cc61191297488551c287f321375205.tar.bz2
re PR c++/30108 (internal compiler error: in make_decl_rtl, at varasm.c:890)
PR c++/30108 * call.c (convert_default_arg): Copy non-constant arguments. PR c++/30108 * g++.dg/other/default6.C: New test. From-SVN: r122844
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/call.c10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/other/default6.C18
4 files changed, 35 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index acc6435..ccbb842 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2007-03-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/30108
+ * call.c (convert_default_arg): Copy non-constant arguments.
+
2007-03-11 Mark Mitchell <mark@codesourcery.com>
PR c++/31038
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 637671b..00e0c06 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4664,10 +4664,14 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
}
else
{
- /* This could get clobbered by the following call. */
- if (TREE_HAS_CONSTRUCTOR (arg))
+ /* We must make a copy of ARG, in case subsequent processing
+ alters any part of it. For example, during gimplification a
+ cast of the form (T) &X::f (where "f" is a member function)
+ will lead to replacing the PTRMEM_CST for &X::f with a
+ VAR_DECL. We can avoid the copy for constants, since they
+ are never modified in place. */
+ if (!CONSTANT_CLASS_P (arg))
arg = copy_node (arg);
-
arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
"default argument", fn, parmnum);
arg = convert_for_arg_passing (type, arg);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2c3f7d8..9d0a8df 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-03-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/30108
+ * g++.dg/other/default6.C: New test.
+
2007-03-12 Richard Sandiford <richard@codesourcery.com>
* lib/target-supports.exp (check_profiling_available): Return false
diff --git a/gcc/testsuite/g++.dg/other/default6.C b/gcc/testsuite/g++.dg/other/default6.C
new file mode 100644
index 0000000..2641801
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/default6.C
@@ -0,0 +1,18 @@
+// PR c++/30108
+
+class BaseRobot {
+ typedef void (BaseRobot::*PseudoState)(void);
+ typedef PseudoState STATE;
+ STATE initial ();
+ int ready ();
+ STATE stpOtherTask ();
+ STATE commonEventProcessing (STATE pIdleTarget=(STATE)&BaseRobot::ready);
+};
+BaseRobot::STATE BaseRobot::initial ()
+{
+ return commonEventProcessing ();
+}
+BaseRobot::STATE BaseRobot::stpOtherTask ()
+{
+ return commonEventProcessing ();
+}