Re: [clang] c90e198 - Fix parsing of enum-base to follow C++11 rules.

2020-05-27 Thread Richard Smith via cfe-commits
On Tue, 26 May 2020 at 20:12, Akira Hatanaka via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> On May 20, 2020, at 5:53 PM, Richard Smith  wrote:
>
> On Wed, 20 May 2020 at 16:30, Akira Hatanaka via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> Hi Richard,
>>
>> It looks like this patch will reject the following code, which used to
>> compile fine:
>>
>> $ cat test.cpp
>> #include 
>>
>> typedef CF_ENUM(unsigned, TestEnum) {
>>   A = 2,
>>   B = 3,
>> };
>>
>> $ clang++ -std=c++11 -c test.cpp
>>
>> *test.cpp:3:9: **error: **non-defining declaration of enumeration with a
>> fixed underlying type is only permitted as a standalone declaration;
>> missing list of enumerators? [-Welaborated-enum-base]*
>> typedef CF_ENUM(unsigned, TestEnum) {
>>
>> The macro is defined in CFAvailability.h:
>>
>>
>> https://opensource.apple.com/source/CF/CF-855.17/CFAvailability.h.auto.html
>>
>> What’s the best way to fix this?
>>
>
> Assuming this macro is always preceded by 'typedef', how about this:
>
> -#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
> +#define CF_ENUM(_type, _name) int _dummy_##_name; enum _name : _type
> _name; typedef enum _name _name; enum _name : _type
>
> Or this:
>
> +#ifdef __cplusplus
>  #define CF_ENUM(_type, _name) int _dummy_##_name; enum _name : _type
> +#else
>  #define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
> +#endif
>
> (One wonders why the 'typedef' is not part of the macro definition.)
>
>
> Thanks! Is there a way to avoid the dummy typedef so that it doesn’t show
> up in completions and stuff or some way in C++ to undef the typedef?
>

A typedef keyword always introduces a typedef, there's no way to remove the
typedef again afterwards, and there's no way for the typedef to be for the
enum type in valid C++ code. So I think the only option is for it to be a
typedef for some other type. You could redeclare some typedef you already
know to be in scope:

#define CF_ENUM(_type, _name) size_t size_t; enum _name : _type

... but that would do surprising things if it appeared anywhere other than
at global namespace scope.

Perhaps you could add an availability / deprecated attribute to hide the
typedef from completion (plus the 'unused' attribute to avoid warnings
about it not being used).

Alternatively you could use a _Pragma to temporarily turn off the clang
error for the invalid enum forward declaration, but presumably it would be
preferable to make the code valid rather than merely get clang to continue
accepting it?

> On May 11, 2020, at 1:37 PM, Richard Smith via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>> On Mon, 11 May 2020 at 06:37, Hans Wennborg via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>>> On Sat, May 9, 2020 at 4:32 AM Richard Smith via cfe-commits
>>>  wrote:
>>> >
>>> >
>>> > Author: Richard Smith
>>> > Date: 2020-05-08T19:32:00-07:00
>>> > New Revision: c90e198107431f64b73686bdce31c293e3380ac7
>>> >
>>> > URL:
>>> https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7
>>> > DIFF:
>>> https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7.diff
>>> >
>>> > LOG: Fix parsing of enum-base to follow C++11 rules.
>>> >
>>> > Previously we implemented non-standard disambiguation rules to
>>> > distinguish an enum-base from a bit-field but otherwise treated a :
>>> > after an elaborated-enum-specifier as introducing an enum-base. That
>>> > misparses various examples (anywhere an elaborated-type-specifier can
>>> > appear followed by a colon, such as within a ternary operator or
>>> > _Generic).
>>> >
>>> > We now implement the C++11 rules, with the old cases accepted as
>>> > extensions where that seemed reasonable. These amount to:
>>> >  * an enum-base must always be accompanied by an enum definition
>>> (except
>>> >in a standalone declaration of the form 'enum E : T;')
>>> >  * in a member-declaration, 'enum E :' always introduces an enum-base,
>>> >never a bit-field
>>> >  * in a type-specifier (or similar context), 'enum E :' is not
>>> >permitted; the colon means whatever else it would mean in that
>>> >context.
>>> >
>>> > Fixed underlying types for enums are also permitted in Objective-C and
>>> > under MS extensions, plus as a language extension in all other modes.
>>> > The behavior in ObjC and MS extensions modes is unchanged (but the
>>> > bit-field disambiguation is a bit better); remaining language modes
>>> > follow the C++11 rules.
>>> >
>>> > Fixes PR45726, PR39979, PR19810, PR44941, and most of PR24297, plus C++
>>> > core issues 1514 and 1966.
>>>
>>> Hello from Chromium :-)
>>>
>>> We saw new errors from some code in a header that looked like this:
>>>
>>>   // Adapted from NSPathUtilities.h and NSObjCRuntime.h.
>>>   typedef enum NSSearchPathDirectory : unsigned long
>>> NSSearchPathDirectory;
>>>
>>> For us we think the enum itself is enough, so we'll fix it by dropping
>>> the typedef, 

