[Bug c++/115196] Bad error message when using library functions from versions before they were introduced

2024-05-22 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115196

--- Comment #5 from Halalaluyafail3  ---
(In reply to Jonathan Wakely from comment #4)
> (In reply to Halalaluyafail3 from comment #0)
> > This note doesn't seem to be very helpful, it mentions adding an extra
> > '#include' when one is already present. A better error message here
> > would be to omit the note, or to make it mention changing the selected C++
> > standard version.
> 
> If you'd tried gcc trunk on godbolt you'd have seen that's exactly what
> happens:
> 
> :3:10: note: 'std::to_address' is only available from C++20 onwards
> 
> There was just a typo which made gcc think std::to_address is part of
>  in C++11, so if it wasn't declared in your program then it must be
> because you didn't include .
> 
> After the fix it correctly suggests using at least C++20.

My bad, I only tested this on GCC 14.1 and assumed that GCC 14.1 was recent
enough that it wouldn't have been changed.

[Bug c++/115196] New: Bad error message when using library functions from versions before they were introduced

2024-05-22 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115196

Bug ID: 115196
   Summary: Bad error message when using library functions from
versions before they were introduced
   Product: gcc
   Version: 14.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

GCC generates some error messages when attempting to use library functions
without including the appropriate header, indicating that the appropriate
header should be included. This seems to act incorrectly when attempting to use
a library function from a version before the function was introduced, for
example:

#include
int main(){
std::to_address((void*)0);
}

std::to_address was introduced in C++20 so when using the default compilation
settings, i.e. C++17 this code is invalid. This is the generated error message
from testing on godbolt with GCC 14.1.0:

: In function 'int main()':
:3:10: error: 'to_address' is not a member of 'std'
3 | std::to_address((void*)0);
  |  ^~
:2:1: note: 'std::to_address' is defined in header ''; this is
probably fixable by adding '#include '
1 | #include
  +++ |+#include 
2 | int main(){

This note doesn't seem to be very helpful, it mentions adding an extra
'#include' when one is already present. A better error message here
would be to omit the note, or to make it mention changing the selected C++
standard version.

[Bug c/115109] Incorrect type of enumeration constant in redeclaration of enumeration constant (C23)

2024-05-18 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115109

--- Comment #4 from Halalaluyafail3  ---
(In reply to Halalaluyafail3 from comment #3)
> enum E { a = 1L, b = _Generic(a, enum E: 2) }; /* { dg-warning "outside the 
> range" } */
Seems like I copied this wrong, the comment should be a part of the first
quote.

[Bug c/115109] Incorrect type of enumeration constant in redeclaration of enumeration constant (C23)

2024-05-18 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115109

--- Comment #3 from Halalaluyafail3  ---
(In reply to uecker from comment #2)
> PATCH: https://gcc.gnu.org/pipermail/gcc-patches/2024-May/652093.html

I'm confused about the tests added here:

> enum H { x = 1 };
> enum H { x = 2UL + UINT_MAX };
Shouldn't this be a constraint violation if unsigned long is wide than
unsigned?

> If two declarations of the same type have a member-declaration or
> enumerator-list, one shall not be nested within the other and both
> declarations shall fulfill all requirements of compatible types (6.2.7)
> with the additional requirement that corresponding members of structure or
> union types shall have the same (and not merely compatible) types.
Section 6.7.3.4 "Tags" Paragraph 1 N3220

I don't see anything that would require a conversion to int here, nor would I
expect this to be the intent. It should just have the same value and the type
will end up the same as in the previous declaration.

> enum E { a = 1L, b = 2 };
> enum E { a = 1L, b = _Generic(a, enum E: 2) }; /* { dg-warning "outside the 
> range" } */
This just seems to be testing if int is compatible with enum E. Which from
testing on godbolt is false on GCC since it would pick for enum E to be
compatible with unsigned. This test also doesn't seem related to the problem
which was having the types of the integral constant expressions for a be
different types.

[Bug c/115109] New: Incorrect type of enumeration constant in redeclaration of enumeration constant (C23)

2024-05-15 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115109

Bug ID: 115109
   Summary: Incorrect type of enumeration constant in
redeclaration of enumeration constant (C23)
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

GCC does not accept the following code:

static_assert(INT_WIDTH<42&_WIDTH>=42);
enum E{a=1UL<<40,b=1};
enum E{a=1ULL<<40,b=_Generic(a,unsigned long:1,default:2)};

The static_assert is there to document the assumptions that should make this
code valid. Here is the relevant part of the standard:

> During the processing of each enumeration constant in the enumerator list,
> the type of the enumeration constant shall be:
> 
> - the previously declared type, if it is a redeclaration of the same
>   enumeration constant; or,
> 
> - the enumerated type, for an enumeration with fixed underlying type; or,
> 
> - int, if there are no previous enumeration constants in the enumerator list
>   and no explicit = with a defining integer constant expression; or,
> 
> - int, if given explicitly with = and the value of the integer constant
>   expression is representable by an int; or,
> 
> - the type of the integer constant expression, if given explicitly with = and
>   if the value of the integer constant expression is not representable by int;
>   or,
> 
>   ...
Section 6.7.3.3 "Enumeration specifiers" Paragraph 12 N3220

The types of the enumeration constants 'a' and 'b' in the first enumeration
specifier should be unsigned long and int, respectively. Then in the second
enumeration declaration, they should have the same types as the first
enumeration declaration because of the first item in the list in the above
quote. GCC does not seem to follow this and makes the type of the enumeration
constant 'a' unsigned long long because the type of the expression is unsigned
long long.

[Bug c/114873] Incorrect warning generated for [*] array when in atomic or typeof type specifier for a parameter declaration

2024-04-29 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114873

--- Comment #5 from Halalaluyafail3  ---
(In reply to Joseph S. Myers from comment #4)
> These are not meant to be valid C (although the relevant requirement isn't a
> Constraint, so a diagnostic isn't required); see the discussion in DR#341.

I thought these declarations were supposed to be valid since there doesn't seem
to be anything forbidding them (unless I misunderstood the text "part of the
nested sequence of declarators or abstract declarators for a parameter
declaration") and they seemed to make sense to me. I did see DR#341 before
making this bug report, and I assumed that it was specifically referring to the
case of [*] in array sizes. Thanks for making the intent clear.

I have recently thought about this again and realized that there may be an
alternative way of doing this:

void foo(typeof(int(*)[(0,0)])(*)[*]);
void bar(_Atomic(int(*)[(0,0)])(*)[*]);

It looks correct as (0,0) is not an integer constant expression and the array
type isn't [*]. GCC and Clang seem to accept this without complaint as well
(haven't tested other compilers). However the current wording says:

> If the size is an expression that is not an integer constant expression:
> if it occurs in a declaration at function prototype scope, it is treated
> as if it were replaced by *; otherwise, each time it is evaluated it shall
> have a value greater than zero.
Section 6.7.7.3 "Array declarators" Paragraph 5 N3220

This wording seems to say that the expression (0,0) would be replaced by *
which would make the program invalid? Or perhaps it means that the type gets
adjusted in the parameter declaration itself so that this is valid. The wording
doesn't seem very clear here, though if it was the former approach then the
following declarations would be invalid:

//the type names in typeof and sizeof have function prototype scope
void baz(size_t x,typeof(int[x])*y);
void qux(size_t x,int(*y)[sizeof(char[x])]);

Which seems unintended. I think this text should be updated to state how *
replacement happens in cases like these. It also isn't clear what would happen
in a declaration like the following:

int a=1;
typedef int b[a];//VLA outside of function prototype scope
void(*c)(b*);//then used in function prototype scope

This would depend upon whether 'it' refers to where the size expression is, or
to where the type is used and then gets adjusted.

[Bug c/114873] Incorrect warning generated for [*] array when in atomic or typeof type specifier for a parameter declaration

2024-04-27 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114873

--- Comment #3 from Halalaluyafail3  ---
(In reply to Andrew Pinski from comment #1)
> clang errors out:
> :3:24: error: star modifier used outside of function prototype
> 3 | void bar(_Atomic(int(*)[*])(*)[*]);
>   |^
> :3:30: error: a type specifier is required for all declarations
> 3 | void bar(_Atomic(int(*)[*])(*)[*]);
>   |  ^

I made a bug report for Clang earlier today about this:
https://github.com/llvm/llvm-project/issues/90348.

[Bug c/114873] New: Incorrect warning generated for [*] array when in atomic or typeof type specifier for a parameter declaration

2024-04-27 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114873

Bug ID: 114873
   Summary: Incorrect warning generated for [*] array when in
atomic or typeof type specifier for a parameter
declaration
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

GCC generates warnings for [*] arrays when in an atomic or type specifier even
if it is part of a parameter declaration for example:

void foo(typeof(int(*)[*])(*)[*]);
void bar(_Atomic(int(*)[*])(*)[*]);

These generate warnings (saying that '[*]' not in a declaration) when they
should be fine. They should be equivalent to:

void foo(int(*(*)[*])[*]);
void bar(int(*_Atomic(*)[*])[*]);

Which generate no warnings.

[Bug c++/114857] New: Pointer attributes and qualifiers are parsed in wrong order

2024-04-25 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114857

Bug ID: 114857
   Summary: Pointer attributes and qualifiers are parsed in wrong
order
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

GCC accepts the following declaration:

int*const[[]]p=0;

And rejects the following declaration:

int*[[]]const p=0;

It seems that GCC expects the attributes of a pointer declarator to come after
the qualifiers. The standard specifies in the grammar that the attributes
should come before qualifiers and not after:

> ptr-operator:
> * attribute-specifier-seq opt cv-qualifier-seq opt
> & attribute-specifier-seq opt
> && attribute-specifier-seq opt
> nested-name-specifier * attribute-specifier-seq opt cv-qualifier-seq opt
Section 9.3.1 "General" [dcl.decl.general] Paragraph 5 ISO/IEC 14882:2020

The first declaration should be rejected and the second declaration should be
accepted. Clang and MSVC get this correct (though not EDG I think so Visual
Studio will show errors in the correct declarations and not in the incorrect
declarations), and GCC gets this correct with pointer to members but not with
normal pointers.

[Bug c/114723] ICE when checking for type compatibility with structure that contains flexible array member (C23)

2024-04-23 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114723

--- Comment #6 from Halalaluyafail3  ---
(In reply to Andrew Pinski from comment #4)
> Oh this is with `-g -std=c23`, godbolt has an implicit -g.

I was not aware of this, thanks for letting me know. Do you know of any way to
disable it? Also it does seem to be quite related, so it is probably the same
bug which caused an ICE here (though the context of that test case would
require the types be the same so it's a little bit different).

[Bug c/114723] ICE when checking for type compatibility with structure that contains flexible array member (C23)

2024-04-23 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114723

--- Comment #3 from Halalaluyafail3  ---
Just tested on godbolt again and it cause an ICE, so perhaps something was
changed to cause an ICE again. Also upon thinking about the implications of
these types being compatible they probably shouldn't be compatible and it's
either a defect in the standard or I missed something that would make these
types incompatible.

[Bug c/114816] New: Non-standard behavior with void arguments

2024-04-22 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114816

Bug ID: 114816
   Summary: Non-standard behavior with void arguments
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

After thinking about qualified void return types I decided to think about void
function parameters:

> The special case of an unnamed parameter of type void as the only item in
> the list specifies that the function has no parameters.
Section 6.7.6.3 "Function declarators (including prototypes)" Paragraph 10
ISO/IEC 9899:2018

No other restrictions are present that would forbid void parameter types. GCC
seems to accept functions that use such arguments as long as they have names,
for example:

void a(void x);
void b(const void x,register void y,register volatile void z);

Are accepted by GCC, but the following declarations are not accepted by GCC
when they should be valid:

void c(void,void);
void d(const void);

Other incomplete types are accepted by GCC. Note that the type of the parameter
is const void and not void so d is a function taking an argument of type const
void and returning void, which means that the types of a and d are compatible.

The storage class register can be used on arguments and the same is true for
void arguments, which doesn't affect the type so the following program should
be valid:

int main(register void){}

Clang accepts this while GCC rejects. The storage class register doesn't affect
the type and it is still one unnamed parameter of type void so this should be a
declaration for zero arguments.

Calling any function with a void parameter is a constraint violation because of
the following contraint:

> If the expression that denotes the called function has a type that includes
> a prototype, the number of arguments shall agree with the number of
> parameters. Each argument shall have a type such that its value may be
> assigned to an object with the unqualified version of the type of its
> corresponding parameter.
Section 6.5.2.2 "Function calls" Paragraph 2 ISO/IEC 9899:2018

GCC does not diagnose the error and instead just interprets the first void
argument as being a sentinel value indicating when the arguments end, for
example with the function a from before GCC accepts calling it with zero
arguments. Qualified versions of void for example with the function b from
before are properly diagnosed.

When referencing a function type with a single void parameter GCC will omit the
name of the parameter as usual which leads to some confusing error messages,
for example:

void f(void x);
void f(void);

The error message indicates that these types are incompatible, but it describes
the first declaration as having type void(void). Here is the error output
omitting source locations:
> error: conflicting types for 'f'; have 'void(void)'
> void f(void);
>  ^
> note: previous declaration of 'f' with type 'void(void)'
> void f(void x);
>  ^

[Bug c/114808] Qualified void return type is not diagnosed

2024-04-22 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114808

Halalaluyafail3  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|NEW |RESOLVED

--- Comment #9 from Halalaluyafail3  ---
Resolving since I feel that the current behavior here is correct after looking
at the text in the standard enough. -Wignored-qualifiers also seems to cover
this case so adding a new warning shouldn't be needed either.

[Bug c/114808] Qualified void return type is not diagnosed

2024-04-22 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114808

--- Comment #6 from Halalaluyafail3  ---
* Paragraph 5 instead of Paragraph 4

[Bug c/114808] Qualified void return type is not diagnosed

2024-04-22 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114808

--- Comment #5 from Halalaluyafail3  ---
I made this bug report because of the warning that clang has, but the following
paragraph may allow this:

> If, in the declaration "T D1", D1 has the form
> D ( parameter-type-list )
> or
> D ( identifier-list opt )
> and the type specified for ident in the declaration "T D" is
> "derived-declarator-type-list T", then the type specified for
> ident is "derived-declarator-type-list function returning the
> unqualified version of T".
Section 6.7.6.3 "Function declarators (including prototypes)" Paragraph 4
ISO/IEC 9899:2018

GCC seems to be using this to not make a diagnostic here, e.g. it warns with a
return type of _Atomic void in C17 mode but not in C23 mode where the text here
was updated to indicate that the result is the unqualified and non-atomic
version of T. If this would make the text talking about the return type of the
function refer to the unqualified return type then this should be allowed I
think, and I will make a bug report to clang to get this diagnostic changed.

[Bug c/114808] New: Qualified void return type is not diagnosed

2024-04-22 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114808

Bug ID: 114808
   Summary: Qualified void return type is not diagnosed
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

The following code is accepted in GCC with no diagnostics being produced (even
when using -pedantic-errors):

const void f(void){}

This code violates the following constraint:

> The return type of a function shall be void or a complete object type other
> than array type.
Section 6.9.1 "Function definitions" Paragraph 3 ISO/IEC 9899:2018

const void is not void and it is not a complete object type.

[Bug c/114723] ICE when checking for type compatibility with structure that contains flexible array member (C23)

2024-04-16 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114723

--- Comment #2 from Halalaluyafail3  ---
(In reply to Richard Biener from comment #1)
> This seems to be fixed recently?

I just tested the code on godbolt again, and it doesn't seem to generate an ICE
anymore. However, it does seem to generate "incompatible" which seems to be
incorrect unless there is something that I missed in the standard which would
make these types incompatible.

[Bug c/114723] New: ICE when checking for type compatibility with structure that contains flexible array member

2024-04-15 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114723

Bug ID: 114723
   Summary: ICE when checking for type compatibility with
structure that contains flexible array member
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

The following code causes an internal compiler error on GCC 14:

#include
struct S{int x,y[1];}*a;
int main(void){
struct S{int x,y[];};
puts(_Generic(
a,
struct S*:"compatible",
default:"incompatible"
));
}

If I understand the type compatibility rules, these types should be compatible?
The types "int[1]" and "int[]" are compatible and everything else seems to
match exactly. Interestingly, it seems to also crash when checking if the type
of a is compatible with struct S (instead of struct S*).

[Bug libstdc++/114325] New: std::format gives incorrect results for negative numbers

2024-03-13 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114325

Bug ID: 114325
   Summary: std::format gives incorrect results for negative
numbers
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

The following code generates an incorrect result with libstdc++:

std::format("{}",-100)

>From testing on godbolt this seems to generate the string "-1\", then when
printed it looks like -10. This seems exclusive to GCC 14, and happens for any
numbers less than -99.

[Bug c++/114315] New: Attributes should be diagnosed when placed in the middle of declaration specifiers

2024-03-11 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114315

Bug ID: 114315
   Summary: Attributes should be diagnosed when placed in the
middle of declaration specifiers
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

GCC will accept programs that use attribute specifiers in the middle of
declaration specifiers, for example:

int[[]]signed main(){}

Attribute specifiers are not allowed inside of the declaration specifiers. I
would expect a warning or an error here, at least when
-pedantic/-pedantic-errors. Here is a link to the grammar of declaration
specifiers: https://eel.is/c++draft/dcl.spec.general#nt:decl-specifier-seq. The
attribute specifier is required to be at the end of the declaration specifiers.

[Bug c++/113571] Preprocessor if directive does not correctly recognize all C++ integral constant expressions

2024-01-23 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113571

--- Comment #3 from Halalaluyafail3  ---
The way the standard is written doesn't make any distinction between a
preprocessor constant expression and a language constant expression (from what
I have seen). The standard just says integral constant expression, and this
term is used both inside of the preprocessor and outside of the preprocessor;
for example the value of an enumerator. I don't see anything in the standard
would make the examples I provided invalid in a preprocessor if so I would
expect them to be valid.

[Bug c++/113571] New: Preprocessor if directive does not correctly recognize all C++ integral constant expressions

2024-01-23 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113571

Bug ID: 113571
   Summary: Preprocessor if directive does not correctly recognize
all C++ integral constant expressions
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

When preprocessing C++ code, GCC interprets preprocessor if expressions using
the same rules as C constant expressions. For example the following
preprocessor if directives cause errors when they should be valid C++:

#if(1,2)
#endif

#if 0?1.,2:3
#endif

#if([]{}(),1)==1
#endif

#if 0<=>0==0
#endif

The C++ standard requires that the expression in a preprocessor if directive is
an integer constant expression:

> The expression that controls conditional inclusion shall be an integral
> constant expression except that identifiers (including those lexically
> identical to keywords) are interpreted as described below and it may contain
> zero or more defined-macro-expressions and/or has-include-expressions and/or
> has-attribute-expressions as unary operator expressions.
Section 15.2 "Conditional inclusion" [cpp.cond] Paragraph 1 ISO/IEC 14882:2020

> An integral constant expression is an expression of integral or unscoped
> enumeration type, implicitly converted to a prvalue, where the converted
> expression is a core constant expression.
Section 7.7 "Constant expressions" [expr.const] Paragraph 8 ISO/IEC 14882:2020

The way C++ describes preprocessor if expressions is equivalent to constant
expressions outside of the preprocessor, so all of the examples listed in this
bug report should be valid (GCC does correctly allow these expressions in other
contexts, such as the value of an enumerator).

These quotes were taken from N4868, so the paragraph numbers not might match
exactly. The text in drafts after C++20 contain the same wording so they should
be correct.

[Bug c/113011] New: main declared with enumerated type is not accepted

2023-12-13 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113011

Bug ID: 113011
   Summary: main declared with enumerated type is not accepted
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

The following code is rejected in GCC with pedantic mode enabled:

enum E{e=-1};
_Static_assert(
_Generic((enum E)e,int:1,default:0),
"incorrect enumeration type"
);
enum E main(){}

If the static assertion succeeds, then the type enum E is compatible with int.
Given that enum E is compatible with int, it should be a valid return type of
main:

> If the return type of the main function is a type compatible with int,
> a return from the initial call to the main function is equivalent to
> calling the exit function with the value returned by the main function
> as its argument; reaching the } that terminates the main function returns
> a value of 0. If the return type is not compatible with int, the termination
> status returned to the host environment is unspecified.
Section 5.1.2.2.3 "Program termination" Paragraph 1 ISO/IEC 9899:2018

Additionally, here is the paragraph explaining that an enumerated type is
compatible with its underlying type:

> Each enumerated type shall be compatible with char, a signed integer type,
> or an unsigned integer type. The choice of type is implementation-defined,
> but shall be capable of representing the values of all the members of the
> enumeration.
Section 6.7.2.2 "Enumeration specifiers" Paragraph 4 ISO/IEC 9899:2018

Outside of pedantic mode, GCC accepts the code but returns a non-zero value
when the closing brace is reached which isn't correct either.

[Bug c/112841] New: typeof_unqual is not removing qualifiers from array types

2023-12-03 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112841

Bug ID: 112841
   Summary: typeof_unqual is not removing qualifiers from array
types
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

GCC does not remove qualifiers from array types when used with typeof_unqual:

puts(_Generic(
(typeof_unqual(const int[])*)0,
int(*)[]:"non-const",
const int(*)[]:"const"
));

This should print non-const, but GCC prints const.

The latest working draft of the standard includes an example of typeof_unqual
with an array of const:

> EXAMPLE 2 The following program:
> const _Atomic int purr = 0;
> const int meow = 1;
> const char* const animals[] = {
> "aardvark",
> "bluejay",
> "catte",
> };
> typeof_unqual(meow) main (int argc, char* argv[]) {
> typeof_unqual(purr) plain_purr;
> typeof(_Atomic typeof(meow)) atomic_meow;
> typeof(animals) animals_array;
> typeof_unqual(animals) animals2_array;
> return 0;
> }
> is equivalent to this program:
> const _Atomic int purr = 0;
> const int meow = 1;
> const char* const animals[] = {
> "aardvark",
> "bluejay",
> "catte",
> };
> int main (int argc, char* argv[]) {
> int plain_purr;
> const _Atomic int atomic_meow;
> const char* const animals_array[3];
> const char* animals2_array[3];
> return 0;
> }
Section 6.7.2.5 "Typeof specifiers" Paragraph 7, from N3096

Here, GCC does not not remove the const on the array type for animals2_array in
the first part of the example.

[Bug c++/112839] New: Unable to default initialize member variable in specific circumstances

2023-12-03 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112839

Bug ID: 112839
   Summary: Unable to default initialize member variable in
specific circumstances
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

The following code is not accepted by GCC:

struct A {
struct B {
int C = 0;
};
A() = default;
A(int) {}
std::pair p;
};

The error message generated indicates that it was unable to find a constructor
to call in the constructor A(int).

Doing any of the following seems to remove the error:
1. Removing the constructor A()
2. Explicitly define the constructor A()
3. Defining a default constructor for B (that isn't defaulted)
4. Removing the default value from C
5. Initializing p when it is being declared, i.e. std::pair p{};
6. Defining B outside of the class
7. Using a non-default constructor in the member initializer list

Clang, MSVC, and old versions of GCC (version 8, version 5, and version 4)
accept this code.

[Bug c/112556] Null pointer constants with enumeration type are not accepted

2023-11-15 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112556

--- Comment #1 from Halalaluyafail3  ---
This bug also seems to happen with boolean types:

void*p=(_Bool)0;

Furthermore, this bug only seems to happen when the type
of the null pointer constant is an enumeration or boolean type:

void*p1=+(_Bool)0,*p2=+(enum{E})E;

No errors are generated for this code.

[Bug c/112556] New: Null pointer constants with enumeration type are not accepted

2023-11-15 Thread luigighiron at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112556

Bug ID: 112556
   Summary: Null pointer constants with enumeration type are not
accepted
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: luigighiron at gmail dot com
  Target Milestone: ---

The following code is not accepted in GCC:

void*p=(enum{E})E;

To make it clear why this code should be accepted, I have
provided some references to the current C standard.

> An integer constant expression with the value 0,
> or such an expression cast to type void *, is called
> a null pointer constant. If a null pointer constant is
> converted to a pointer type, the resulting pointer,
> called a null pointer, is guaranteed to compare unequal
> to a pointer to any object or function.
Section 6.3.2.3 "Pointers" Paragraph 1 ISO/IEC 9899:2018

> An integer constant expression shall have integer type
> and shall only have operands that are integer constants,
> enumeration constants, character constants, sizeof
> expressions whose results are integer constants,
> _Alignof expressions, and floating constants that are
> the immediate operands of casts. Cast operators in an
> integer constant expression shall only convert arithmetic
> types to integer types, except as part of an operand
> to the sizeof or _Alignof operator.
Section 6.6 "Constant expressions" Paragraph 6 ISO/IEC 9899:2018

> The type char, the signed and unsigned integer types,
> and the enumerated types are collectively called
> integer types. The integer and real floating types are
> collectively called real types.
> 
> Integer and floating types are collectively called
> arithmetic types. Each arithmetic type belongs to
> one type domain: the real type domain comprises the
> real types, the complex type domain comprises the
> complex types.
Section 6.2.5 "Types" Paragraphs 17 and 18 ISO/IEC 9899:2018

(enum{E})E is an integer constant expression because
E is an enumeration constant, and the cast is converting
an arithmetic type (int) to an integer type (the enumeration
type). This integer constant expression has the value zero,
so it is a null pointer constant.

This problem seems to be specific to null pointer constants,
for example the type int(*)[(enum{A,B})B] is not considered
to be a variable length array type (which is correct).