This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] PR21210: Default construction of complex types


The following patch is my proposed solution to PR c++/21210 which
is a rejects-valid regression in all gcc 4.x.  The issue is that
when a constructor of a non-aggregate type is given without an
argument, the instance should be zero initialized.  This is implemented
in the C++ front-end by casting integer zero to the appropriate type.

The problem is that the code in build_functional argument currently uses
build_c_cast, which is a user-level/parser level function for this
conversion, and issues an error as an integer zero can't be explicitly
cast to a complex floating point type in user code.  As Mark points
out in the PR, if the C++ standard is clarrified/changed to accept
this, the problem will go away.

The approach used below is to use a different (lower-level) conversion
routine when the user hasn't explicitly specified an initial value,
which avoids this problem and the resulting bogus error message about
converting from "int", when the source code doesn't mention any ints.
Possibilities including using "fold_convert", "convert" or "ocp_convert"
as the lower-level routine but I think the correct choice in this context
is "cp_convert".

Unfortunately, I don't have a convenient copy of the C++ standard to
know whether this keeps with the precise wording of the standard, but
its within its spirit as without GCC's complex number extensions all
non-aggegrate types probably can be converted from integer zero without
problems using an explicit C-style cast.

The following patch has been tested on x86_64-unknown-linux-gnu with a
full "make bootstrap", all default languages, and regression tested with
a top-level "make -k check" with no new failures.

Ok for mainline, and the open branches after a while?



2006-06-07  Roger Sayle  <roger@eyesopen.com>

	PR c++/21210
	* typeck2.c (build_functional_cast): Use cp_convert to construct
	non-aggregate initializers instead of the user-level build_c_cast.

	* g++.dg/init/complex1.C: New test case.


Index: typeck2.c
===================================================================
*** typeck2.c	(revision 114381)
--- typeck2.c	(working copy)
*************** build_functional_cast (tree exp, tree pa
*** 1299,1310 ****

    if (! IS_AGGR_TYPE (type))
      {
-       /* This must build a C cast.  */
        if (parms == NULL_TREE)
! 	parms = integer_zero_node;
!       else
! 	parms = build_x_compound_expr_from_list (parms, "functional cast");

        return build_c_cast (type, parms);
      }

--- 1299,1309 ----

    if (! IS_AGGR_TYPE (type))
      {
        if (parms == NULL_TREE)
! 	return cp_convert (type, integer_zero_node);

+       /* This must build a C cast.  */
+       parms = build_x_compound_expr_from_list (parms, "functional cast");
        return build_c_cast (type, parms);
      }



/* PR c++/21210 */
/* { dg-do compile } */
/* { dg-options "-O2" } */

typedef float __complex__ fcomplex;
fcomplex cplx = fcomplex();


Roger
--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]