Re: [clang] c90e198 - Fix parsing of enum-base to follow C++11 rules.

2020-05-26 Thread Akira Hatanaka via cfe-commits

> On May 20, 2020, at 5:53 PM, Richard Smith  wrote:
> 
> On Wed, 20 May 2020 at 16:30, Akira Hatanaka via cfe-commits 
> mailto:cfe-commits@lists.llvm.org>> wrote:
> Hi Richard,
> 
> It looks like this patch will reject the following code, which used to 
> compile fine:
> 
> $ cat test.cpp
> #include 
> 
> typedef CF_ENUM(unsigned, TestEnum) {
>   A = 2,
>   B = 3,
> };
> 
> $ clang++ -std=c++11 -c test.cpp
> 
> test.cpp:3:9: error: non-defining declaration of enumeration with a fixed 
> underlying type is only permitted as a standalone declaration; missing list 
> of enumerators? [-Welaborated-enum-base]
> typedef CF_ENUM(unsigned, TestEnum) {
> 
> The macro is defined in CFAvailability.h:
> 
> https://opensource.apple.com/source/CF/CF-855.17/CFAvailability.h.auto.html 
> 
> 
> What’s the best way to fix this?
> 
> Assuming this macro is always preceded by 'typedef', how about this:
> 
> -#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
> +#define CF_ENUM(_type, _name) int _dummy_##_name; enum _name : _type _name; 
> typedef enum _name _name; enum _name : _type
> 
> Or this:
> 
> +#ifdef __cplusplus
>  #define CF_ENUM(_type, _name) int _dummy_##_name; enum _name : _type
> +#else
>  #define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
> +#endif
> 
> (One wonders why the 'typedef' is not part of the macro definition.)

Thanks! Is there a way to avoid the dummy typedef so that it doesn’t show up in 
completions and stuff or some way in C++ to undef the typedef? 

> 
>> On May 11, 2020, at 1:37 PM, Richard Smith via cfe-commits 
>> mailto:cfe-commits@lists.llvm.org>> wrote:
>> 
>> On Mon, 11 May 2020 at 06:37, Hans Wennborg via cfe-commits 
>> mailto:cfe-commits@lists.llvm.org>> wrote:
>> On Sat, May 9, 2020 at 4:32 AM Richard Smith via cfe-commits
>> mailto:cfe-commits@lists.llvm.org>> wrote:
>> >
>> >
>> > Author: Richard Smith
>> > Date: 2020-05-08T19:32:00-07:00
>> > New Revision: c90e198107431f64b73686bdce31c293e3380ac7
>> >
>> > URL: 
>> > https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7
>> >  
>> > 
>> > DIFF: 
>> > https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7.diff
>> >  
>> > 
>> >
>> > LOG: Fix parsing of enum-base to follow C++11 rules.
>> >
>> > Previously we implemented non-standard disambiguation rules to
>> > distinguish an enum-base from a bit-field but otherwise treated a :
>> > after an elaborated-enum-specifier as introducing an enum-base. That
>> > misparses various examples (anywhere an elaborated-type-specifier can
>> > appear followed by a colon, such as within a ternary operator or
>> > _Generic).
>> >
>> > We now implement the C++11 rules, with the old cases accepted as
>> > extensions where that seemed reasonable. These amount to:
>> >  * an enum-base must always be accompanied by an enum definition (except
>> >in a standalone declaration of the form 'enum E : T;')
>> >  * in a member-declaration, 'enum E :' always introduces an enum-base,
>> >never a bit-field
>> >  * in a type-specifier (or similar context), 'enum E :' is not
>> >permitted; the colon means whatever else it would mean in that
>> >context.
>> >
>> > Fixed underlying types for enums are also permitted in Objective-C and
>> > under MS extensions, plus as a language extension in all other modes.
>> > The behavior in ObjC and MS extensions modes is unchanged (but the
>> > bit-field disambiguation is a bit better); remaining language modes
>> > follow the C++11 rules.
>> >
>> > Fixes PR45726, PR39979, PR19810, PR44941, and most of PR24297, plus C++
>> > core issues 1514 and 1966.
>> 
>> Hello from Chromium :-)
>> 
>> We saw new errors from some code in a header that looked like this:
>> 
>>   // Adapted from NSPathUtilities.h and NSObjCRuntime.h.
>>   typedef enum NSSearchPathDirectory : unsigned long NSSearchPathDirectory;
>> 
>> For us we think the enum itself is enough, so we'll fix it by dropping
>> the typedef, but this raised the question of how your change affects
>> the Mac system headers. IIUC your change makes an exception for Obj-C,
>> but the headers can be used from regular C/C++ too. Do you think there
>> might be issues there?
>> 
>> The errors are DefaultError ExtWarns, so they will be suppressed by default 
>> in system headers. Even then:
>>  * In Objective-C (and Objective-C++), the prior rule is unchanged.
>>  * In (non-Objective) C++11 onwards, we now enforce the standard rules. 
>> (System headers should ideally be valid code, but if not, the system header 
>> exclusion will kick in. And the errors can be disabled by warning flag in 
>> user code written against old Clang.)
>>  * In any other language mode, 

