diff mbox

C++ PATCH for c++/58511 (inherited ctor/constexpr diagnostic)

Message ID 53C367B3.5010608@redhat.com
State New
Headers show

Commit Message

Jason Merrill July 14, 2014, 5:16 a.m. UTC
synthesized_method_walk doesn't recognize that the default argument 
prevents B(int) from producing a constant expression; instead, we should 
use require_potential_rvalue_constant_expression to get diagnostics for 
functions that are marked constexpr.  And we should keep the 
DECL_SAVED_TREE for a defaulted constexpr function around long enough to 
pass it in.

The explain_implicit_non_constexpr change may be unnecessary, but is 
correct in any case.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox

Patch

commit 57669c237723c6d109badb660440675fd2aab883
Author: Jason Merrill <jason@redhat.com>
Date:   Sun Jul 13 14:20:24 2014 -0400

    	PR c++/58511
    	* semantics.c (is_instantiation_of_constexpr): Return true for
    	defaulted functions, too.
    	(explain_invalid_constexpr_fn): Only use
    	explain_implicit_non_constexpr if !DECL_DECLARED_CONSTEXPR_P.
    	* method.c (explain_implicit_non_constexpr): Pass
    	DECL_INHERITED_CTOR_BASE to explain_implicit_non_constexpr.

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 4d8aac1..1fa4be8 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1575,7 +1575,8 @@  explain_implicit_non_constexpr (tree decl)
   synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
 			   special_function_p (decl), const_p,
 			   NULL, NULL, NULL, &dummy, true,
-			   NULL_TREE, NULL_TREE);
+			   DECL_INHERITED_CTOR_BASE (decl),
+			   FUNCTION_FIRST_USER_PARMTYPE (decl));
 }
 
 /* DECL is an instantiation of an inheriting constructor template.  Deduce
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index a6d941b..c87764d 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3949,13 +3949,16 @@  emit_associated_thunks (tree fn)
 }
 
 /* Returns true iff FUN is an instantiation of a constexpr function
-   template.  */
+   template or a defaulted constexpr function.  */
 
 static inline bool
 is_instantiation_of_constexpr (tree fun)
 {
-  return (DECL_TEMPLOID_INSTANTIATION (fun)
-	  && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun)));
+  return ((DECL_TEMPLOID_INSTANTIATION (fun)
+	   && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun)))
+	  || (DECL_DEFAULTED_FN (fun)
+	      && DECL_DECLARED_CONSTEXPR_P (fun)));
+
 }
 
 /* Generate RTL for FN.  */
@@ -8048,7 +8051,7 @@  explain_invalid_constexpr_fn (tree fun)
   if (is_valid_constexpr_fn (fun, true))
     {
       /* Then if it's OK, the body.  */
-      if (DECL_DEFAULTED_FN (fun))
+      if (!DECL_DECLARED_CONSTEXPR_P (fun))
 	explain_implicit_non_constexpr (fun);
       else
 	{
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-inhctor1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-inhctor1.C
new file mode 100644
index 0000000..ee8757f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-inhctor1.C
@@ -0,0 +1,15 @@ 
+// PR c++/58511
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  constexpr A(int, int = i) {}
+  static const int i;
+};
+
+struct B : A
+{
+  using A::A;			// { dg-error "A::i" }
+};
+
+constexpr B b(0);		// { dg-error "B::B" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C
index a8e8cdf..6ac414b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C
@@ -10,9 +10,9 @@  struct B
 {
   A a1 = 1;			// { dg-error "" }
   A a2 { 2 };
-  A a3 = { 3 };			// { dg-error "" }
+  A a3 = { 3 };			// { dg-error "explicit" }
 };
 
 constexpr B b;			// { dg-error "B::B" }
 
-// { dg-message "a1. is invalid" "" { target *-*-* } 11 }
+// { dg-prune-output "uninitialized member" }