Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-15 Thread Jonathan Wakely

On 14/06/18 17:51 +0100, Jonathan Wakely wrote:

On 14/06/18 10:46 -0600, Martin Sebor wrote:

On 06/13/2018 10:30 AM, Jonathan Wakely wrote:

The C++ committee has confirmed that passing a null pointer to the
unary basic_string_view constructor is undefined. This removes the check
from our implementation, and adds the nonnull attribute to warn when the
compiler can detect undefined input.

Any objections to this change?


I have a general question about using the new C++ attributes in
libstdc++ (standard or otherwise): what does C++ have to say about
programs that define macros with the same names?  E.g., is this
a valid program?

#define nonnull "..."
...
#include 

How about:

#define noreturn "..."
...
#include 

The view in WG14 is that the corresponding C programs (if C2X
were to adopt the proposed C++ attributes) would be valid and
that it's up to implementations to make it work.


Good point, I suppose I have to use __attribute__((__nonnull__))
instead. The reason I didn't is that I find the grammar for the
position of C++11 attributes much easier to understand. But in this
instance the same location works for either.


Nobody's objected to the patch in princple, so I'll commit this
version, using __attribute__((__nonnull__)) instead of
[[gnu::nonnull].


commit 5a1626332e84b64adc049b7ce13c2ed8917a7fa3
Author: Jonathan Wakely 
Date:   Wed Jun 13 16:54:47 2018 +0100

Decorate string_view members with nonnull attribute

The C++ committee has confirmed that passing a null pointer to the
unary basic_string_view constructor is undefined. This removes the check
from our implementation, and adds the nonnull attribute to warn when the
compiler can detect undefined input.

* include/std/string_view (basic_string_view(const CharT*)): Remove
check for null pointer and add nonnull attribute.
(compare(const CharT*), compare(size_type, size_type, const CharT*))
(find(const CharT*, size_type), rfind(const CharT*, size_type))
(find_first_of(const CharT*, size_type))
(find_last_of(const CharT*, size_type))
(find_first_not_of(const CharT*, size_type))
(find_last_not_of(const CharT*, size_type)): Add nonnull attribute.
* testsuite/21_strings/basic_string_view/cons/char/nonnull.cc: New.
* testsuite/21_strings/basic_string_view/operations/compare/char/
nonnull.cc: New.
* testsuite/21_strings/basic_string_view/operations/find/char/
nonnull.cc: New.
* testsuite/21_strings/basic_string_view/operations/rfind/char/
nonnull.cc: New.

diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view
index 9f39df853e8..f84664ca286 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -96,8 +96,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   constexpr basic_string_view(const basic_string_view&) noexcept = default;
 
-  constexpr basic_string_view(const _CharT* __str) noexcept
-  : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
+  __attribute__((__nonnull__)) constexpr
+  basic_string_view(const _CharT* __str) noexcept
+  : _M_len{traits_type::length(__str)},
 	_M_str{__str}
   { }
 
@@ -270,11 +271,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
   }
 
-  constexpr int
+  __attribute__((__nonnull__)) constexpr int
   compare(const _CharT* __str) const noexcept
   { return this->compare(basic_string_view{__str}); }
 