Re: [clang] c90e198 - Fix parsing of enum-base to follow C++11 rules.

2020-05-20 Thread Richard Smith via cfe-commits
On Wed, 20 May 2020 at 16:30, Akira Hatanaka via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Hi Richard,
>
> It looks like this patch will reject the following code, which used to
> compile fine:
>
> $ cat test.cpp
> #include 
>
> typedef CF_ENUM(unsigned, TestEnum) {
>   A = 2,
>   B = 3,
> };
>
> $ clang++ -std=c++11 -c test.cpp
>
> *test.cpp:3:9: **error: **non-defining declaration of enumeration with a
> fixed underlying type is only permitted as a standalone declaration;
> missing list of enumerators? [-Welaborated-enum-base]*
> typedef CF_ENUM(unsigned, TestEnum) {
>
> The macro is defined in CFAvailability.h:
>
> https://opensource.apple.com/source/CF/CF-855.17/CFAvailability.h.auto.html
>
> What’s the best way to fix this?
>

Assuming this macro is always preceded by 'typedef', how about this:

-#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#define CF_ENUM(_type, _name) int _dummy_##_name; enum _name : _type
_name; typedef enum _name _name; enum _name : _type

Or this:

+#ifdef __cplusplus
 #define CF_ENUM(_type, _name) int _dummy_##_name; enum _name : _type
+#else
 #define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#endif

(One wonders why the 'typedef' is not part of the macro definition.)

> On May 11, 2020, at 1:37 PM, Richard Smith via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
> On Mon, 11 May 2020 at 06:37, Hans Wennborg via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> On Sat, May 9, 2020 at 4:32 AM Richard Smith via cfe-commits
>>  wrote:
>> >
>> >
>> > Author: Richard Smith
>> > Date: 2020-05-08T19:32:00-07:00
>> > New Revision: c90e198107431f64b73686bdce31c293e3380ac7
>> >
>> > URL:
>> https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7
>> > DIFF:
>> https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7.diff
>> >
>> > LOG: Fix parsing of enum-base to follow C++11 rules.
>> >
>> > Previously we implemented non-standard disambiguation rules to
>> > distinguish an enum-base from a bit-field but otherwise treated a :
>> > after an elaborated-enum-specifier as introducing an enum-base. That
>> > misparses various examples (anywhere an elaborated-type-specifier can
>> > appear followed by a colon, such as within a ternary operator or
>> > _Generic).
>> >
>> > We now implement the C++11 rules, with the old cases accepted as
>> > extensions where that seemed reasonable. These amount to:
>> >  * an enum-base must always be accompanied by an enum definition (except
>> >in a standalone declaration of the form 'enum E : T;')
>> >  * in a member-declaration, 'enum E :' always introduces an enum-base,
>> >never a bit-field
>> >  * in a type-specifier (or similar context), 'enum E :' is not
>> >permitted; the colon means whatever else it would mean in that
>> >context.
>> >
>> > Fixed underlying types for enums are also permitted in Objective-C and
>> > under MS extensions, plus as a language extension in all other modes.
>> > The behavior in ObjC and MS extensions modes is unchanged (but the
>> > bit-field disambiguation is a bit better); remaining language modes
>> > follow the C++11 rules.
>> >
>> > Fixes PR45726, PR39979, PR19810, PR44941, and most of PR24297, plus C++
>> > core issues 1514 and 1966.
>>
>> Hello from Chromium :-)
>>
>> We saw new errors from some code in a header that looked like this:
>>
>>   // Adapted from NSPathUtilities.h and NSObjCRuntime.h.
>>   typedef enum NSSearchPathDirectory : unsigned long
>> NSSearchPathDirectory;
>>
>> For us we think the enum itself is enough, so we'll fix it by dropping
>> the typedef, but this raised the question of how your change affects
>> the Mac system headers. IIUC your change makes an exception for Obj-C,
>> but the headers can be used from regular C/C++ too. Do you think there
>> might be issues there?
>>
>
> The errors are DefaultError ExtWarns, so they will be suppressed by
> default in system headers. Even then:
>  * In Objective-C (and Objective-C++), the prior rule is unchanged.
>  * In (non-Objective) C++11 onwards, we now enforce the standard rules.
> (System headers should ideally be valid code, but if not, the system header
> exclusion will kick in. And the errors can be disabled by warning flag in
> user code written against old Clang.)
>  * In any other language mode, system headers should really not be using
> this functionality, since it's a non-standard language extension, and not
> supported by (for example) GCC. (With the same provisos as in the prior
> bullet.)
>
> We can make the C++ side of things more permissive if necessary, but I'm
> hopeful that we will be able to enforce the standard rules by default in
> this instance.
>
> (See https://chromium-review.googlesource.com/c/chromium/src/+/2193673
>> for the Chromium discussion.)
>> ___
>> cfe-commits mailing list
>> cfe-commits@lists.llvm.org
>> 

