diff mbox series

C++ PATCH to default argument conversion and SFINAE

Message ID CADzB+2kuXMo073UrLQUMDk3pdC48miOMe7XrUcLUbSDGZrTuYQ@mail.gmail.com
State New
Headers show
Series C++ PATCH to default argument conversion and SFINAE | expand

Commit Message

Jason Merrill Aug. 29, 2017, 6:37 p.m. UTC
A Core working group discussion noted that G++ was getting
__is_constructible wrong in this case, where the conversion from
nullptr to the parameter type fails, but we weren't noticing that and
so happily built up a CALL_EXPR with an ERROR_MARK argument.

When that is fixed, we can change the parser to remember an erroneous
default argument to improve error recovery.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 6d165eb63bbd0cd4f312b89f2711f15d48a4411a
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Aug 15 15:29:23 2017 -0700

            Fix default argument conversion failure and SFINAE.
    
            * call.c (build_over_call): Check convert_default_arg result for
            error_mark_node.
            * parser.c (cp_parser_late_parsing_default_args): Remember
            error_mark_node.
diff mbox series

Patch

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 067db59a..6405be2 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7892,10 +7892,13 @@  build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
     {
       if (TREE_VALUE (parm) == error_mark_node)
 	return error_mark_node;
-      argarray[j++] = convert_default_arg (TREE_VALUE (parm),
-					   TREE_PURPOSE (parm),
-					   fn, i - is_method,
-					   complain);
+      val = convert_default_arg (TREE_VALUE (parm),
+				 TREE_PURPOSE (parm),
+				 fn, i - is_method,
+				 complain);
+      if (val == error_mark_node)
+        return error_mark_node;
+      argarray[j++] = val;
     }
 
   /* Ellipsis */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b849824..9b7c2c0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -27645,11 +27645,6 @@  cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
 	= cp_parser_late_parse_one_default_arg (parser, parmdecl,
 						default_arg,
 						TREE_VALUE (parm));
-      if (parsed_arg == error_mark_node)
-	{
-	  continue;
-	}
-
       TREE_PURPOSE (parm) = parsed_arg;
 
       /* Update any instantiations we've already created.  */
diff --git a/gcc/testsuite/g++.dg/ext/is_constructible1.C b/gcc/testsuite/g++.dg/ext/is_constructible1.C
new file mode 100644
index 0000000..b80ac28
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_constructible1.C
@@ -0,0 +1,6 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+template<class T> struct Foo { Foo(T = nullptr) {} };
+
+static_assert (!__is_constructible(Foo<int>));
diff --git a/gcc/testsuite/g++.dg/other/new1.C b/gcc/testsuite/g++.dg/other/new1.C
index 7138370..30b6513 100644
--- a/gcc/testsuite/g++.dg/other/new1.C
+++ b/gcc/testsuite/g++.dg/other/new1.C
@@ -10,5 +10,5 @@  struct A
 
 void foo()
 {
-  new A;	// { dg-error "default argument" }
+  new A;
 }
diff --git a/gcc/testsuite/g++.dg/parse/crash40.C b/gcc/testsuite/g++.dg/parse/crash40.C
index df352dd..537cdb7 100644
--- a/gcc/testsuite/g++.dg/parse/crash40.C
+++ b/gcc/testsuite/g++.dg/parse/crash40.C
@@ -37,6 +37,6 @@  void bar()
   int i;
   i.C::foo<0>(); /* { dg-error "which is of non-class type" } */
 
-  S<false> s; /* { dg-error "default argument" } */
+  S<false> s;
   SS<false> ss;
 }
diff --git a/gcc/testsuite/g++.dg/parse/defarg12.C b/gcc/testsuite/g++.dg/parse/defarg12.C
index 2d2d7e7..df80581 100644
--- a/gcc/testsuite/g++.dg/parse/defarg12.C
+++ b/gcc/testsuite/g++.dg/parse/defarg12.C
@@ -9,5 +9,5 @@  struct A
 
 void foo()
 {
-  A().i; /* { dg-error "default argument" } */
+  A().i;
 }
diff --git a/gcc/testsuite/g++.dg/template/error15.C b/gcc/testsuite/g++.dg/template/error15.C
index 8693658..ad18a1b 100644
--- a/gcc/testsuite/g++.dg/template/error15.C
+++ b/gcc/testsuite/g++.dg/template/error15.C
@@ -18,7 +18,7 @@  protected:
 
 template <class T>
 void B<T>::g(void) {
-  f(); // { dg-error "default argument" }
+  f();
 }
 
 template class B<long>;