-  constexpr int
+  __attribute__((__nonnull__)) constexpr int
   compare(size_type __pos1, size_type __n1, const _CharT* __str) const
   { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
 
@@ -296,7 +297,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   constexpr size_type
   find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
 
-  constexpr size_type
+  __attribute__((__nonnull__)) constexpr size_type
   find(const _CharT* __str, size_type __pos = 0) const noexcept
   { return this->find(__str, __pos, traits_type::length(__str)); }
 
@@ -310,7 +311,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   constexpr size_type
   rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
 
-  constexpr size_type
+  __attribute__((__nonnull__)) constexpr size_type
   rfind(const _CharT* __str, size_type __pos = npos) const noexcept
   { return this->rfind(__str, __pos, traits_type::length(__str)); }
 
@@ -323,9 +324,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { return this->find(__c, __pos); }
 
   constexpr size_type
-  find_first_of(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
+  find_first_of(const _CharT* __str, size_type __pos,
+		size_type __n) const noexcept;
 
-  constexpr 

Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Martin Sebor

On 06/14/2018 10:54 AM, Ville Voutilainen wrote:

On 14 June 2018 at 19:51, Jonathan Wakely  wrote:

On 14/06/18 10:46 -0600, Martin Sebor wrote:


On 06/13/2018 10:30 AM, Jonathan Wakely wrote:


The C++ committee has confirmed that passing a null pointer to the
unary basic_string_view constructor is undefined. This removes the check
from our implementation, and adds the nonnull attribute to warn when the
compiler can detect undefined input.

Any objections to this change?



I have a general question about using the new C++ attributes in
libstdc++ (standard or otherwise): what does C++ have to say about
programs that define macros with the same names?  E.g., is this
a valid program?

 #define nonnull "..."
 ...
 #include 

How about:

 #define noreturn "..."
 ...
 #include 

The view in WG14 is that the corresponding C programs (if C2X
were to adopt the proposed C++ attributes) would be valid and
that it's up to implementations to make it work.



Good point, I suppose I have to use __attribute__((__nonnull__))
instead. The reason I didn't is that I find the grammar for the
position of C++11 attributes much easier to understand. But in this
instance the same location works for either.


[macro.names]/2 forbids #defining macros with the same names as the
standard attributes.
The programs Martin shows as examples are not valid.


Okay, that's good to know about the one that uses the standard
attribute (and thanks for the reference).  WG14 should consider
this when integrating attributes into C2X.

FWIW, the problem I suspect will come up in WG14 is that C tries
hard to avoid introducing new reserved words into the public
namespace.  At the same time, two of the biggest selling points
of the C++ attribute syntax proposal in WG14 (i.e., the double
brackets, as opposed to something more C-ish like _Attribute())
are a) compatibility and interoperability with C++ and b) being
able to avoid relying on preprocessor conditionals and macros
to use attributes in portable code.  If C2X programs (and
libraries) are going to continue to be allowed to #define macros
with the same names as even standard attributes, we (i.e., both
WG14 and to an extent even WG21) will have failed to deliver on
these goals.  To avoid name clashes, mixed C/C++ programs will
still have to use #ifdefs and macros in both languages to make
use of attributes because the spelling of the "private" attribute
names (like __noreturn__) is not specified.  Even if C2X were to
impose the same restriction on macros as C++, there likely are
C headers out there today that do just that, and not all those
headers will necessarily migrate to C2X.

Martin



Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Ville Voutilainen
On 14 June 2018 at 20:40, Jonathan Wakely  wrote:
>> Namely "For an attribute-token (including an attribute-scoped-token)
>> not specified in this document, the behavior is
>> implementation-defined.", aka [dcl.attr.grammar]/6.
>
>
> As I said on IRC, if the user does
>
> #define gnu R"(
> ,= ,-_-. =.
> ((_/)o o(\_))
>  `-'(. .)`-'
>  \_/
> )"
>
> then the attribute-scoped-token isn't even valid, and so the behaviour
> of the implementation-defined gnu::nonnull attribute doesn't matter.
> The code doesn't contain such an attribute.
>
> This seems like an unnecessary discussion: we should just use the
> __attribute__ form instead.

That may well be, but deciding to handle preprocessor definitions of
vendor attributes
in a particular way doesn't make us non-conforming. The behaviour of a
gnu::nonnull
would, as far as I understand it, possibly include restrictions on
what the preprocessor
can do with it, just like the specification for standard attributes
does. The preprocessor
is part of the implementation, not a magical separate step that can do
whatever it pleases.

Conformance being a moot point, I'd prefer using the standard
attribute syntax if we can,
instead of using the gnuattribute syntax, but that's not a strong preference.


Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Jonathan Wakely

On 14/06/18 20:27 +0300, Ville Voutilainen wrote:

On 14 June 2018 at 20:21, Ville Voutilainen  wrote:

On 14 June 2018 at 20:08, Jonathan Wakely  wrote:

Oops, indeed. But for gnu-attributes, surely we can decide whatever we
want about what's
valid and what's not?



We could say that #defining 'nonnull' and/or 'gnu' as a macro is
undefined, but then programs that the standard says are valid would
fail to compile, and we'd be a non-conforming implementation.

We can use __attribute__(__nonnull__)) so that we accept those
programs (and be a conforming implementation). Why would we choose to
be non-conforming when we don't have to?


I can read the specification liberally enough that it might give us
the freedom to disallow programs
that #define names that our implementation uses for vendor attributes.