Re: [clang] c90e198 - Fix parsing of enum-base to follow C++11 rules.

2020-05-20 Thread Akira Hatanaka via cfe-commits
Hi Richard,

It looks like this patch will reject the following code, which used to compile 
fine:

$ cat test.cpp
#include 

typedef CF_ENUM(unsigned, TestEnum) {
  A = 2,
  B = 3,
};

$ clang++ -std=c++11 -c test.cpp

test.cpp:3:9: error: non-defining declaration of enumeration with a fixed 
underlying type is only permitted as a standalone declaration; missing list of 
enumerators? [-Welaborated-enum-base]
typedef CF_ENUM(unsigned, TestEnum) {

The macro is defined in CFAvailability.h:

https://opensource.apple.com/source/CF/CF-855.17/CFAvailability.h.auto.html

What’s the best way to fix this?

> On May 11, 2020, at 1:37 PM, Richard Smith via cfe-commits 
>  wrote:
> 
> On Mon, 11 May 2020 at 06:37, Hans Wennborg via cfe-commits 
> mailto:cfe-commits@lists.llvm.org>> wrote:
> On Sat, May 9, 2020 at 4:32 AM Richard Smith via cfe-commits
> mailto:cfe-commits@lists.llvm.org>> wrote:
> >
> >
> > Author: Richard Smith
> > Date: 2020-05-08T19:32:00-07:00
> > New Revision: c90e198107431f64b73686bdce31c293e3380ac7
> >
> > URL: 
> > https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7
> >  
> > 
> > DIFF: 
> > https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7.diff
> >  
> > 
> >
> > LOG: Fix parsing of enum-base to follow C++11 rules.
> >
> > Previously we implemented non-standard disambiguation rules to
> > distinguish an enum-base from a bit-field but otherwise treated a :
> > after an elaborated-enum-specifier as introducing an enum-base. That
> > misparses various examples (anywhere an elaborated-type-specifier can
> > appear followed by a colon, such as within a ternary operator or
> > _Generic).
> >
> > We now implement the C++11 rules, with the old cases accepted as
> > extensions where that seemed reasonable. These amount to:
> >  * an enum-base must always be accompanied by an enum definition (except
> >in a standalone declaration of the form 'enum E : T;')
> >  * in a member-declaration, 'enum E :' always introduces an enum-base,
> >never a bit-field
> >  * in a type-specifier (or similar context), 'enum E :' is not
> >permitted; the colon means whatever else it would mean in that
> >context.
> >
> > Fixed underlying types for enums are also permitted in Objective-C and
> > under MS extensions, plus as a language extension in all other modes.
> > The behavior in ObjC and MS extensions modes is unchanged (but the
> > bit-field disambiguation is a bit better); remaining language modes
> > follow the C++11 rules.
> >
> > Fixes PR45726, PR39979, PR19810, PR44941, and most of PR24297, plus C++
> > core issues 1514 and 1966.
> 
> Hello from Chromium :-)
> 
> We saw new errors from some code in a header that looked like this:
> 
>   // Adapted from NSPathUtilities.h and NSObjCRuntime.h.
>   typedef enum NSSearchPathDirectory : unsigned long NSSearchPathDirectory;
> 
> For us we think the enum itself is enough, so we'll fix it by dropping
> the typedef, but this raised the question of how your change affects
> the Mac system headers. IIUC your change makes an exception for Obj-C,
> but the headers can be used from regular C/C++ too. Do you think there
> might be issues there?
> 
> The errors are DefaultError ExtWarns, so they will be suppressed by default 
> in system headers. Even then:
>  * In Objective-C (and Objective-C++), the prior rule is unchanged.
>  * In (non-Objective) C++11 onwards, we now enforce the standard rules. 
> (System headers should ideally be valid code, but if not, the system header 
> exclusion will kick in. And the errors can be disabled by warning flag in 
> user code written against old Clang.)
>  * In any other language mode, system headers should really not be using this 
> functionality, since it's a non-standard language extension, and not 
> supported by (for example) GCC. (With the same provisos as in the prior 
> bullet.)
> 
> We can make the C++ side of things more permissive if necessary, but I'm 
> hopeful that we will be able to enforce the standard rules by default in this 
> instance.
> 
> (See https://chromium-review.googlesource.com/c/chromium/src/+/2193673 
> 
> for the Chromium discussion.)
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org 
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits 
> 
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org 
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits 
> 

