diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 1db60367918655ba12c58f72e20e217e74fd2265..9442f687e8d9175a3aafa9a4e2d577e643b67a82 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2006-11-28  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/29976
+	* trans-expr.c (gfc_conv_missing_dummy): Remove build_int_const
+	and replace with cast to type of se->expr of integer_zero_node.
+
 2006-11-28  Paul Thomas  <pault@gcc.gnu.org>
 
 	PR fortran/20880
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 8e1dcc13f3fe81207df9922c391b60ed7ef9b401..d5040431f1c98d6cd951fd7a82555e2a2a729d73 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -153,7 +153,8 @@ gfc_conv_missing_dummy (gfc_se * se, gfc_expr * arg, gfc_typespec ts)
 
   present = gfc_conv_expr_present (arg->symtree->n.sym);
   tmp = build3 (COND_EXPR, TREE_TYPE (se->expr), present, se->expr,
-		build_int_cst (TREE_TYPE (se->expr), 0));
+		fold_convert (TREE_TYPE (se->expr), integer_zero_node));
+
   tmp = gfc_evaluate_now (tmp, &se->pre);
   se->expr = tmp;
   if (ts.type == BT_CHARACTER)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 89b0464f272349416ea8ddc36361d76996eaed11..5c87db9650346c69c5de74b25d7cabeb9b9c98fa 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-11-28  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/29976
+	* gfortran.dg/missing_optional_dummy_3.f90
+
 2006-11-28  Paul Thomas  <pault@gcc.gnu.org>
 
 	PR fortran/20880
diff --git a/gcc/testsuite/gfortran.dg/missing_optional_dummy_3.f90 b/gcc/testsuite/gfortran.dg/missing_optional_dummy_3.f90
new file mode 100644
index 0000000000000000000000000000000000000000..d330ddaea8f43fa163b7872d90877d3415e877a8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/missing_optional_dummy_3.f90
@@ -0,0 +1,32 @@
+! { dg-do compile }
+! Tests the fix for PR29976, in which the call to CMPLX caused an
+! ICE with an optional dummy for the imaginary part.
+!
+! Contributed by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+!
+SUBROUTINE pw_sumup (alpha_im)
+  REAL, INTENT(in), OPTIONAL :: alpha_im
+  COMPLEX :: my_alpha_c
+  IF (PRESENT(alpha_im)) THEN
+     my_alpha_c = CMPLX(0.,alpha_im)
+  END IF
+END SUBROUTINE pw_sumup
+
+! Check non-intrinsic functions.
+SUBROUTINE pw_sumup_2 (alpha_im)
+  REAL, INTENT(in), OPTIONAL :: alpha_im
+  COMPLEX :: my_alpha_c
+  IF (PRESENT(alpha_im)) THEN
+     my_alpha_c = MY_CMPLX(0.,alpha_im)
+  END IF
+contains
+  complex function MY_CMPLX (re, im)
+    real, intent(in) :: re
+    real, intent(in), optional :: im
+    if (present (im)) then 
+      MY_CMPLX = cmplx (re, im)
+    else
+      MY_CMPLX = cmplx (re, 0.0)
+    end if
+  end function MY_CMPLX
+END SUBROUTINE pw_sumup_2