]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: check constexpr constructor body
authorJason Merrill <jason@redhat.com>
Sat, 13 Nov 2021 21:59:31 +0000 (16:59 -0500)
committerJason Merrill <jason@redhat.com>
Mon, 15 Nov 2021 07:50:45 +0000 (02:50 -0500)
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.

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
gcc/testsuite/g++.dg/cpp1y/constexpr-89285-2.C
gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C
libstdc++-v3/include/experimental/internet
libstdc++-v3/src/c++17/memory_resource.cc

index 82a597d7bad666f09c9c92696537825bf7a31346..c92db5d413c2d4d350f4c4f0ca24f82d52268dc0 100644 (file)
@@ -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};
index 656bc9cb7f1e2d61c72c0d44ee8753be86d221ce..ea44daa849e0dc7a70df43537ea198df6e2eef15 100644 (file)
@@ -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 {
index 3809e1f7a9f80e6ec3994940483dedc913b05527..26aab9b6a50a88a6ef71aca342fd6da26c07fc2e 100644 (file)
@@ -17,4 +17,4 @@ struct C : A {
   B bar {this};
 };
 
-constexpr C foo {};    // { dg-message "expansion of" }
+constexpr C foo {};            // { dg-message "" }
index 65c97de07d915606918e9b845ead6a4c32582d5c..95b8cdc99637fb8712617056fafb1bee6c817a92 100644 (file)
@@ -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)
index 1ba79903f870517296bbd0d1343de1532057ebe3..9fc3bb754c1e6399a9ab8865a500982cfe706c02 100644 (file)
@@ -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);