Re: [clang] c90e198 - Fix parsing of enum-base to follow C++11 rules.

2020-05-11 Thread Richard Smith via cfe-commits
On Mon, 11 May 2020 at 06:37, Hans Wennborg via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> On Sat, May 9, 2020 at 4:32 AM Richard Smith via cfe-commits
>  wrote:
> >
> >
> > Author: Richard Smith
> > Date: 2020-05-08T19:32:00-07:00
> > New Revision: c90e198107431f64b73686bdce31c293e3380ac7
> >
> > URL:
> https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7
> > DIFF:
> https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7.diff
> >
> > LOG: Fix parsing of enum-base to follow C++11 rules.
> >
> > Previously we implemented non-standard disambiguation rules to
> > distinguish an enum-base from a bit-field but otherwise treated a :
> > after an elaborated-enum-specifier as introducing an enum-base. That
> > misparses various examples (anywhere an elaborated-type-specifier can
> > appear followed by a colon, such as within a ternary operator or
> > _Generic).
> >
> > We now implement the C++11 rules, with the old cases accepted as
> > extensions where that seemed reasonable. These amount to:
> >  * an enum-base must always be accompanied by an enum definition (except
> >in a standalone declaration of the form 'enum E : T;')
> >  * in a member-declaration, 'enum E :' always introduces an enum-base,
> >never a bit-field
> >  * in a type-specifier (or similar context), 'enum E :' is not
> >permitted; the colon means whatever else it would mean in that
> >context.
> >
> > Fixed underlying types for enums are also permitted in Objective-C and
> > under MS extensions, plus as a language extension in all other modes.
> > The behavior in ObjC and MS extensions modes is unchanged (but the
> > bit-field disambiguation is a bit better); remaining language modes
> > follow the C++11 rules.
> >
> > Fixes PR45726, PR39979, PR19810, PR44941, and most of PR24297, plus C++
> > core issues 1514 and 1966.
>
> Hello from Chromium :-)
>
> We saw new errors from some code in a header that looked like this:
>
>   // Adapted from NSPathUtilities.h and NSObjCRuntime.h.
>   typedef enum NSSearchPathDirectory : unsigned long NSSearchPathDirectory;
>
> For us we think the enum itself is enough, so we'll fix it by dropping
> the typedef, but this raised the question of how your change affects
> the Mac system headers. IIUC your change makes an exception for Obj-C,
> but the headers can be used from regular C/C++ too. Do you think there
> might be issues there?
>

