[Bug preprocessor/82359] #line does not allow C++14 quotes in number

2020-10-28 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82359

Aaron Ballman  changed:

   What|Removed |Added

 CC||aaron at aaronballman dot com

--- Comment #3 from Aaron Ballman  ---
(In reply to Jonathan Wakely from comment #1)
> (In reply to Andrew Schepler from comment #0)
> > In C++14 and later, any integer literal may contain single quote characters
> > (aka apostrophe, ASCII 0x27).
> 
> That's a standard defect (and has already been raised as such on the
> committee reflector).

I'm working on a proposal to add support for digit separators in C and came
across this bug as part of that effort. FWIW, I looked around for a defect on
this and could not find one, nor any reflector discussion on it. So I reached
out to Core to ask their opinion and the position seems to be that there's no
reason to disallow digit separators in #line directives. They observed that
digit separators are permitted in digit sequences in general (for example, in
preprocessor constant expressions), so treating #line as a special case would
seem like an arbitrary inconsistency. 

https://lists.isocpp.org/core/2020/10/10086.php

There is implementation divergence on it: GCC and EDG reject digit separators
in #line; Clang and MSVC accept.

I'm hoping to avoid accidentally diverging C and C++ here, so my intent is to
propose to accept digit separators in C as well. Is there a reason GCC needs to
reject that Core perhaps isn't aware of?

[Bug c++/101209] New: ICE with trailing return type on a conversion operator

2021-06-25 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101209

Bug ID: 101209
   Summary: ICE with trailing return type on a conversion operator
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: aaron at aaronballman dot com
  Target Milestone: ---

I was curious what kind of diagnostics different compilers would give me for
some nonsense code, and found that the following code causes an ICE in GCC.

struct S {
  operator int() const -> double;
};

:2:27: internal compiler error: in splice_late_return_type, at
cp/pt.c:29753
2 |   operator int() const -> double;
  |   ^~
0x1d48999 internal_error(char const*, ...)
???:0
0x724013 fancy_abort(char const*, int, char const*)
???:0
0x9847fc splice_late_return_type(tree_node*, tree_node*)
???:0
0x808c53 grokdeclarator(cp_declarator const*, cp_decl_specifier_seq*,
decl_context, int, tree_node**)
???:0
0x834403 grokfield(cp_declarator const*, cp_decl_specifier_seq*, tree_node*,
bool, tree_node*, tree_node*)
???:0
0x94cadd c_parse_file()
???:0
0xacfe82 c_common_parse_file()
???:0
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See  for instructions.
Compiler returned: 1

This should likely give an error about using a trailing return type for a
function with a declared return type other than a placeholder type.

[Bug c++/101209] ICE with trailing return type on a conversion operator

2021-06-25 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101209

--- Comment #1 from Aaron Ballman  ---
> This should likely give an error about using a trailing return type for a 
> function with a declared return type other than a placeholder type.

Err, that would be bad now that I think about it
(http://eel.is/c++draft/class.conv.fct#6). So I'd amend this to: it should
probably give a reasonable diagnostic. :-)

[Bug c/108694] need a new warning option for preparing migration to ISO C 23

2023-02-07 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108694

--- Comment #3 from Aaron Ballman  ---
(In reply to Bruno Haible from comment #2)
> But '-Wdeprecated-non-prototype' does not exactly have the behaviour you
> want: while it warns for 'func1 (1);' and 'func3 (3);' (good!), it warns
> also for 'void func3 ();', that is, where you don't want to see a warning.

FWIW, the reason you get a warning on the declaration of `func3` in Clang is
because of the definition of `func3` that is invalid in C2x but was valid in
prior standards modes. If you do not provide a problematic conflicting
definition, the diagnostic is silenced: https://godbolt.org/z/aMPrvWz1j

[Bug c/108796] Can't intermix C2x and GNU style attributes

2023-02-16 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108796

Aaron Ballman  changed:

   What|Removed |Added

 CC||aaron at aaronballman dot com

--- Comment #7 from Aaron Ballman  ---
(In reply to jos...@codesourcery.com from comment #6)
> The logic is that GNU attributes are declaration specifiers (and can mix 
> anywhere with other declaration specifiers), but standard attributes 
> aren't declaration specifiers; rather, they come in specified positions 
> relative to declaration specifiers (the semantics before and after the 
> declaration specifiers are different), and in the middle isn't such a 
> position.

How does that square with:
```
struct __attribute__((packed)) S { ... };
void func(int *ip) __attribute__((nonnull(1)));
```
where the GNU attribute is not written where a declaration specifier is
allowed?

FWIW, the Clang rationale for our behavior is that users don't really
distinguish between spelling an attribute with `[[]]` or spelling it with
`__attribute__` -- it's an attribute either way. We couldn't find a reason why
it made sense to force users to determine arbitrary parse ordering rules for
conceptually "identical" constructs. While not compatible with GCC's approach,
a correct usage in GCC is expected to also be a correct usage in Clang.

[Bug c/108796] Can't intermix C2x and GNU style attributes

2023-02-16 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108796

--- Comment #9 from Aaron Ballman  ---
> GNU attributes are declaration specifiers *in the previous examples given 
> here*, not necessarily in all other cases.

Thanks for clarifying!

> (There is then logic in GCC to handle __attribute__ that, according to the 
> syntax, should appertain to a particular entity, so that it's instead 
> applied to some other related entity; for example, moving an attribute 
> from a declaration to its type.  This is deliberately *not* done for [[]] 
> attribute syntax; those attributes are expected to be written in a correct 
> location for the entity they appertain to.)

This touches on why I came to the decision I did in Clang. What `__attribute__`
will apply to is sometimes inscrutable and users are (perhaps) used to it
sliding around to whatever works. As you point out, `[[]]` doesn't have the
same behavior; it has strict appertainment. Because `__attribute__` doesn't
have strict appertainment, it did not seem like an issue for it to continue to
shift around to whatever makes sense. Thus `[[]]` will apply to what the
standard says it applies to, and `__attribute__` applies to whatever it should
apply to based on the attribute names in the specifier, but users don't have to
know whether they need to write `[[]] __attribute__(())` vs `__attribute__(())
[[]]`. (Clang also supports `__declspec`, so there are more combinations to
worry about sometimes.)

It really boils down to whether `__attribute__` is fundamentally a different
"thing" than `[[]]` and I couldn't convince myself they were different. The
result is, when the grammar allows consecutive attribute syntaxes, we parse all
allowed syntaxes in a loop so users can write them in an arbitrary order.

[Bug c/108796] Can't intermix C2x and GNU style attributes

2023-02-16 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108796

--- Comment #10 from Aaron Ballman  ---
One other reason for the Clang behavior that may be worth mentioning is that
this helps users who wish to migrate away from `__attribute__` and towards
`[[]]`. Many (most?) uses of attributes end up behind a macro, so the user may
not even be aware which syntax is being used. Consider this contrived example:
```
// LibraryHeader.h
#if SOMETHING
#define FOO_ATTR __attribute__((foo))
#define BAR_ATTR __attribute__((bar))
#define BAZ_ATTR [[lib::baz]]
#elif SOMETHING_ELSE
...
#else
#define FOO_ATTR
#define BAR_ATTR
#define BAZ_ATTR
#endif

// UserCode.c
FOO_ATTR BAR_ATTR void func(void) { ... }
```
The user reading UserCode.c has no idea what attribute syntax is being used,
nor do they probably care all that much.

Under a strict parsing model, trying to add `BAZ_ATTR` to the declaration of
`func()` requires the user to be very aware of exactly what each macro expands
to, otherwise they might get the order wrong.

With a relaxed parsing model, the user doesn't have to care. Additionally, the
library header can migrate `BAR_ATTR` to `[[gnu::bar]]` syntax without also
migrating `FOO_ATTR` at the same time with less fear of breaking downstream
users due to attribute ordering, so this allows for gradual migration to a
newer syntax. (It's not "no fear" because `[[]]` has strict appertainment
rules, so it's possible for some attributes to break user code when migrating
from `__attribute__` to `[[]]` due to differences in appertainment.)

[Bug c++/104765] Expression statement with a return in a lambda-parameter-default causes segfault when called in a different function

2022-03-03 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104765

Aaron Ballman  changed:

   What|Removed |Added

 CC||aaron at aaronballman dot com

--- Comment #3 from Aaron Ballman  ---
Here's another example that causes diagnostics and then ICEs in a different
way: https://godbolt.org/z/nWTGEc1dW

template 
int foo(Callable&& Call) {
  return Call();
}

int main() {
  auto l = [](int a = ({ int x = 12; x; })) {
return a;
  };
  return foo(l);
}


(I was trying to see how well the locally-declared `x` in the lambda's default
argument worked in practice.) Consider me a +1 for prohibiting statement
expressions in lambda default arguments.

[Bug c++/104765] Expression statement with a return in a lambda-parameter-default causes segfault when called in a different function

2022-03-16 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104765

--- Comment #6 from Aaron Ballman  ---
(In reply to Marek Polacek from comment #4)
> My preference: prohibit any use of ({}) in default arguments.

That's my preference as well assuming it doesn't break a significant amount of
code (which I have no reason to believe it will).

[Bug ipa/104187] Call site specific attribute to control inliner

2022-02-10 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104187

Aaron Ballman  changed:

   What|Removed |Added

 CC||aaron at aaronballman dot com

--- Comment #7 from Aaron Ballman  ---
(In reply to Dávid Bolvanský from comment #5)
> So you prefer eg.
> 
> g = a[i] - [[gnu::always_inline]] foo(x, y) + 2 * bar();

To be clear, this syntax isn't valid in either C or C++. There are
statement-level attributes, there are not expression-level attributes.

[Bug c++/103084] New: Accepts invalid using enum declaration with an invalid elaborated-type-specifier

2021-11-04 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103084

Bug ID: 103084
   Summary: Accepts invalid using enum declaration with an invalid
elaborated-type-specifier
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: aaron at aaronballman dot com
  Target Milestone: ---

GCC (and MSVC) currently accepts the following snippet while Clang and ICC
reject:
```
enum class Pig { Oink };
using Hog = Pig;
using enum Hog; // Clang & ICC rejects, GCC & MSVC accepts
```
I think Clang and ICC are correct to reject this code.
http://eel.is/c++draft/enum.udecl says that the production needs to parse an
elaborated-enum-specifier. One of the requirements for a valid
elaborated-enum-specifier is that the elaboration has to agree in kind with the
given declaration (https://eel.is/c++draft/dcl.type.elab#6). In this case, the
given declaration is not an enum, it's a type alias.

Note that all compilers reject the following slightly different example due to
the elaborated type specifier being invalid:
```
enum class Pig { Oink };
using Hog = Pig;
enum Hog H; // Everyone rejects
```

[Bug c++/103084] Accepts invalid using enum declaration with an invalid elaborated-type-specifier

2021-11-04 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103084

--- Comment #5 from Aaron Ballman  ---
(In reply to Marek Polacek from comment #4)
> But elaborated-enum-specifier is an elaborated-type-specifier, so
> [dcl.type.elab]#6 should still apply, right?

That is my understanding. Otherwise p6 doesn't make much sense when it says
"The class-key or enum keyword present in the elaborated-type-specifier shall
agree" because that production has no enum keyword directly within it.

[Bug c++/103084] Accepts invalid using enum declaration with an invalid elaborated-type-specifier

2021-11-04 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103084

--- Comment #8 from Aaron Ballman  ---
(In reply to M Welinder from comment #6)
> elaborated-enum-specifier can be a elaborated-type-specifier.  It is in the
> "enum Hog H;" case.
> 
> But elaborated-enum-specifier is NOT an elaborated-type-specifier in the
> "using enum Hog;" case,
> 
> See http://eel.is/c++draft/enum.udecl -- this uses elaborated-enum-specifier
> directly.

You're correct about the productions, but http://eel.is/c++draft/dcl.type.elab
then provides no semantics whatsoever for what type is referred to by an
elaborated-enum-specifier. https://eel.is/c++draft/dcl.type.elab#6 would not
apply, so the only requirement on the type then comes from
http://eel.is/c++draft/enum.udecl#1, which says that the type referred to must
be a reachable enum-specifier. But the type named isn't a reachable
enum-specifier (maybe, who knows, no semantics means we can't really say), it's
a type alias to an enum-specifier. So there's confusion either way you read it,
IMO.

(In reply to M Welinder from comment #7)
> Maybe kick it up to the C++ people?
>
> Note, that if the code is not allowed then a type alias is no longer as
> powerful as the original type.  I really doubt that was intended.

FWIW, my initial inclination was that Clang and ICC were wrong to reject
because this does seem like a useful construct that should be supported. It is
possible there's a Core issue here and that this should not be rejected. The
original paper on the topic doesn't say anything, and I didn't see a mention of
type aliases in the WG21 wiki discussions for the paper, but it's entirely
possible I missed something while looking. So I agree that it'd be useful to
allow this, but I'm not convinced the standard permits it currently.

[Bug c++/102753] New: ICE on invalid use of pointer to a consteval member function

2021-10-14 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102753

Bug ID: 102753
   Summary: ICE on invalid use of pointer to a consteval member
function
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: aaron at aaronballman dot com
  Target Milestone: ---

The following code crashes GCC instead of giving an error:

struct test {
  consteval int f() const { return 12; }
};

constexpr test t;
int main() {
  (t.*&test::f)();
}

Note that the call to the PMF is not in a constant evaluated context.

https://godbolt.org/z/beWhE9qMv

[Bug c++/86369] constexpr const char* comparison fails

2022-11-04 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

Aaron Ballman  changed:

   What|Removed |Added

 CC||aaron at aaronballman dot com

--- Comment #9 from Aaron Ballman  ---
(In reply to Jason Merrill from comment #8)
> (In reply to Nicolas Lesser from comment #1)
> > For clarity, b1 shouldn't compile.
> > 
> > [lex.string]p16 says: "whether successive evaluations of a string-literal
> > yield the same or a different object is unspecified."
> > 
> > [expr.const]p2 says: "An expression e is a core constant expression unless
> > the evaluation of e, [...], would evaluate one of the following expressions:
> > [...]; a relational or equality operator where the result is unspecified;"
> 
> I think the second quote refers to places in [expr.eq] that say "the result
> is unspecified", not to all instances of unspecified behavior in the
> standard.

Doesn't [expr.eq] make it unspecified though?

[expr.eq]p6 says: "If two operands compare equal, the result is true for the ==
operator and false for the != operator. If two operands compare unequal, the
result is false for the == operator and true for the != operator. Otherwise,
the result of each of the operators is unspecified."

If it is unspecified whether a subsequent string literal evaluation produces
the same object or a different object then it's unspecified whether the two
operands will or won't compare equal, so the result of the operators is also
unspecified.

[Bug c++/86369] constexpr const char* comparison fails

2022-11-04 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369

--- Comment #11 from Aaron Ballman  ---
(In reply to Jakub Jelinek from comment #10)
> (In reply to Aaron Ballman from comment #9)
> > Doesn't [expr.eq] make it unspecified though?
> 
> Will defer that answer to Jason.
> But please have a look at the comment 6 testcase.  I strongly hope that
> constexpr const char *p = "abc";
> constexpr const char *q = p;
> static_assert (p == q, "");
> doesn't actually mean the string literal is evaluated multiple times, because
> if it would be, then one pretty much can't use string literals for anything
> reliably.

Oh yeah, I agree with you in that case. I was talking about the summary example
with function calls returning a string literal. Sorry for not being more clear!

> I bet the wording in there is for the
> constexpr const char *r = "abc";
> constexpr const char *s = "abc";
> case, where the standard doesn't force implementations to unify same string
> literals within the same TU but allows it (and also allows say tail merging
> of them).  From what I can see in the LLVM constant expression evaluation
> behavior, it doesn't track what comes from which evaluation of a string
> literal (GCC doesn't track that either) and just assumes that it could be
> different evaluation, while GCC assumes it is not.

Yeah, that sounds plausible.

[Bug c/107980] New: va_start incorrectly accepts an arbitrary number of arguments in C2x

2022-12-05 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107980

Bug ID: 107980
   Summary: va_start incorrectly accepts an arbitrary number of
arguments in C2x
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: aaron at aaronballman dot com
  Target Milestone: ---

GCC implemented WG14 N2975 which relaxes the requirements for va_start.
However, there's a diagnostic missing for it when the user passes more than two
arguments:
```
#include 

void func(int i, ...) {
  va_list va;
  va_start(va, i, 23, 4);

  va_end(va);
}

```
is silently accepted by GCC even with -Wall and -pedantic.

I noticed this when I was working on the Clang implementation of N2975. I
noticed that GCC has not changed the definition of __builtin_va_start, which I
think is a good approach (keeping builtin interfaces stable between compiler
and language versions is a nicety). I was considering adding
`__builtin_c23_va_start` to Clang with a signature that accepts `...` so I can
diagnose this case, but I think that will run afoul of 7.16.1.4p4 "Any
additional arguments are not used by the macro and will not be expanded or
evaluated for any reason." without some heroics, so I'm not certain how/if
Clang will address this.

[Bug c/107980] va_start incorrectly accepts an arbitrary number of arguments in C2x

2022-12-05 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107980

--- Comment #2 from Aaron Ballman  ---
(In reply to Andrew Pinski from comment #1)
> Hmm from https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3054.pdf :
> ```
> 7.16.1.4 The va_start macro
> void va_start(va_list ap, ...);
> 
> 
> Any additional arguments are not used by
> the macro and will not be expanded or evaluated for any reason.
> ```
> 
> 
> I would assume since it is `arguments` rather than additional argument, that
> it could be more than one additional argument.

Yes, the standard says "arguments" because there can be additional arguments
due to using `...`. However, think about the user experience:
```
// This should always be happily accepted because it's
// idiomatic C before C2x and it's valid C in C2x and later.
va_start(list, some_arg);

// This should be accepted in C2x mode and if you care
// to do such things, warn the user that it's incompatible
// with standards before C2x. Pre-C2x, this is an error.
va_start(list);

// Under what circumstances is this anything other than
// programmer confusion? It's invalid before C2x and the
// extra args are meaningless in C2x and later.
va_start(list, 1, 2, 3, 4);
```

[Bug c/107980] va_start does not warn about an arbitrary number of arguments in C2x mode

2022-12-06 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107980

--- Comment #5 from Aaron Ballman  ---
(In reply to Andrew Pinski from comment #3)
> I think we should warn but how to warn is going to have to special case the
> macro I think.

I was contemplating a perhaps terrible idea of adding some new builtins:
```
unsigned __builtin_va_opt_count(...);
void __builtin_c23_va_start(va_list list, unsigned arg_count);
```
and then doing something along these lines in stdarg.h:
```
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L
#define va_start(ap, ...) __builtin_c23_va_start(ap,
__builtin_va_opt_count(__VA_OPT__))
#else
...
#endif
```
but I've not put enough thought into it yet. WDYT about something along those
lines?

(In reply to Andrew Pinski from comment #4)
> (In reply to Andrew Pinski from comment #3)
> > I think we should warn but how to warn is going to have to special case the
> > macro I think.
> 
> But saying that I do think it is valid C2X code if you take the C2X standard
> seperately from the older standards.

I'm sad I noticed this after the NB comment period closed for the US NB because
otherwise I'd leave a comment to make it a constraint violation to pass more
than two arguments to the macro (or at least a recommended practice to
diagnose). Because I agree with you that the letter of the standard makes this
valid in C2x, but given that the extra arguments are not expanded or evaluated,
there is no reason to accept more than two arguments in any C standard version.

[Bug c/107980] va_start does not warn about an arbitrary number of arguments in C2x mode

2022-12-06 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107980

--- Comment #8 from Aaron Ballman  ---
(Sorry, I meant __VA_ARGS__ and not __VA_OPT__; C23 on the brain!)

(In reply to Andrew Pinski from comment #6)
> Maybe add a _Static_warn builtin instead which is like _Static_assert but
> instead of an error, it is a warning.
> 
> That is:
> #define va_start(ap, ...) (_Static_warn(__builtin_va_opt_count(__VA_OPT__)
> <= 1, "More than one argument supplied to the macro va_start"),
> __builtin_va_start(ap, 0))
> 
> 
> THe only issue is that message does not get translated.

Huh, that's a really neat idea to consider! But _Static_assert is a
declaration, not an expression, so we'd have to use a statement expression
there instead of rely on the comma operator. But I could use that for both
diagnosing passing > 2 args as well as passing < 2 args (we sometimes like to
warn "this feature is incompatible with standards before " in Clang).


(In reply to Jakub Jelinek from comment #7)
> Why do you need a builtin for counting number of arguments in __VA_OPT__?
> That can be done in the preprocessor.  All one needs is 1, 2 or more
> arguments.

Yes, you can beat the preprocessor into doing this for you, but a builtin that
counts the number of arguments in __VA_ARGS__ would solve a problem users have
(https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments),
so I figured it was better than preprocessor games.

[Bug c/107980] va_start does not warn about an arbitrary number of arguments in C2x mode

2022-12-06 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107980

--- Comment #9 from Aaron Ballman  ---
Btw, a similar issue in this area is that GCC no longer diagnoses when the user
passes a second argument to va_start in C2x mode and the argument is not the
parameter before the ellipsis. e.g.,
```
#include 

void diag(int a, int b, ...) {
  va_list list;
  va_start(list, a);
  va_end(list);
}
```
https://godbolt.org/z/daeYbPv6z

[Bug c/107980] va_start does not warn about an arbitrary number of arguments in C2x mode

2022-12-06 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107980

--- Comment #11 from Aaron Ballman  ---
(In reply to Jakub Jelinek from comment #10)
> That again is completely valid in C2X.

Yes, it is. And again, it's still something worth diagnosing (IMO) because it's
utter nonsense code that is invalid with C17 and earlier as well as C++.

I don't believe WG14 intended to make this invalid code valid for C2x.

[Bug c/107980] va_start does not warn about an arbitrary number of arguments in C2x mode

2022-12-07 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107980

--- Comment #14 from Aaron Ballman  ---
(In reply to jos...@codesourcery.com from comment #12)
> The standard rule about not using extra arguments means that any warnings 
> would need to avoid even converting those arguments from pp-tokens to 
> tokens; it's OK for them to contain pp-tokens that cannot be converted to 
> tokens.

Agreed, that's why I filed an NB comment to remove the restriction that the
arguments can't be expanded. Hopefully WG14 will relax that so we can give good
diagnostic behavior.

> I think the accepted change to the standard was entirely clear about 
> ignoring the extra arguments; it wasn't some obscure non-obvious 
> consequence that such code would become valid.

It was not discussed in the paper, or the meeting minutes, or my personal
notes. I may have missed something, but I have no reason to believe WG14
explicitly considered the ramifications of this. Also, I cannot find another
instance where a function-like macro accepts arguments that it is not allowed
to *expand*; that's a novel WG14 invention.

Also, it was a potentially silently breaking change (if you don't mind horribly
contrived examples of breakage): https://godbolt.org/z/T4bG6179f

[Bug c/107980] va_start does not warn about an arbitrary number of arguments in C2x mode

2022-12-07 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107980

--- Comment #16 from Aaron Ballman  ---
(In reply to Andrew Pinski from comment #15)
> (In reply to Aaron Ballman from comment #14)
> > Also, it was a potentially silently breaking change (if you don't mind
> > horribly contrived examples of breakage): https://godbolt.org/z/T4bG6179f
> 
> But __COUNTER__ is not part of the standard 

The code changed meaning regardless and WG14 usually goes out of our way to
avoid changing the meaning of existing, conforming code. (FWIW, I'll freely
admit this example is not compelling; it's just intended as a demonstration
that I don't think WG14 fully thought through the ramifications of what
prohibiting token expansion does in practice.)

[Bug c++/105824] New: Accepts invalid issue with implicit conversion of a scoped enumeration type

2022-06-02 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105824

Bug ID: 105824
   Summary: Accepts invalid issue with implicit conversion of a
scoped enumeration type
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: aaron at aaronballman dot com
  Target Milestone: ---

Consider the following code:
```
enum class E1 {
  Val1 = 1L
};

int p1[E1::Val1];
int *p2 = new int[E1::Val1];

```
GCC correctly diagnoses the declaration of p1 because E1::Val1 cannot be
implicitly converted to an integer type, but does not diagnose the new
expression which initializes p2 despite it requiring the same implicit
conversion.

Other compilers diagnose both p1 and p2: https://godbolt.org/z/Pd6dhdxxa

[Bug c++/110848] New: Consider enabling -Wvla by default in C++ modes

2023-07-28 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110848

Bug ID: 110848
   Summary: Consider enabling -Wvla by default in C++ modes
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: aaron at aaronballman dot com
  Target Milestone: ---

VLAs as they're expressed in C have been considered by WG21 and rejected, are
easy to use accidentally to the surprise of users (e.g.,
https://ddanilov.me/default-non-standard-features/), and they have potential
security implications beyond constant-size arrays
(https://wiki.sei.cmu.edu/confluence/display/c/ARR32-C.+Ensure+size+arguments+for+variable+length+arrays+are+in+a+valid+range).

As a result, I've been exploring enabling this diagnostic by default in Clang
in both C++ and GNU++ modes. The in-progress patch discussion can be found at
https://reviews.llvm.org/D156565. However, we like to keep our diagnostic
behaviors in sync with GCC when possible, so I'm wondering if GCC would also
consider such a change.

[Bug c++/110848] Consider enabling -Wvla by default in C++ modes

2023-07-28 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110848

--- Comment #3 from Aaron Ballman  ---
(In reply to Andrew Pinski from comment #1)
> Since VLA support has been a GNU C++ extension way before it was proposed to
> WG21, I doubt we want to enable this by default.

I think it boils down to whether you think users are using it on purpose or by
accident. My experience has been that more people use this by accident than not
in C++ and are unhappily surprised when they learn of it (sometimes by porting
to other compilers (like MSVC) that don't have the extension, sometimes through
other means like static analysis, etc). Given that there are security
implications with them, they're very easy to use accidentally, there are more
idiomatic approaches like std::vector, and that code generation can be quite a
bit slower for VLAs than other approaches, I think warning on them by default
is justifiable (the folks using them on purpose can add -Wno-vla to disable the
diagnostic, but I honestly expect them to be in the minority).

Do you have evidence there's a lot of intentional use of this feature in C++ in
the wild?

[Bug c++/110848] Consider enabling -Wvla by default in C++ modes

2023-07-29 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110848

--- Comment #6 from Aaron Ballman  ---
(In reply to Andrew Pinski from comment #4)
> Maybe my issue is this has been a documented extension for 20 years now.

Which is totally fair -- we don't usually enable congratulatory diagnostics by
default.

> -pedantic or -std=c++NN has always rejected it like it should. GCC has other
> extensions which folks could use by accident too (like statement
> expressions). Why is VLA special here?

FWIW, I can't honestly say I've ever seen someone use a statement expression
accidentally, though I believe it's possible to do so if you work hard enough
at it. That said, I think misuse of accidental VLAs has more opportunity for
poor security behavior (specifically around attacker-controllable stack usage)
than for statement expressions. Given the security concerns coupled with the
ease of accidental usage, I think VLAs *are* different than statement
expressions. Some supporting evidence of the confusion in the wild:

https://stackoverflow.com/questions/70912167/how-do-i-tell-if-i-am-using-vla-variable-length-array
https://stackoverflow.com/questions/39334435/variable-length-array-vla-in-c-compilers
https://ddanilov.me/default-non-standard-features/
https://meta.stackoverflow.com/questions/376955/what-should-i-do-when-an-op-uses-variable-length-arrays-vlas-in-c
https://cplusplus.com/forum/beginner/284866/

(Granted, there's confusion about *everything* in C and C++.)

It's worth noting that -std=c++NN does *not* reject use of VLAs; you have to
pass -pedantic or -Wvla to get the diagnostic: https://godbolt.org/z/PGorTYG7r

[Bug c++/110848] Consider enabling -Wvla by default in non-GNU C++ modes

2023-07-31 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110848

--- Comment #8 from Aaron Ballman  ---
(In reply to Richard Biener from comment #7)
> I think -std=c++XY should diagnose (at least with a warning) the use of GNU
> extensions.  Let me alter the summary and confirm.

Thanks! I still think this should be diagnosed in all language modes due to the
ease of accidental usage along with the feature's security concerns, but at
least getting it diagnosed by default in C++ language modes is a step in the
right direction. Some more evidence of the security concerns (VLAs in general,
not specific to C++):

https://nvd.nist.gov/vuln/detail/CVE-2015-5147
https://nvd.nist.gov/vuln/detail/CVE-2020-11203
https://nvd.nist.gov/vuln/detail/CVE-2021-3527

That said, it sounds like GCC maintainers feel (at least somewhat) strongly
that this extension should not be diagnosed by default in GNU mode. I think
Clang can follow suit so that there's less problems for folks porting between
the two compilers. But we've recently started being more aggressive about
diagnosing things that have security implications in C and C++ because of
warnings to not use these languages due to poor security practices and lack of
coverage with tooling:

https://advocacy.consumerreports.org/wp-content/uploads/2023/01/Memory-Safety-Convening-Report-1-1.pdf
https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI_SOFTWARE_MEMORY_SAFETY.PDF

I think VLA usage in C++ meets the bar as something to be more aggressive with
warning users about. It's not that the extension is broken, it's that it's very
often a surprise you're using the extension in the first place. It's
unfortunate to have to opt out of diagnostics about an extension you're
intentionally using; IMO, it's more unfortunate to have a CVE for your product
due to accidentally using an extension you weren't aware of.

[Bug c++/110848] Consider enabling -Wvla by default in non-GNU C++ modes

2023-08-01 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110848

--- Comment #10 from Aaron Ballman  ---
(In reply to Jonathan Wakely from comment #9)
> Personally I'd like it diagnosed in GNU modes, but this is pretty much the
> poster child for "conforming extension diagnosed with -pedantic" so I can
> see the argument for not diagnosing it by default.

Agreed -- I also see the argument for not diagnosing it by default. Normally I
wouldn't suggest such a thing and I would not consider this to be a precedent
to be applied to other extensions if it does get warned on by default. (I think
the only other extension that might m be in the same category
would be nested functions in C, but I've not spent nearly enough time
researching that one to be sure.)

[Bug c++/110848] Consider enabling -Wvla by default in non-GNU C++ modes

2023-08-04 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110848

--- Comment #12 from Aaron Ballman  ---
(In reply to Eric Gallager from comment #11)
> How about:
> 
> -std=c++XY: enabled by default (as per the proposal)
> -std=gnu++XY: enabled by -Wall and/or -Wextra (in addition to being enabled
> by -pedantic like it already is)

That's a good suggestion -- I'd be quite happy with adding it to -Wall (or
barring that, -Wextra) in GNU++ modes.

[Bug c/110977] New: Should -fms-extensions define _MSC_EXTENSIONS?

2023-08-10 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110977

Bug ID: 110977
   Summary: Should -fms-extensions define _MSC_EXTENSIONS?
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: aaron at aaronballman dot com
  Target Milestone: ---

This macro is predefined by MSVC when their extensions are enabled (/Ze in
cl.exe, on by default):
https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170

However, GCC does not define the macro when enabling Microsoft extensions. See
https://godbolt.org/z/MqKTz6ob7 for a reproducer.

Clang also does not define this macro when passing -fms-extensions, but we're
investigating defining the macro in this case
(https://reviews.llvm.org/D157334); if Clang goes that route, would GCC do the
same or are there reasons you're not defining this macro that we should be
aware of?

[Bug c++/110977] Should -fms-extensions define _MSC_EXTENSIONS?

2023-08-10 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110977

--- Comment #2 from Aaron Ballman  ---
(In reply to Andrew Pinski from comment #1)
> I don't think GCC has all of MSVC extensions implemented so defining that
> might break code 

Clang doesn't either, FWIW. But the point is well-taken; code thinking this is
a feature testing macro that says we've implemented all MS extensions could be
tripped up. But not defining the macro means code guarding use of MS extensions
which are supported also gets tripped up, just in the opposite direction.

Microsoft adds new extensions with basically every significant release, so
we'll always be behind them in terms of implementation. Because of that, I
think treating _MSC_EXTENSIONS as meaning "the user enabled whatever MS
extensions we support" is a practical interpretation.

[Bug c++/110848] Consider enabling -Wvla by default in non-GNU C++ modes

2023-10-21 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110848

--- Comment #13 from Aaron Ballman  ---
Just to circle back around on this topic, these are changes recently landed in
Clang:
https://github.com/llvm/llvm-project/commit/84a3aadf0f2483dde0acfc4e79f2a075a5f35bd1

It enables the -Wvla-extension diagnostic group in C++ language modes by
default, adds the warning group to -Wall in GNU++ language modes, and the
warning is still opt-in in C language modes.

[Bug c++/110848] Consider enabling -Wvla by default in non-GNU C++ modes

2023-10-22 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110848

--- Comment #17 from Aaron Ballman  ---
(In reply to Martin Uecker from comment #16)
> I do not think -Wall should warn about GNU extensions when used with
> -std=gnu++XX in C++ and I think it is annoying that clang does it now. It
> only drives people to use alloca or other alternatives with worse safety
> properties. 
> 
> And I think the security concerns for VLAs are largely based on a logical
> fallacy: Because they appear in CVE is no reason to believe they caused it:
> It is likely saying that people ICDs have more often cardiac arrests if
> because of the ICDs.  Any kind of dynamically sized buffer will appear in
> CVEs because buffers are used to process data from the network. If you
> discourage the one with the best potential for  bounds checking people will
> turn to worse options. This will not improve safety.
> 
> But stack clash protection should become the default.

In the time I opened this request, a new CVE related to VLAs came out:
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2023-4039

Stack protection should become the default and it should certainly help
mitigate issues, but VLAs are still a valid security concern IMO. So yes, this
is intended to drive people to use alternatives (not necessarily `alloca`,
which would be a strange choice of replacement for VLAs in C++ in 2023).

[Bug c++/110848] Consider enabling -Wvla by default in non-GNU C++ modes

2023-10-22 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110848

--- Comment #19 from Aaron Ballman  ---
(In reply to Andrew Pinski from comment #18)
> (In reply to Aaron Ballman from comment #17) 
> > In the time I opened this request, a new CVE related to VLAs came out:
> > https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2023-4039
> 
> Everything is a security risk. Seriously it is. Everything can and will be
> abused; does not mean it is always right to warn about it.  Also
> -fstack-protector should never be a CVE. CVEs will get to the point where
> they will be ignored because how they are now pointing out non-security
> issues.

My point is that this was a case where the developer used the language feature
and tried to do what they could to protect against security issues and still
ran into the security issue which resulted in a CVE. That's pretty different
from "everything can be abused". (I wasn't suggesting there's an issue with
using -fstack-protector or that it's a security issue itself)

[Bug driver/115990] New: Consider deprecating -Ofast

2024-07-18 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115990

Bug ID: 115990
   Summary: Consider deprecating -Ofast
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: driver
  Assignee: unassigned at gcc dot gnu.org
  Reporter: aaron at aaronballman dot com
  Target Milestone: ---

Clang 19 is expected to deprecate the -Ofast compiler option, with hopes to
remove the option sometime in the future (currently targeting 2026, but there's
flexibility in timeline and approach, including deprecating the option but
never removing it). The rationale why the Clang community is deprecating the
option may also apply to GCC, and can be summarized as:

* Users typically do not expect optimization levels to impact the correctness
of valid, correct code, but -Ofast enables -ffast-math which enables
non-conforming extensions that can impact the correctness of results.

* The name itself leads to people enabling it without realizing what those
impacts are. Deprecation ensures that users know about the behavior and it
guides users towards being more explicit about their intent with the command
line arguments.

* The original motivation for adding -Ofast (for compliance with SPEC benchmark
rules) no longer applies.

Does GCC have an appetite for deprecation with an eye towards eventual removal
for -Ofast?

Related:
https://discourse.llvm.org/t/rfc-deprecate-ofast/78687/
https://github.com/llvm/llvm-project/pull/98736

[Bug driver/115990] Consider deprecating -Ofast

2024-07-18 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115990

--- Comment #3 from Aaron Ballman  ---
(In reply to Andrew Pinski from comment #1)
> I don't think it should be deprecated or removed. It still has its uses.

Can you explain what those uses are and why they're not served by a more
explicit command line with `-O3 -ffast-math`? Mostly trying to understand if
there's something we've missed with Clang's assessment.

> Documentation is clear too.
> 
> We just fixed some documentation about the flags being enabled by -Ofast too.
> 
> People will never read the documentation either way anyways.

Agreed, that's part of why we're deprecating.

[Bug driver/115990] Consider deprecating -Ofast

2024-07-18 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115990

--- Comment #6 from Aaron Ballman  ---
Thank you for the feedback btw!

(In reply to Andrew Pinski from comment #4)
> (In reply to Aaron Ballman from comment #3).
> > > 
> > > People will never read the documentation either way anyways.
> > 
> > Agreed, that's part of why we're deprecating.
> 
> That is a real bad excuse really.

I disagree, but so it goes. :-)


> Also -Ofast for gcc is more than just -O3 -ffast-math. It enables unrolling
> loops and more.

Oh, that's really good to know, thank you!

[Bug driver/115990] Consider deprecating -Ofast

2024-07-19 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115990

--- Comment #14 from Aaron Ballman  ---
(In reply to Richard Biener from comment #13)
> Note that -ffast-math isn't in any way better, it doesn't suggest wrong-math
> either.  It possibly should have been -fno-ieee-conformant-math or so.

100% agreed and if there's an appetite to deprecate -ffast-math in place of
literally anything else, it's worth considering IMO. That flag has caused
significant user pain for years because who wouldn't want their math to be
fast?

[Bug c++/110343] [C++26] P2558R2 - Add @, $, and ` to the basic character set

2025-04-16 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110343

Aaron Ballman  changed:

   What|Removed |Added

 CC||aaron at aaronballman dot com

--- Comment #14 from Aaron Ballman  ---
(In reply to Jakub Jelinek from comment #11)
> I've posted https://gcc.gnu.org/pipermail/gcc-patches/2024-July/657583.html
> I don't think we should change the raw string handling for C23, because
> unlike C++26 they didn't add the $@` chars to the basic character set, but
> next to it.

5.2.1p3 added it to the list of graphic characters in the basic character set?

[Bug c++/110343] [C++26] P2558R2 - Add @, $, and ` to the basic character set

2025-04-16 Thread aaron at aaronballman dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110343

--- Comment #17 from Aaron Ballman  ---
(In reply to Jakub Jelinek from comment #16)
> N3220 does have those 3 in there too, but dunno if that is a post C23 or pre
> C23 draft.

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3124.pdf was adopted as a
resolution to US-032
(https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3148.doc), so this was a
(late) C23 change.