Namely "For an attribute-token (including an attribute-scoped-token)
not specified in this document, the behavior is
implementation-defined.", aka [dcl.attr.grammar]/6.


As I said on IRC, if the user does

#define gnu R"(
,= ,-_-. =.
((_/)o o(\_))
 `-'(. .)`-'
 \_/
)"

then the attribute-scoped-token isn't even valid, and so the behaviour
of the implementation-defined gnu::nonnull attribute doesn't matter.
The code doesn't contain such an attribute.

This seems like an unnecessary discussion: we should just use the
__attribute__ form instead.




Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Ville Voutilainen
On 14 June 2018 at 20:21, Ville Voutilainen  wrote:
> On 14 June 2018 at 20:08, Jonathan Wakely  wrote:
>>> Oops, indeed. But for gnu-attributes, surely we can decide whatever we
>>> want about what's
>>> valid and what's not?
>>
>>
>> We could say that #defining 'nonnull' and/or 'gnu' as a macro is
>> undefined, but then programs that the standard says are valid would
>> fail to compile, and we'd be a non-conforming implementation.
>>
>> We can use __attribute__(__nonnull__)) so that we accept those
>> programs (and be a conforming implementation). Why would we choose to
>> be non-conforming when we don't have to?
>
> I can read the specification liberally enough that it might give us
> the freedom to disallow programs
> that #define names that our implementation uses for vendor attributes.

Namely "For an attribute-token (including an attribute-scoped-token)
not specified in this document, the behavior is
implementation-defined.", aka [dcl.attr.grammar]/6.


Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Ville Voutilainen
On 14 June 2018 at 20:08, Jonathan Wakely  wrote:
>> Oops, indeed. But for gnu-attributes, surely we can decide whatever we
>> want about what's
>> valid and what's not?
>
>
> We could say that #defining 'nonnull' and/or 'gnu' as a macro is
> undefined, but then programs that the standard says are valid would
> fail to compile, and we'd be a non-conforming implementation.
>
> We can use __attribute__(__nonnull__)) so that we accept those
> programs (and be a conforming implementation). Why would we choose to
> be non-conforming when we don't have to?

I can read the specification liberally enough that it might give us
the freedom to disallow programs
that #define names that our implementation uses for vendor attributes.


Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Jonathan Wakely

On 14/06/18 20:02 +0300, Ville Voutilainen wrote:

On 14 June 2018 at 19:57, Jonathan Wakely  wrote:

[macro.names]/2 forbids #defining macros with the same names as the
standard attributes.
The programs Martin shows as examples are not valid.



But nonnull isn't a standard attribute though. So we can't use
[[gnu::xxx]] attributes in libstdc++ and have to use __attribute__
instead.


Oops, indeed. But for gnu-attributes, surely we can decide whatever we
want about what's
valid and what's not?


We could say that #defining 'nonnull' and/or 'gnu' as a macro is
undefined, but then programs that the standard says are valid would
fail to compile, and we'd be a non-conforming implementation.

We can use __attribute__(__nonnull__)) so that we accept those
programs (and be a conforming implementation). Why would we choose to
be non-conforming when we don't have to?

We can use [[gnu::__nonnull__]] but that would still reject programs
that #define gnu so maybe we want the front-end to also recognise
__gnu__ as our attribute namespace.



Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Ville Voutilainen
On 14 June 2018 at 19:57, Jonathan Wakely  wrote:
>> [macro.names]/2 forbids #defining macros with the same names as the
>> standard attributes.
>> The programs Martin shows as examples are not valid.
>
>
> But nonnull isn't a standard attribute though. So we can't use
> [[gnu::xxx]] attributes in libstdc++ and have to use __attribute__
> instead.

Oops, indeed. But for gnu-attributes, surely we can decide whatever we
want about what's
valid and what's not?


Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Jonathan Wakely

On 14/06/18 19:54 +0300, Ville Voutilainen wrote:

On 14 June 2018 at 19:51, Jonathan Wakely  wrote:

On 14/06/18 10:46 -0600, Martin Sebor wrote:


On 06/13/2018 10:30 AM, Jonathan Wakely wrote:


The C++ committee has confirmed that passing a null pointer to the
unary basic_string_view constructor is undefined. This removes the check
from our implementation, and adds the nonnull attribute to warn when the
compiler can detect undefined input.

Any objections to this change?



