]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Make __builtin_launder reject invalid types [PR116673]
authorJonathan Wakely <jwakely@redhat.com>
Wed, 11 Sep 2024 10:47:44 +0000 (11:47 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 12 Sep 2024 19:42:48 +0000 (20:42 +0100)
The standard says that std::launder is ill-formed for function pointers
and cv void pointers, so there's no reason for __builtin_launder to
accept them. This change allows implementations of std::launder to defer
to the built-in for error checking, although libstdc++ will continue to
diagnose it directly for more user-friendly diagnostics.

PR c++/116673

gcc/cp/ChangeLog:

* semantics.cc (finish_builtin_launder): Diagnose function
pointers and cv void pointers.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/launder2.C: Adjust dg-error strings.
* g++.dg/cpp1z/launder10.C: New test.

gcc/cp/semantics.cc
gcc/testsuite/g++.dg/cpp1z/launder10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/launder2.C

index 63212afafb3b75aae66dfd34a511c8febcdf9fc8..8219d6410b8e6e644411d951a95e06668710cb02 100644 (file)
@@ -13482,10 +13482,10 @@ finish_builtin_launder (location_t loc, tree arg, tsubst_flags_t complain)
     arg = decay_conversion (arg, complain);
   if (error_operand_p (arg))
     return error_mark_node;
-  if (!type_dependent_expression_p (arg)
-      && !TYPE_PTR_P (TREE_TYPE (arg)))
+  if (!type_dependent_expression_p (arg) && !TYPE_PTROB_P (TREE_TYPE (arg)))
     {
-      error_at (loc, "non-pointer argument to %<__builtin_launder%>");
+      error_at (loc, "type %qT of argument to %<__builtin_launder%> "
+               "is not a pointer to object type", TREE_TYPE (arg));
       return error_mark_node;
     }
   if (processing_template_decl)
diff --git a/gcc/testsuite/g++.dg/cpp1z/launder10.C b/gcc/testsuite/g++.dg/cpp1z/launder10.C
new file mode 100644 (file)
index 0000000..2109a2e
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/116673
+// { dg-do compile }
+
+void
+bar (void *p)
+{
+  __builtin_launder (bar); // { dg-error {argument to '__builtin_launder'} }
+  __builtin_launder (p);   // { dg-error {argument to '__builtin_launder'} }
+  const void* cp = p;
+  __builtin_launder (cp);  // { dg-error {argument to '__builtin_launder'} }
+  volatile void* vp = p;
+  __builtin_launder (vp);  // { dg-error {argument to '__builtin_launder'} }
+  const volatile void* cvp = p;
+  __builtin_launder (cvp); // { dg-error {argument to '__builtin_launder'} }
+}
index 9cd1779704b3643fabed388e1fab7f444bb37b59..a2d4486126557870473958745922b7e61756337d 100644 (file)
@@ -4,11 +4,11 @@ int a;
 int *b = __builtin_launder ();         // { dg-error "wrong number of arguments to" }
 int *c = __builtin_launder (&a, 2);    // { dg-error "wrong number of arguments to" }
 int *d = __builtin_launder (&a);
-int e = __builtin_launder (a);         // { dg-error "non-pointer argument to" }
+int e = __builtin_launder (a);         // { dg-error "not a pointer to object type" }
 int &f = a;
-int g = __builtin_launder (f);         // { dg-error "non-pointer argument to" }
+int g = __builtin_launder (f);         // { dg-error "not a pointer to object type" }
 
-template <typename T> T f1 (T x) { return __builtin_launder (x); }     // { dg-error "non-pointer argument to" }
+template <typename T> T f1 (T x) { return __builtin_launder (x); }     // { dg-error "not a pointer to object type" }
 template <typename T> T f2 (T x) { return __builtin_launder (x); }
 
 int h = f1 (a);