public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [pushed] c++: check constexpr constructor body
@ 2021-11-15  7:51 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2021-11-15  7:51 UTC (permalink / raw)
  To: gcc-patches

The implicit constexpr patch revealed that our checks for constexpr
constructors that could possibly produce a constant value (which
otherwise are IFNDR) was failing to look at most of the function body.
Fixing that required some library tweaks.

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

gcc/cp/ChangeLog:

	* constexpr.c (maybe_save_constexpr_fundef): Also check whether the
	body of a constructor is potentially constant.

libstdc++-v3/ChangeLog:

	* src/c++17/memory_resource.cc: Add missing constexpr.
	* include/experimental/internet: Only mark copy constructor
	as constexpr with __cpp_constexpr_dynamic_alloc.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp1y/constexpr-89285-2.C: Expect error.
	* g++.dg/cpp1y/constexpr-89285.C: Adjust error.
---
 gcc/cp/constexpr.c                            | 27 ++++++++++++++-----
 .../g++.dg/cpp1y/constexpr-89285-2.C          |  2 +-
 gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C  |  2 +-
 libstdc++-v3/src/c++17/memory_resource.cc     |  2 +-
 libstdc++-v3/include/experimental/internet    |  2 ++
 5 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 82a597d7bad..c92db5d413c 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -870,7 +870,9 @@ maybe_save_constexpr_fundef (tree fun)
       || (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun)))
     return;
 
-  if (!is_valid_constexpr_fn (fun, !DECL_GENERATED_P (fun)))
+  bool complain = !DECL_GENERATED_P (fun);
+
+  if (!is_valid_constexpr_fn (fun, complain))
     return;
 
   tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
@@ -883,15 +885,26 @@ maybe_save_constexpr_fundef (tree fun)
     }
 
   bool potential = potential_rvalue_constant_expression (massaged);
-  if (!potential && !DECL_GENERATED_P (fun))
+  if (!potential && complain)
     require_potential_rvalue_constant_expression (massaged);
 
-  if (DECL_CONSTRUCTOR_P (fun)
-      && cx_check_missing_mem_inits (DECL_CONTEXT (fun),
-				     massaged, !DECL_GENERATED_P (fun)))
-    potential = false;
+  if (DECL_CONSTRUCTOR_P (fun) && potential)
+    {
+      if (cx_check_missing_mem_inits (DECL_CONTEXT (fun),
+				      massaged, complain))
+	potential = false;
+      else if (cxx_dialect > cxx11)
+	{
+	  /* What we got from massage_constexpr_body is pretty much just the
+	     ctor-initializer, also check the body.  */
+	  massaged = DECL_SAVED_TREE (fun);
+	  potential = potential_rvalue_constant_expression (massaged);
+	  if (!potential && complain)
+	    require_potential_rvalue_constant_expression (massaged);
+	}
+    }
 
-  if (!potential && !DECL_GENERATED_P (fun))
+  if (!potential && complain)
     return;
 
   constexpr_fundef entry = {fun, NULL_TREE, NULL_TREE, NULL_TREE};
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C
index 656bc9cb7f1..ea44daa849e 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C
@@ -10,7 +10,7 @@ struct B {
     int *c = &x->a;
     while (*c)
       c = reinterpret_cast<int *>((reinterpret_cast<char *>(c) + *c));
-    *c = reinterpret_cast<char *>(this) - reinterpret_cast<char *>(c);
+    *c = reinterpret_cast<char *>(this) - reinterpret_cast<char *>(c); // { dg-error "reinterpret_cast" }
   }
 };
 struct C : A {
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C
index 3809e1f7a9f..26aab9b6a50 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C
@@ -17,4 +17,4 @@ struct C : A {
   B bar {this};
 };
 
-constexpr C foo {};	// { dg-message "expansion of" }
+constexpr C foo {};		// { dg-message "" }
diff --git a/libstdc++-v3/src/c++17/memory_resource.cc b/libstdc++-v3/src/c++17/memory_resource.cc
index 1ba79903f87..9fc3bb754c1 100644
--- a/libstdc++-v3/src/c++17/memory_resource.cc
+++ b/libstdc++-v3/src/c++17/memory_resource.cc
@@ -603,7 +603,7 @@ namespace pmr
     void* pointer = nullptr;
     aligned_size<min> _M_size;
 
-    size_t size() const noexcept
+    constexpr size_t size() const noexcept
     {
       if (_M_size.value == size_t(-1)) [[unlikely]]
 	return size_t(-1);
diff --git a/libstdc++-v3/include/experimental/internet b/libstdc++-v3/include/experimental/internet
index 65c97de07d9..95b8cdc9963 100644
--- a/libstdc++-v3/include/experimental/internet
+++ b/libstdc++-v3/include/experimental/internet
@@ -460,7 +460,9 @@ namespace ip
     // constructors:
     constexpr address() noexcept : _M_v4(), _M_is_v4(true) { }
 
+#if __cpp_constexpr_dynamic_alloc
     constexpr
+#endif
     address(const address& __a) noexcept : _M_uninit(), _M_is_v4(__a._M_is_v4)
     {
       if (_M_is_v4)

base-commit: bd95d75f3412e1a7debab7c6c602ba409f274eb5
prerequisite-patch-id: 27a5ed4ace5d1a1b46b77a7be24baec6a2d6bdf3
-- 
2.27.0


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-11-15  7:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-15  7:51 [pushed] c++: check constexpr constructor body Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).