I have a general question about using the new C++ attributes in
libstdc++ (standard or otherwise): what does C++ have to say about
programs that define macros with the same names?  E.g., is this
a valid program?

 #define nonnull "..."
 ...
 #include 

How about:

 #define noreturn "..."
 ...
 #include 

The view in WG14 is that the corresponding C programs (if C2X
were to adopt the proposed C++ attributes) would be valid and
that it's up to implementations to make it work.



Good point, I suppose I have to use __attribute__((__nonnull__))
instead. The reason I didn't is that I find the grammar for the
position of C++11 attributes much easier to understand. But in this
instance the same location works for either.


[macro.names]/2 forbids #defining macros with the same names as the
standard attributes.
The programs Martin shows as examples are not valid.


But nonnull isn't a standard attribute though. So we can't use
[[gnu::xxx]] attributes in libstdc++ and have to use __attribute__
instead.

[[sad_face]]




Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Ville Voutilainen
On 14 June 2018 at 19:51, Jonathan Wakely  wrote:
> On 14/06/18 10:46 -0600, Martin Sebor wrote:
>>
>> On 06/13/2018 10:30 AM, Jonathan Wakely wrote:
>>>
>>> The C++ committee has confirmed that passing a null pointer to the
>>> unary basic_string_view constructor is undefined. This removes the check
>>> from our implementation, and adds the nonnull attribute to warn when the
>>> compiler can detect undefined input.
>>>
>>> Any objections to this change?
>>
>>
>> I have a general question about using the new C++ attributes in
>> libstdc++ (standard or otherwise): what does C++ have to say about
>> programs that define macros with the same names?  E.g., is this
>> a valid program?
>>
>>  #define nonnull "..."
>>  ...
>>  #include 
>>
>> How about:
>>
>>  #define noreturn "..."
>>  ...
>>  #include 
>>
>> The view in WG14 is that the corresponding C programs (if C2X
>> were to adopt the proposed C++ attributes) would be valid and
>> that it's up to implementations to make it work.
>
>
> Good point, I suppose I have to use __attribute__((__nonnull__))
> instead. The reason I didn't is that I find the grammar for the
> position of C++11 attributes much easier to understand. But in this
> instance the same location works for either.

[macro.names]/2 forbids #defining macros with the same names as the
standard attributes.
The programs Martin shows as examples are not valid.


Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Jonathan Wakely

On 14/06/18 10:46 -0600, Martin Sebor wrote:

On 06/13/2018 10:30 AM, Jonathan Wakely wrote:

The C++ committee has confirmed that passing a null pointer to the
unary basic_string_view constructor is undefined. This removes the check
from our implementation, and adds the nonnull attribute to warn when the
compiler can detect undefined input.

Any objections to this change?


I have a general question about using the new C++ attributes in
libstdc++ (standard or otherwise): what does C++ have to say about
programs that define macros with the same names?  E.g., is this
a valid program?

 #define nonnull "..."
 ...
 #include 

How about:

 #define noreturn "..."
 ...
 #include 

The view in WG14 is that the corresponding C programs (if C2X
were to adopt the proposed C++ attributes) would be valid and
that it's up to implementations to make it work.


Good point, I suppose I have to use __attribute__((__nonnull__))
instead. The reason I didn't is that I find the grammar for the
position of C++11 attributes much easier to understand. But in this
instance the same location works for either.




Re: [PATCH] Decorate string_view members with nonnull attribute

2018-06-14 Thread Martin Sebor

On 06/13/2018 10:30 AM, Jonathan Wakely wrote:

The C++ committee has confirmed that passing a null pointer to the
unary basic_string_view constructor is undefined. This removes the check
from our implementation, and adds the nonnull attribute to warn when the
compiler can detect undefined input.

Any objections to this change?


I have a general question about using the new C++ attributes in
libstdc++ (standard or otherwise): what does C++ have to say about
programs that define macros with the same names?  E.g., is this
a valid program?

  #define nonnull "..."
  ...
  #include 

How about:

  #define noreturn "..."
  ...
  #include 

The view in WG14 is that the corresponding C programs (if C2X
were to adopt the proposed C++ attributes) would be valid and
that it's up to implementations to make it work.

Martin


[PATCH] Decorate string_view members with nonnull attribute

2018-06-13 Thread Jonathan Wakely

