aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-09-11 11:47:44 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2024-09-12 20:42:48 +0100
commit9fe57e4879de93b6e3c7b4c226f42d5f3a48474f (patch)
tree3c5f6531054e747488806b2b131af161c26806bc /gcc
parent2847a541c1f19b67ae84be8d0f6dc8e1f9371d16 (diff)
downloadgcc-9fe57e4879de93b6e3c7b4c226f42d5f3a48474f.zip
gcc-9fe57e4879de93b6e3c7b4c226f42d5f3a48474f.tar.gz
gcc-9fe57e4879de93b6e3c7b4c226f42d5f3a48474f.tar.bz2
c++: Make __builtin_launder reject invalid types [PR116673]
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/semantics.cc6
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/launder10.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/launder2.C6
3 files changed, 21 insertions, 6 deletions
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 63212af..8219d641 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -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
index 0000000..2109a2e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/launder10.C
@@ -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'} }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/launder2.C b/gcc/testsuite/g++.dg/cpp1z/launder2.C
index 9cd1779..a2d4486 100644
--- a/gcc/testsuite/g++.dg/cpp1z/launder2.C
+++ b/gcc/testsuite/g++.dg/cpp1z/launder2.C
@@ -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);