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

Reply via email to