[PATCH] Fix PR c++/69961 (invalid ctor call with dependent args)

Patrick Palka patrick@parcs.ath.cx
Sun Feb 28 18:56:00 GMT 2016


In r233563 (where I applied the 2nd version of the fix for PR c++/68948)
I shouldn't have reverted the original fix because it is still required
for diagnosing an invalid constructor call with dependent arguments
(because in that case we delay further processing of the call until
instantiation).  Otherwise we end up with an error_mark_node in place of
the constructor call without ever emitting an error message.

This patch adds back in the check in tsubst_baselink which was removed.
One minor caveat about this check is that it emits an error instead of a
permerror because I'm not sure how to correctly recover from this error
here.

Bootstrapped and tested on x86_64-pc-linux gnu.  Does this look ok to
commit?

gcc/cp/ChangeLog:

	PR c++/68948
	PR c++/69961
	* pt.c (tsubst_baselink): Reinstate the check for an invalid
	constructor call.

gcc/testsuite/ChangeLog:

	PR c++/69961
	* g++.dg/template/pr69961a.C: New test.
	* g++.dg/template/pr69961b.C: New test.
---
 gcc/cp/pt.c                              | 10 +++++++++-
 gcc/testsuite/g++.dg/template/pr69961a.C | 25 +++++++++++++++++++++++++
 gcc/testsuite/g++.dg/template/pr69961b.C | 15 +++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/template/pr69961a.C
 create mode 100644 gcc/testsuite/g++.dg/template/pr69961b.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 12cb788..a7d2288 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -13607,7 +13607,15 @@ tsubst_baselink (tree baselink, tree object_type,
       name = mangle_conv_op_name_for_type (optype);
     baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
     if (!baselink)
-      return error_mark_node;
+      {
+	if (constructor_name_p (name, qualifying_scope))
+	  {
+	    if (complain & tf_error)
+	      error ("cannot call constructor %<%T::%D%> directly",
+		     qualifying_scope, name);
+	  }
+	return error_mark_node;
+      }
 
     /* If lookup found a single function, mark it as used at this
        point.  (If it lookup found multiple functions the one selected
diff --git a/gcc/testsuite/g++.dg/template/pr69961a.C b/gcc/testsuite/g++.dg/template/pr69961a.C
new file mode 100644
index 0000000..b0c5d41
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr69961a.C
@@ -0,0 +1,25 @@
+// PR c++/69961
+// { dg-do compile { target c++11 } }
+
+#include <string>
+
+using std::string;
+
+class Format {
+ public:
+  explicit Format(string formatted) {}
+  string buffer;
+};
+
+string StrCat(const string& a) {
+  return "";
+}
+
+template <typename... AV>
+Format Message(string msg, const AV&... args) {
+  return Format::Format(StrCat(msg, args...)); // { dg-error "cannot call constructor" }
+}
+
+int main(int, char**) {
+  Message("msg");
+}
diff --git a/gcc/testsuite/g++.dg/template/pr69961b.C b/gcc/testsuite/g++.dg/template/pr69961b.C
new file mode 100644
index 0000000..5fff1c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr69961b.C
@@ -0,0 +1,15 @@
+// PR c++/69961
+
+struct A { A (int); };
+
+template <typename T>
+void foo ()
+{
+  A::A ((T)0); // { dg-error "cannot call constructor .A::A. directly" }
+}
+
+void
+bar ()
+{
+  foo<int> ();
+}
-- 
2.8.0.rc0.11.g9bfbc33



More information about the Gcc-patches mailing list