This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/42415 (bad assembly output for explicit constructor call)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 18 Dec 2009 11:15:32 -0500
- Subject: C++ PATCH for c++/42415 (bad assembly output for explicit constructor call)
DR 147 changed A::A() from a functional cast to an (ill-formed) direct
call to the constructor. In the testcase for 42415 we weren't catching
the ill-formedness and therefore generated a call to the maybe-in-charge
constructor which doesn't really exist.
Fixed thus. -fpermissive will allow the testcase to compile as in 4.4,
with a warning.
Tested x86_64-pc-linux-gnu, applied to trunk.
commit 34b37ddc7db7b17f394fa88513f243ba64e570a6
Author: Jason Merrill <jason@redhat.com>
Date: Fri Dec 18 10:06:16 2009 -0500
PR c++/42415
* call.c (build_new_method_call): Complain about calling the
constructor directly.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 0ed3383..67f4465 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6239,6 +6239,25 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
make_args_non_dependent (*args);
}
+ user_args = args == NULL ? NULL : *args;
+ /* Under DR 147 A::A() is an invalid constructor call,
+ not a functional cast. */
+ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
+ {
+ if (! (complain & tf_error))
+ return error_mark_node;
+
+ permerror (input_location,
+ "cannot call constructor %<%T::%D%> directly",
+ basetype, name);
+ inform (input_location, "for a function-style cast, remove the "
+ "redundant %<::%D%>", name);
+ call = build_functional_cast (basetype, build_tree_list_vec (user_args),
+ complain);
+ release_tree_vector (user_args);
+ return call;
+ }
+
/* Figure out whether to skip the first argument for the error
message we will display to users if an error occurs. We don't
want to display any compiler-generated arguments. The "this"
@@ -6246,7 +6265,6 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
pointer if this is a call to a base-class constructor or
destructor. */
skip_first_for_error = false;
- user_args = args == NULL ? NULL : *args;
if (IDENTIFIER_CTOR_OR_DTOR_P (name))
{
/* Callers should explicitly indicate whether they want to construct
diff --git a/gcc/testsuite/g++.dg/tc1/dr147.C b/gcc/testsuite/g++.dg/tc1/dr147.C
index 9006be9..a29986b 100644
--- a/gcc/testsuite/g++.dg/tc1/dr147.C
+++ b/gcc/testsuite/g++.dg/tc1/dr147.C
@@ -4,7 +4,7 @@
namespace N1 {
-struct A { A(); };
+struct A { A(); void f(); };
struct B: public A { B(); };
A::A() { }
@@ -13,10 +13,15 @@ B::B() { }
B::A ba;
A::A a; // { dg-error "constructor" "the injected-class-name can never be found through qualified lookup" }
+void A::f()
+{
+ A::A(); // { dg-message "::A" "c++/42415" }
+}
+
void f()
{
A::A a; // { dg-error "constructor" }
-} // { dg-error "" "" { target *-*-* } 18 } error cascade
+} // { dg-error "" "" { target *-*-* } 23 } error cascade
}
namespace N2 {