The errors are DefaultError ExtWarns, so they will be suppressed by default
in system headers. Even then:
 * In Objective-C (and Objective-C++), the prior rule is unchanged.
 * In (non-Objective) C++11 onwards, we now enforce the standard rules.
(System headers should ideally be valid code, but if not, the system header
exclusion will kick in. And the errors can be disabled by warning flag in
user code written against old Clang.)
 * In any other language mode, system headers should really not be using
this functionality, since it's a non-standard language extension, and not
supported by (for example) GCC. (With the same provisos as in the prior
bullet.)

We can make the C++ side of things more permissive if necessary, but I'm
hopeful that we will be able to enforce the standard rules by default in
this instance.

(See https://chromium-review.googlesource.com/c/chromium/src/+/2193673
> for the Chromium discussion.)
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [clang] c90e198 - Fix parsing of enum-base to follow C++11 rules.

2020-05-11 Thread Hans Wennborg via cfe-commits
On Sat, May 9, 2020 at 4:32 AM Richard Smith via cfe-commits
 wrote:
>
>
> Author: Richard Smith
> Date: 2020-05-08T19:32:00-07:00
> New Revision: c90e198107431f64b73686bdce31c293e3380ac7
>
> URL: 
> https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7
> DIFF: 
> https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7.diff
>
> LOG: Fix parsing of enum-base to follow C++11 rules.
>
> Previously we implemented non-standard disambiguation rules to
> distinguish an enum-base from a bit-field but otherwise treated a :
> after an elaborated-enum-specifier as introducing an enum-base. That
> misparses various examples (anywhere an elaborated-type-specifier can
> appear followed by a colon, such as within a ternary operator or
> _Generic).
>
> We now implement the C++11 rules, with the old cases accepted as
> extensions where that seemed reasonable. These amount to:
>  * an enum-base must always be accompanied by an enum definition (except
>in a standalone declaration of the form 'enum E : T;')
>  * in a member-declaration, 'enum E :' always introduces an enum-base,
>never a bit-field
>  * in a type-specifier (or similar context), 'enum E :' is not
>permitted; the colon means whatever else it would mean in that
>context.
>
> Fixed underlying types for enums are also permitted in Objective-C and
> under MS extensions, plus as a language extension in all other modes.
> The behavior in ObjC and MS extensions modes is unchanged (but the
> bit-field disambiguation is a bit better); remaining language modes
> follow the C++11 rules.
>
> Fixes PR45726, PR39979, PR19810, PR44941, and most of PR24297, plus C++
> core issues 1514 and 1966.

Hello from Chromium :-)

We saw new errors from some code in a header that looked like this:

  // Adapted from NSPathUtilities.h and NSObjCRuntime.h.
  typedef enum NSSearchPathDirectory : unsigned long NSSearchPathDirectory;

For us we think the enum itself is enough, so we'll fix it by dropping
the typedef, but this raised the question of how your change affects
the Mac system headers. IIUC your change makes an exception for Obj-C,
but the headers can be used from regular C/C++ too. Do you think there
might be issues there?

(See https://chromium-review.googlesource.com/c/chromium/src/+/2193673
for the Chromium discussion.)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] c90e198 - Fix parsing of enum-base to follow C++11 rules.

2020-05-08 Thread Richard Smith via cfe-commits

Author: Richard Smith
Date: 2020-05-08T19:32:00-07:00
New Revision: c90e198107431f64b73686bdce31c293e3380ac7

