diff mbox series

[1/2,v2] c++: Make __builtin_launder reject invalid types [PR116673]

Message ID CACb0b4=RtTkh1=JQnUE1eRC=hgPtUj165msb0kw+bfiRhwPaBw@mail.gmail.com
State New
Headers show
Series [1/2,v2] c++: Make __builtin_launder reject invalid types [PR116673] | expand

Commit Message

Jonathan Wakely Sept. 12, 2024, 7:59 p.m. UTC
On Thu, 12 Sept 2024 at 16:02, Jason Merrill wrote:
>
> On 9/12/24 4:49 AM, Jonathan Wakely wrote:
> > Tested x86_64-linux. OK for trunk?
> >
> > -- >8 --
> >
> > 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/launder10.C: New test.
> > ---
> >   gcc/cp/semantics.cc                    | 17 +++++++++++++----
> >   gcc/testsuite/g++.dg/cpp1z/launder10.C | 15 +++++++++++++++
> >   2 files changed, 28 insertions(+), 4 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/cpp1z/launder10.C
> >
> > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
> > index 63212afafb3..b194b01f865 100644
> > --- a/gcc/cp/semantics.cc
> > +++ b/gcc/cp/semantics.cc
> > @@ -13482,11 +13482,20 @@ 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))
> >       {
> > -      error_at (loc, "non-pointer argument to %<__builtin_launder%>");
> > -      return error_mark_node;
> > +      tree type = TREE_TYPE (arg);
> > +      if (!TYPE_PTR_P (type))
> > +     {
> > +       error_at (loc, "non-pointer argument to %<__builtin_launder%>");
> > +       return error_mark_node;
> > +     }
> > +      else if (!object_type_p (TREE_TYPE (type)))
> > +     {
> > +       // std::launder is ill-formed for function and cv void pointers.
> > +       error_at (loc, "invalid argument to %<__builtin_launder%>");
>
> Let's be more specific by combining both errors into
>
> "type %qT of argument to %<__builtin_launder"> is not a pointer to
> object type"
>
> The tests can also be combined to !TYPE_PTROB_P.
>
> OK with that change.

Thanks, here's what I pushed.
commit 9fe57e4879de93b6e3c7b4c226f42d5f3a48474f
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Sep 11 11:47:44 2024

    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.
diff mbox series

Patch

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 63212afafb3..8219d6410b8 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 00000000000..2109a2e3839
--- /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 9cd1779704b..a2d44861265 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);