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 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 {

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