URL: 
https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7
DIFF: 
https://github.com/llvm/llvm-project/commit/c90e198107431f64b73686bdce31c293e3380ac7.diff

LOG: Fix parsing of enum-base to follow C++11 rules.

Previously we implemented non-standard disambiguation rules to
distinguish an enum-base from a bit-field but otherwise treated a :
after an elaborated-enum-specifier as introducing an enum-base. That
misparses various examples (anywhere an elaborated-type-specifier can
appear followed by a colon, such as within a ternary operator or
_Generic).

We now implement the C++11 rules, with the old cases accepted as
extensions where that seemed reasonable. These amount to:
 * an enum-base must always be accompanied by an enum definition (except
   in a standalone declaration of the form 'enum E : T;')
 * in a member-declaration, 'enum E :' always introduces an enum-base,
   never a bit-field
 * in a type-specifier (or similar context), 'enum E :' is not
   permitted; the colon means whatever else it would mean in that
   context.

Fixed underlying types for enums are also permitted in Objective-C and
under MS extensions, plus as a language extension in all other modes.
The behavior in ObjC and MS extensions modes is unchanged (but the
bit-field disambiguation is a bit better); remaining language modes
follow the C++11 rules.

Fixes PR45726, PR39979, PR19810, PR44941, and most of PR24297, plus C++
core issues 1514 and 1966.

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Parse/Parser.h
clang/lib/Parse/ParseDecl.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Parse/ParseTentative.cpp
clang/lib/Sema/SemaDecl.cpp
clang/test/CXX/drs/dr15xx.cpp
clang/test/CXX/drs/dr19xx.cpp
clang/test/CXX/drs/dr21xx.cpp
clang/test/CXX/expr/expr.prim/expr.prim.general/p8-0x.cpp
clang/test/Parser/c1x-generic-selection.c
clang/test/Parser/cxx0x-ambig.cpp
clang/test/Parser/cxx0x-decl.cpp
clang/test/SemaCXX/enum-bitfield.cpp
clang/test/SemaCXX/enum-scoped.cpp
clang/test/SemaObjC/enum-fixed-type.m
clang/www/cxx_dr_status.html

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 552c9187e705..04014780615b 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -105,6 +105,14 @@ def ext_clang_c_enum_fixed_underlying_type : Extension<
 def warn_cxx98_compat_enum_fixed_underlying_type : Warning<
   "enumeration types with a fixed underlying type are incompatible with 
C++98">,
   InGroup, DefaultIgnore;
+def ext_enum_base_in_type_specifier : ExtWarn<
+  "non-defining declaration of enumeration with a fixed underlying type is "
+  "only permitted as a standalone declaration"
+  "%select{|; missing list of enumerators?}0">, 
InGroup>;
+def err_anonymous_enum_bitfield : Error<
+  "ISO C++ only allows ':' in member enumeration declaration to introduce "
+  "a fixed underlying type, not an anonymous bit-field">;
+
 def warn_cxx98_compat_alignof : Warning<
   "alignof expressions are incompatible with C++98">,
   InGroup, DefaultIgnore;

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b3f6f66a8c56..5ca0982ce5c3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5484,6 +5484,8 @@ def err_bitfield_width_exceeds_type_width : Error<
 def err_anon_bitfield_width_exceeds_type_width : Error<
   "width of anonymous bit-field (%0 bits) exceeds %select{width|size}1 "
   "of its type (%2 bit%s2)">;
+def err_anon_bitfield_init : Error<
+  "anonymous bit-field cannot have a default member initializer">;
 def err_incorrect_number_of_vector_initializers : Error<
   "number of elements must be either one or match the size of the vector">;
 

diff  --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index 4a8acf5cd196..cbdf9fede665 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -2181,6 +2181,68 @@ class Parser : public CodeCompletionHandler {
 llvm_unreachable("Missing DeclSpecContext case");
   }
 
+  /// Whether a defining-type-specifier is permitted in a given context.
+  enum class AllowDefiningTypeSpec {
+/// The grammar doesn't allow a defining-type-specifier here, and we must
+/// not parse one (eg, because a '{' could mean something else).
+No,
+/// The grammar doesn't allow a defining-type-specifier here, but we permit
+/// one for error recovery purposes. Sema will reject.
+