diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2024-09-11 11:47:44 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2024-09-12 20:42:48 +0100 |
commit | 9fe57e4879de93b6e3c7b4c226f42d5f3a48474f (patch) | |
tree | 3c5f6531054e747488806b2b131af161c26806bc /gcc | |
parent | 2847a541c1f19b67ae84be8d0f6dc8e1f9371d16 (diff) | |
download | gcc-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.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/launder10.C | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/launder2.C | 6 |
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); |