Bug 114210 - Potential bug wrt __restrict on member function decl/def
Summary: Potential bug wrt __restrict on member function decl/def
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 14.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization, wrong-code
Depends on:
Blocks:
 
Reported: 2024-03-02 17:41 UTC by Sirraide
Modified: 2024-03-31 00:25 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sirraide 2024-03-02 17:41:36 UTC
Clang dev here; I’m currently working on improving our support for `__restrict`
in the cv-qualifier-seq of member functions, and I have a question about the following situation:

struct S {
    void a() __restrict;
    void b();
};

void S::a() { static_assert(__is_same(decltype(this), S*)); }
void S::b() __restrict { 
    static_assert(__is_same(decltype(this), S* __restrict)); 
}

`decltype(this)` is `S* __restrict` in the body of `S::b`, but `S*` (no `__restrict`) in the body of `S::a`, i.e. GCC only seems to care about
`__restrict` being present in the definition, not the declaration. 

According to the documentation (https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Restricted-Pointers.html), ‘you only need to specify __restrict__ in a function definition, rather than in a function prototype as well.’ This doesn’t
really say anything about what happens if the opposite is the case (i.e. if `__restrict` is only present in the declaration, not the definition).

My question, then: is this intended, or is it a bug?
Comment 1 Andrew Pinski 2024-03-31 00:08:45 UTC
Note the class method is similar to how normal functions work:

```
void
foo (int* __restrict b);
void
foo (int*  b)
{
         static_assert(__is_same(decltype(b), int*));
}
void
foo1 (int*  b);
void
foo1 (int* __restrict b)
{
         static_assert(__is_same(decltype(b), int*__restrict));
}
```
Comment 2 Andrew Pinski 2024-03-31 00:18:12 UTC
Exactly like the following standard C23 code:
```
void nonrestirct();
void restirctcall();
void
foo (int* a, int* __restrict b, int n);
void
foo (int* a, int*  b, int n)
{
        typeof(b) c = b;
        _Generic (&c ,
          int * __restrict*: restirctcall(),
          int **: nonrestirct()
        ); // calls nonrestirct
}
void
foo1 (int* a, int*  b, int n);
void
foo1 (int* a, int* __restrict b, int n)
{
        typeof(b) c = b;
        _Generic (&c ,
          int * __restrict*: restirctcall(),
          int **: nonrestirct()
        ); // calls restirctcall
}

```
Comment 3 Sirraide 2024-03-31 00:25:54 UTC
Ah, that makes sense: it’s basically treated like any other top-level cv-qualifier on a function parameter—it’s just that it happens to syntactically be in an unusual place compared to cv-qualifiers on regular function parameters. Thanks for clarifying this.