The C++ committee has confirmed that passing a null pointer to the
unary basic_string_view constructor is undefined. This removes the check
from our implementation, and adds the nonnull attribute to warn when the
compiler can detect undefined input.

Any objections to this change?

commit 05d33d556eaabb3c81f4db15b9818c465b359c15
Author: Jonathan Wakely 
Date:   Wed Jun 13 16:54:47 2018 +0100

Decorate string_view members with nonnull attribute

The C++ committee has confirmed that passing a null pointer to the
unary basic_string_view constructor is undefined. This removes the check
from our implementation, and adds the nonnull attribute to warn when the
compiler can detect undefined input.

* include/std/string_view (basic_string_view(const CharT*)): Remove
check for null pointer and add nonnull attribute.
(compare(const CharT*), compare(size_type, size_type, const CharT*))
(find(const CharT*, size_type), rfind(const CharT*, size_type))
(find_first_of(const CharT*, size_type))
(find_last_of(const CharT*, size_type))
(find_first_not_of(const CharT*, size_type))
(find_last_not_of(const CharT*, size_type)): Add nonnull attribute.
* testsuite/21_strings/basic_string_view/cons/char/nonnull.cc: New.
* testsuite/21_strings/basic_string_view/operations/compare/char/
nonnull.cc: New.
* testsuite/21_strings/basic_string_view/operations/find/char/
nonnull.cc: New.
* testsuite/21_strings/basic_string_view/operations/rfind/char/
nonnull.cc: New.

diff --git a/libstdc++-v3/include/std/string_view 
b/libstdc++-v3/include/std/string_view
index 9f39df853e8..4de484a96ba 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -96,8 +96,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   constexpr basic_string_view(const basic_string_view&) noexcept = default;
 
-  constexpr basic_string_view(const _CharT* __str) noexcept
-  : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
+  [[gnu::nonnull]] constexpr
+  basic_string_view(const _CharT* __str) noexcept
+  : _M_len{traits_type::length(__str)},
_M_str{__str}
   { }
 
@@ -270,11 +271,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2));
   }
 
-  constexpr int
+  [[gnu::nonnull]] constexpr int
   compare(const _CharT* __str) const noexcept
   { return this->compare(basic_string_view{__str}); }
 
-  constexpr int
+  [[gnu::nonnull]] constexpr int
   compare(size_type __pos1, size_type __n1, const _CharT* __str) const
   { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); }
 
@@ -296,7 +297,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   constexpr size_type
   find(const _CharT* __str, size_type __pos, size_type __n) const noexcept;
 
-  constexpr size_type
+  [[gnu::nonnull]] constexpr size_type
   find(const _CharT* __str, size_type __pos = 0) const noexcept
   { return this->find(__str, __pos, traits_type::length(__str)); }
 
@@ -310,7 +311,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   constexpr size_type
   rfind(const _CharT* __str, size_type __pos, size_type __n) const 
noexcept;
 
-  constexpr size_type
+  [[gnu::nonnull]] constexpr size_type
   rfind(const _CharT* __str, size_type __pos = npos) const noexcept
   { return this->rfind(__str, __pos, traits_type::length(__str)); }
 
@@ -323,9 +324,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { return this->find(__c, __pos); }
 
   constexpr size_type
-  find_first_of(const _CharT* __str, size_type __pos, size_type __n) const 
noexcept;
+  find_first_of(const _CharT* __str, size_type __pos,
+   size_type __n) const noexcept;
 
-  constexpr size_type
+  [[gnu::nonnull]] constexpr size_type
   find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept
   { return this->find_first_of(__str, __pos, traits_type::length(__str)); }
 
@@ -342,7 +344,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   find_last_of(const _CharT* __str, size_type __pos,
   size_type __n) const noexcept;
 
-  constexpr size_type
+  [[gnu::nonnull]] constexpr size_type
   find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept
   { return this->find_last_of(__str, __pos, traits_type::length(__str)); }
 
@@ -358,7 +360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   find_first_not_of(const _CharT* __str,
size_type __pos, size_type __n) const noexcept;
 
-  constexpr size_type
+  [[gnu::nonnull]] constexpr size_type
   find_first_not_of(const _CharT* __str, size_type __pos = 0) const 
noexcept
   {
return this->find_first_not_of(__str, __pos,
@@ -377,7 +379,7 @@