[Bug tree-optimization/94357] New: Inline assembly with memory operand is considered nothrow with `-fnon-call-exceptions`

2020-03-27 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94357

Bug ID: 94357
   Summary: Inline assembly with memory operand is considered
nothrow with `-fnon-call-exceptions`
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

Created attachment 48130
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48130&action=edit
Issue demonstration

The documentation of `-fnon-call-exceptions`
(https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fnon-call-exceptions)
states that any instruction with a "memory references" is allowed to throw a
c++ exception (or in other words: do what essentially boils down to performing
a CFI unwind, and calling `__gxx_personality_v0()` without that function
calling `std::terminate()` because the faulting PC isn't allowed to trap)

However, from what I can tell by looking at the GCC sources
(gcc/tree-eh.c:tree_could_trap_p(); case ASM_EXPR), GCC only considers an
`asm()` statement as being able to cause a non-call-exception (i.e. trap) when
written as `asm volatile()`.

Given the fact that "memory references" is listed as one of the possible
reasons for an instruction to be trapable, it stands reason that any inline
assembly statement that uses memory operands (i.e. `asm("..." : "=m" (...))` or
`asm("..." : : "m" (...))`), as well as any assembly statement that specifies
"memory" as part of its clobber list (i.e. `asm("..." : : : "memory")`) should
also be considered as potentially containing instructions that may trap.

Note also that during my investigation I've noticed that the catch(...) block
is fully optimized away in the following case ... (`gcc -S` does contain `/*
Hello */`, but doesn't contain `/* World! */`):
```c
void foo() {
try {
__asm__ __volatile__("/* Hello */");
} catch (...) {
__asm__("/* World! */");
}
}
```

... but isn't optimized away when the first `__asm__ __volatile__` is placed in
an inline function (`gcc -S` does contains both `/* Hello */` and `/* World!
*/`):
```c
inline void bar() {
__asm__ __volatile__("/* Hello */");
}
void foo() {
try {
bar();
} catch (...) {
__asm__("/* World! */");
}
}
```


The attached file shows the different cases where `__asm__` appears in `try ...
catch`, and should be compiled as follows (note that -O* flags don't have any
affect on which catch-statements get deleted; -O0 has the same output as -O3):
$ g++ -S -x c++ -fnon-call-exceptions attaced-file.cc -o - | grep "reference"

The current output is:```
callmust_reference_1
```

A consistent output (with the current rules concerning __volatile__) would look
like:```
callmust_reference_1
callmust_reference_2
callmust_reference_3
```

And an output consistent with published documentation would look like:```
callmust_reference_1
callmust_reference_2
callmust_reference_3
callmust_reference_4
callmust_reference_5
callmust_reference_6
```

[Bug debug/96417] New: c++ `using` causes massive debug-info bloat (debug-info is kept for types/symbols)

2020-08-02 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96417

Bug ID: 96417
   Summary: c++ `using` causes massive debug-info bloat
(debug-info is kept for types/symbols)
   Product: gcc
   Version: 9.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: debug
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

Created attachment 48982
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48982&action=edit
Compile me with and without -DNO_USING

It appears as though the c++ `using` keyword prevents
  - `-feliminate-unused-debug-symbols` and
  - `-feliminate-unused-debug-types`
from working for the associated symbol/type. As such, any use of c++'s `using`
causes debug information to be generated, even if (in the case of symbols) the
associated object doesn't appears as an addressible entity in generated object
files, or are ever even used.

As a demonstration, you may compile the attached file as:
  $ g++ -g -S -o - demo.cc | grep imported_
.string "_ZN1a17imported_functionEi"
.string "imported_function"
.string "imported_type"
  $ g++ -g -S -o - demo.cc -DNO_USING | grep imported_


Note that only `using ns::symbol;` is affected by this, but `using namespace
ns;` works just fine.

In addition to g++9.3.0, I was also able to reproduce the same problem on
g++9.1.0 and g++5.4.0, meaning that this must have been going on for ages. - So
long as a matter of fact that I'm wondering if there's some ABI mandate that
requires this kind of behavior???
In case there is some kind of weird, non-sensical ABI requirement that requires
debug information to always be generated for c++ using declarations, I'd like
to request a commandline option to work around this, as I'm working on a
program that's currently 4MiB actual text+data, and 6MiB debug info (and that
is with already using -gz=zlib)

[Bug c++/96516] New: template + __attribute__((copy)) produce compiler errors

2020-08-07 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96516

Bug ID: 96516
   Summary: template + __attribute__((copy)) produce compiler
errors
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

Created attachment 49016
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49016&action=edit
Same code as already seen in the bug description

Using `__attribute__((copy(...)))' to inherit an `returns_nonnull' attribute
will cause a compiler error if the applied-to function's return type uses a
decltype type-expression, or has it's is-pointer-y-ness depend on a template
parameter. However, when `returns_nonnull' is not inherited via `copy()', but
explicitly used, then everything still works fine, so there appears to be a
discrepency between using `copy()' to inherit `returns_nonnull', and specifying
`returns_nonnull' directly.

```
__attribute__((returns_nonnull)) void *base(void *);

  __attribute__((copy(base))) __typeof__((void *)0) wrap1(void
*);
  __attribute__((copy(base)))   decltype((void *)0) wrap2(void
*);
template __attribute__((copy(base)))  T   *wrap3(T *);
template __attribute__((copy(base)))  decltype(T())   *wrap4(T *);
template __attribute__((returns_nonnull)) decltype((T *)0) wrap5(T *);
template __attribute__((copy(base)))  decltype((T *)0) wrap6(T *);
template __attribute__((copy(base)))__typeof__((T *)0) wrap7(T *);
template __attribute__((copy(base)))  Twrap8(T);
template __attribute__((returns_nonnull)) Twrap9(T);
```

All of these `wrapN()' functions should work the same, and none of them should
produce an error, but `wrap6()', `wrap7()' and `wrap8()' produce errors:
`returns_nonnull attribute on a function not returning a pointer'

I know that `__attribute__((copy(...)))' is a gcc extension, and this bug only
happens with g++, and I also know that it being an extension, it's correct
behavior isn't written in stone. But in this example, it's behavior is plainly
inconsistent (if `returns_nonnull' wasn't allowed with a template-dependent
return expression, then `wrap5()' and `wrap9()' should also cause errors, even
though they don't), and as already stated, _all_ of the above should work
without issues in my opinion.

I've placed this Report under c++ since this bug seems to be specific to the
combination of `template' + `__attribute__((copy))', where the template-part is
specific to c++. But if I had to guess, this is probably caused by a minor
difference in how `copy()' sets the `returns_nonnull' attribute vs. how
directly making use of `returns_nonnull' does the same.


Note: The same thing also happens with `__attribute((malloc))' and
`__attribute((nonnull(...)))' (in the case of `nonnull(...)', it even appears
to produce errors for _all_ template-functions that use `copy()' (`wrap5' and
`wrap9' continue to work correctly, so this is most definitely a problem with
`copy()')) (s.a. the attached `bug.cc`, which is replicated in the following):
```
__attribute__((returns_nonnull, malloc, nonnull(1))) void *base(void *);

  __attribute__((copy(base))) __typeof__((void *)0)
wrap1(decltype((void *)0));
  __attribute__((copy(base)))   decltype((void *)0)
wrap2(decltype((void *)0));
template __attribute__((copy(base)))  T  
*wrap3(decltype((T *)0));
template __attribute__((copy(base)))  decltype(T())  
*wrap4(decltype((T *)0));
template __attribute__((returns_nonnull, nonnull(1))) decltype((T *)0)
wrap5(decltype((T *)0));
template __attribute__((copy(base)))  decltype((T *)0)
wrap6(decltype((T *)0));
template __attribute__((copy(base)))__typeof__((T *)0)
wrap7(decltype((T *)0));
template __attribute__((copy(base)))  T   
wrap8(T);
template __attribute__((returns_nonnull, nonnull(1))) T   
wrap9(T);
```
The following are the errors produced by the above code. Note that inheriting
`__attribute__((malloc))' causes the `returns_nonnull` error to become
duplicated for `wrap6()', `wrap7()' and `wrap8()' for some reason (possibly an
unrelated bug), and that `wrap5()' and `wrap9()' (i.e. the declarations that
don't use `copy()') produces no errors or warnings:
```
[wrap3]: warning: 'nonnull' attribute argument value '1' refers to parameter
type 'decltype ((T*)(0))' [-Wattributes]
[wrap4]: warning: 'nonnull' attribute argum

[Bug c++/96516] template + __attribute__((copy)) produce compiler errors

2020-08-07 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96516

--- Comment #3 from sagebar at web dot de ---
No problem. Also: What you just said made me realize that once
__attribute__((copy)) works correctly with templates, _any_ attribute that can
be inherited via copy() can be made template-conditional in c++:

```
template struct conditional_returns_nonnull {
static __attribute__((returns_nonnull)) void *func(void);
};
template<> struct conditional_returns_nonnull {
static void *func(void);
};

template __attribute__((copy(conditional_returns_nonnull::func)))
void *function_with_conditional_returns_nonnull_attribute();

#define SASS(x) static_assert(x, #x)
SASS(!__builtin_has_attribute(
conditional_returns_nonnull::func,
returns_nonnull));
SASS(__builtin_has_attribute(
conditional_returns_nonnull::func,
returns_nonnull));

SASS(!__builtin_has_attribute(
function_with_conditional_returns_nonnull_attribute,
returns_nonnull));
SASS(__builtin_has_attribute(
function_with_conditional_returns_nonnull_attribute,
returns_nonnull));
```

Currently, this doesn't compile due to the last `static_assert()' failing
(Which I'm guessing is due to the same bug)
-> So I guess: Here's another test

[Bug c++/96516] template + __attribute__((copy)) produce compiler errors

2020-08-07 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96516

--- Comment #4 from sagebar at web dot de ---
(In reply to sagebar from comment #3)
> ..., _any_ attribute that
> can be inherited via copy() can be made template-conditional in c++:

Also note that I've tested if gcc (`-x c') allows multiple copy attributes on
the same declaration, and it appears to do allow this, meaning that deferring
attribute copy until template instantiation should be made functional for 0-N
copy attributes, rather than 0-1:

gcc currently allows multiple __attribute__((copy)) within the same
declaration:
```

__attribute__((returns_nonnull)) void *func_with_returns_nonnull();
__attribute__((malloc)) void *func_with_malloc();

__attribute__((
copy(func_with_returns_nonnull),
copy(func_with_malloc)))
void *func_with_both();

#define SASS(x) static_assert(x, #x)
SASS(__builtin_has_attribute(func_with_returns_nonnull, returns_nonnull));
SASS(!__builtin_has_attribute(func_with_returns_nonnull, malloc));
SASS(!__builtin_has_attribute(func_with_malloc, returns_nonnull));
SASS(__builtin_has_attribute(func_with_malloc, malloc));
SASS(__builtin_has_attribute(func_with_both, returns_nonnull));
SASS(__builtin_has_attribute(func_with_both, malloc));
```

[Bug c++/96985] New: c++ `noexcept` is ignored for *known* functions

2020-09-08 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96985

Bug ID: 96985
   Summary: c++ `noexcept` is ignored for *known* functions
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

g++ has a list of *special* function names that it recognizes as builtins. This
includes things like `memcpy` or `strlen`.

The problem is that this list includes information about a function being
nothrow/noexcept, too, and there doesn't seem to be any way of preventing g++
from compiling/generating code based on these assumptions, even if they violate
a previous, explicit declaration, and even when "-ffreestanding -fno-builtin"
is passed on the commandline.

See the following (compile as `g++ -ffreestanding -fno-builtin`):
```
extern "C" {
extern void *cpymem(void *, void const *, unsigned long) noexcept(false);
extern void *memcpy(void *, void const *, unsigned long) noexcept(false);
} /* extern "C" */

static_assert(!noexcept(cpymem(0, 0, 0)));
static_assert(!noexcept(memcpy(0, 0, 0)));
```

The second static_assertion (the one for `memcpy`) fails because despite asking
g++ to compile without any assumptions in regards to *known* functions
(-ffreestanding), it still makes use of its builtin assumptions regarding a
function named `memcpy()`. (Note: I know the `noexcept(false)` are redundant,
but they're there to emphasize my point)


Work-around:
```
#define STRINGIFY2(x) #x
#define STRINGIFY(x) STRINGIFY2(x)
extern "C++" {
extern void *memcpy(void *, void const *, unsigned long)
__asm__(STRINGIFY(__USER_LABEL_PREFIX__) "memcpy");
} /* extern "C++" */
static_assert(!noexcept(memcpy(0, 0, 0)));
```
I assume this works because only functions with extern-c linkage are considered
candidates for builtin functions, so declaring as extern-c++ and assigning the
proper asm-name for extern-c manually, bypasses the is-a-builtin detector
entirely.


Proposed solution / expected behavior:
 - gcc/g++ should disregard whatever it believes to be the case in regards to
nothrow/noexcept for any *known* function when `-ffreestanding` or
`-fno-builtin` are given.
 - Similarly, when `-fnon-call-exceptions` is given, gcc/g++ should assume that
the library variant of any of its builtin functions may throw an exception
(example: `memcpy()` can trigger SIGSEGV)
- iow: Handle `-fnon-call-exceptions` the same as `-ffreestanding` /
`-fno-builtin` in regards to nothrow/noexcept

[Bug c++/92438] New: Function declaration parsed incorrectly with `-std=c++1z`

2019-11-10 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92438

Bug ID: 92438
   Summary: Function declaration parsed incorrectly with
`-std=c++1z`
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

Created attachment 47204
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47204&action=edit
Demonstration of incorrect parsing + several work-arounds

Functions declarations returning a typedef'ed struct-type, and having their
names wrapped by parenthesis, as well as a calling-convention attribute within
those parenthesis, causes g++ to think that it's a variable declaration, rather
than a function declaration.

Essentially, given something like this:
```
typedef struct myint_struct { int x; } MYINT;
```

All of the following declarations get parsed correctly:
```
MYINT (myabs1)(MYINT x);
MYINT __attribute__((stdcall)) myabs2(MYINT x);
struct myint_struct (__attribute__((stdcall)) myabs3)(MYINT x);
```

However, this declaration (incorrectly) causes a parser error:
```
MYINT (__attribute__((stdcall)) myabs4)(MYINT x);
```

Note that the problem only appears when `-std=c++1z` or `-std=gnu++1z` is
passed on the commandline, such that you can re-produce the problem with the
attached file and:
```
g++ -c -std=c++1z attached-file.cc
g++ -c -std=gnu++1z attached-file.cc
```

However, compiling it without any special std=... flag doesn't produce any
errors:
```
g++ -c attached-file.cc
```

[Bug c++/92438] [7/8/9/10 Regression] Function declaration parsed incorrectly with `-std=c++1z`

2019-11-11 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92438

--- Comment #2 from sagebar at web dot de ---
The c++ standard may not cover it, however in the interest of compatibility
with other compilers, g++ for cygwin actually defines the following predefined
macros (among others):

g++ -dM -E -x c++ - < /dev/null | grep cdecl
```
#define _cdecl __attribute__((__cdecl__))
#define __cdecl __attribute__((__cdecl__))
```

Obviously, these are there for compatibility with msvc, and as it turns out:
msvc _only_ allows calling convention attributes if they are written between a
function's return type, and its name (or in the case of there being
parenthesis: only inside of them).
```
// - The only way that msvc accepts it
// - One of the ways that g++ for cygwin accepts it
int __cdecl foo();
int (__cdecl bar)();
```

So it does make perfect sense, and in a way is very much intended behavior in
my mind that __attribute__((...)) is accepted in that same place, and even more
so: If you look at the windows headers used by cygwin, you'll see that this is
behavior that is very much depended upon.

And even disregarding the (thus far fully maintained) compatibility with msvc
as far as the annotation of calling conventions go, this is most definitely
still a bug since using the typedef'd name `MYINT` as return type breaks g++,
however using the struct's name (including the `struct` prefix) as `struct
myint_struct` gets parsed correctly (so whatever would be the ~correct~ way of
doing, g++ is inconsistent about it).

[Bug middle-end/92641] New: Function called from dead branch

2019-11-23 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92641

Bug ID: 92641
   Summary: Function called from dead branch
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

Created attachment 47339
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47339&action=edit
Listing of problematic code, and similar code that works correctly

Given something like this:```
extern unsigned int get_vla_size(void);
```

This is ok:```
if (0) {
(void)(int(*)[get_vla_size()])0;
} else {
(void)get_vla_size();
}
```
asm:```
call_Z12get_vla_sizev
```


However, re-writing this code to use the ?-operator causes `get_vla_size()` to
be called twice:```
0 ? (
(void)(int(*)[get_vla_size()])0
) : (
(void)get_vla_size()
);
```
asm:```
call_Z12get_vla_sizev
call_Z12get_vla_sizev
```
Note that the first call to `get_vla_size()` happens from within a dead branch,
meaning that the call should have been fully removed, or at the very least have
been skipped by an unconditional jump.


When the first branch is wrapped in statement-expressions, code once again
function as expected:```
0 ? ({
(void)(int(*)[get_vla_size()])0;
}) : (
(void)get_vla_size()
);
```
asm:```
call_Z12get_vla_sizev
```


This problem consistently appears when compiling for c++, regardless of
optimization level, and if I had to guess, it's probably related to the scope
in which some given type is declared, where `type-expr` in `{ int x; 0 ?
(type-expr)expr : expr; }` is declared in the same scope as `x`, and thereby
unconditionally initialized.

The problem can be reproduced using:```
g++ -S attached-file.cc && cat attached-file.s
```
and inspecting the produced output 


Note: I hope that `middle-end` was the correct place to report this, and I'm
sorry if it isn't.

[Bug c++/92641] VLA type finalized at the beginging of the statement rather at the point of use

2019-11-23 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92641

--- Comment #2 from sagebar at web dot de ---
(In reply to Andrew Pinski from comment #1)
> The big question comes, where should the VLA type be finalized, at the use
> or at the beginning of the statement.
> 
> Statement expressions create a new statement so you are seeing that.
> 
> I don't know the correct answer.  Since VLA types are not part of the C++
> standard, what GCC does currently might be considered the correct answer
> (and most likely could not be implemented different either).


That may be so, however I find it extremely disconcerting that it is possible
to have the contents of a compile-time dead branch be able to affect the
generated assembly in ways that can cause some very real side-effects (function
calls) at runtime.

When I write a macro like `#define ifelse(c, tt, ff) ((c) ? (tt) : (ff))`, then
I really _have_ to be able to rely on the fact that whatever happens, and
whatever it is passed, _only_ 1 of `tt` or `ff` get evaluated at runtime, no
matter what happens between me invoking g++, and eventually running the
produced binary.

To answer the question as to when finalization of the type should happen: the
naive (and probably most comprehensible) answer would be at the end of the dead
?-branch, though I can see how that might be difficult since that branch
doesn't have its own scope.

I sadly don't know enough of how gcc in particular generates assembly, however
I do know how a generic compiler works, so one solution might be to compile `0
? vla-expr : other-expr' as `jmp 1f; vla-expr; jmp 2f; 1: other-expr; 2:` and
use peephole optimization to transform this into `other-expr;`

[Bug c/93087] New: Bogus `-Wsuggest-attribute=cold` on function already marked as `__attribute__((cold))`

2019-12-28 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93087

Bug ID: 93087
   Summary: Bogus `-Wsuggest-attribute=cold` on function already
marked as `__attribute__((cold))`
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

Created attachment 47555
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47555&action=edit
Issue demonstration

Like the title implies, `-Wsuggest-attribute=cold` is emit for functions that
were already given the `__attribute__((cold))` annotation
The attached file demonstrates the issue, and should be compiled as:
```
gcc -c -O* attached-file.c
```
Where `*` can be any one of `` (empty), `1-3` (though not `0`), `g`, `s`,
`fast`
Note that the issue doesn't arise when no `-O*` flag is given at all (or when
`-O0` is given)

[Bug target/93985] New: Sub-optimal assembly for %st(0) constant loading with SSE enabled (x86_64)

2020-03-01 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93985

Bug ID: 93985
   Summary: Sub-optimal assembly for %st(0) constant loading with
SSE enabled (x86_64)
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

Created attachment 47939
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47939&action=edit
Inefficient code generation, similar working cases & work-around

With gcc for x86_64, where SSE is enabled by default, some situations exist
where legacy (fpu) math instructions (and their constraints) still have to be
used.
x86 offets a hand full of instructions to load specific floating point
constants more efficiently (including `1.0`).
As such, it would stand to reason to implement a function `atan()` as:
```c
double atan(double x) {
double result;
__asm__("fpatan"
: "=t" (result)
: "0" (1.0)
, "u" (x)
: "st(1)");
return result;
}
```

This code works perfectly on i386, where it compiles to:
```asm
fldl4(%esp)   # push(x)
fld1  # push(1.0)
fpatan
ret
```

However, on x86_64 it is compiled as:
```asm
movsd   .LC0(%rip), %xmm1
movsd   %xmm1, -8(%rsp)
fldl-8(%rsp)  # push(1.0)
movsd   %xmm0, -8(%rsp)
fldl-8(%rsp)  # push(x)
fxch%st(1)# { x, 1.0 } -> { 1.0, x }
fpatan
fstpl   -8(%rsp)
movsd   -8(%rsp), %xmm0
ret
...
.LC0:
.long   0 # SSE constant: 1.0
.long   1072693248# ...
```

When the optimal code would look like:
```asm
movsd   %xmm0, -8(%rsp)
fldl-8(%rsp)  # push(x)
fld1  # push(1.0)
fpatan
fstpl   -8(%rsp)
movsd   -8(%rsp), %xmm0
ret
```

Still though, it appears that GCC _is_ aware of the fld1 instruction for
encoding inline assembly operands, even when SSE is enabled (s.a.
`atan_reverse()` within the attached file).
So it would stand to reason that this is either a problem with how GCC weights
different encoding schemes, or a problem with how GCC decides if certain
encoding schemes are even possible at all (which seems quite likely, especially
considering that the x86_64 version contains an fxch-instruction which also
wouldn't be necessary if GCC had encoded the `1.0` _after_ pushing `x`
(ignoring the fact that `1.0` can be pushed using `fld1`))

NOTE: The attached file should be compiled as `gcc -O3 -S attached-file.c`

[Bug libstdc++/91655] New: Use of `__in` and `__out` as argument names in c++ headers

2019-09-04 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91655

Bug ID: 91655
   Summary: Use of `__in` and `__out` as argument names in c++
headers
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

After building libstdc++ for a custom toolchain that tries to form a hybrid of
both linux/gnu system headers, as well as headers normally only found on MSVC
(in this case namely: ), I've noticed a problem when it comes to some of
the names used for paramters taken/used by functions exposed in headers created
by libstdc++

Example:
In
[`bits/basic_string.tcc`](https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00771_source.html),
a function is defined `[...] operator>>(basic_istream<_CharT, _Traits>& __in,
[...])`
As plainly visible, this function takes (and uses) an argument named `__in`.
This causes a collision with a macro defined by MSVC's
[``](https://github.com/dotnet/corert/blob/master/src/Native/inc/unix/sal.h)
header, which is also used by headers such as ``.

I bring up this minor compatibility problem not because it posed too much
problems for me (for my purposes, I simply created a
[patch](https://github.com/GrieferAtWork/KOSmk4/blob/master/kos/misc/patches/libstdc%2B%2B-9.1.0.patch)
file to fix all of those argument names), but because the fix would be so
simple that resolving it could possibly take less time than reading this bug
report.

Of course you are still free to mark this as wont-fix and I would fully
understand the decision to not provide for such compatibility with a
proprietary Windows header.

[Bug libstdc++/91655] Use of `__in` and `__out` as argument names in c++ headers

2019-09-04 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91655

--- Comment #2 from sagebar at web dot de ---
Of course. I understand, am sorry to have bothered you, and totally agree that
those macros are extremely bad (but sadly are being used by programs that I'm
trying to provide compatibility for).
Have a great day, and thanks for the quick reply

[Bug tree-optimization/90710] New: Bogus Wmaybe-uninitialized caused by __builtin_expect when compiled with -Og

2019-06-02 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90710

Bug ID: 90710
   Summary: Bogus Wmaybe-uninitialized caused by __builtin_expect
when compiled with -Og
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

Created attachment 46442
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46442&action=edit
Copy of the code already contained in the description

Use of `__builtin_expect()` within `testFunction()` below causes a warning to
be falsely emit when compiled as `gcc -Og -Wall test.c':
```
test.c: In function 'testfunction':
test.c:22:3: warning: 'value' may be used uninitialized in this function
[-Wmaybe-uninitialized]
   22 |   printf("My if() causes -Wmaybe-uninitialized for my use of `value':
%d\n",value);
  |  
^~~~
/
```


Code (`test.c`):
```
#include 

/* A simple store-value-in-pointer-or-return-error function */
static __inline__ __attribute__((__always_inline__))
unsigned int getValueIfNotZero(unsigned int value, unsigned int *result) {
if (value == 0)
goto err;
*result = value;
return 1;
err:
return 0;
}

__attribute__((__noinline__)) void
testFunction(void) {
volatile unsigned int x = 1;
unsigned int value;
int was_ok = getValueIfNotZero(x, &value);
if (was_ok)
printf("My if() compiles fine: %d\n",value);
if (__builtin_expect(was_ok, 1))
printf("My if() causes -Wmaybe-uninitialized for my use of
`value': %d\n",value);
}
```

This problem seems to be related to the `-Og` flag, as I was unable to
reproduce it with `-O[0-4]`

I can personally confirm this warning being emit the same way with:
- i686-pc-cygwin-gcc.exe  (gcc version 6.4.0)
- i686-elf-gcc.exe(gcc version 9.1.0)
I can only assume that this also affects all versions between these two
My host is a windows 10 machine and I'm using cygwin to run GCC

[Bug tree-optimization/90710] Bogus Wmaybe-uninitialized caused by __builtin_expect when compiled with -Og

2019-06-02 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90710

--- Comment #2 from sagebar at web dot de ---
(In reply to Jeffrey A. Law from comment #1)
> We focus most of our effort on avoiding false positives with -O2
> optimization levels.  As you lower the optimization level (-Og) you will
> almost certainly run into these kinds of issues.
> 
> Elimination of false positive uninitialized warnings is highly dependent
> upon what we call "jump threading".  The purpose of jump threading is to
> realize that certain paths through the CFG are not possible and to use block
> copying to isolate and remove those paths.  At lower optimization levels the
> compiler does not aggressively thread jumps and thus can leave unexecutable
> paths in the CFG which leads to the false positive warning.
> 
> The use of builtin_expect can have these effects too as it impacts the cost
> analysis done during jump threading to determine the cost/benefit of block
> copying  to isolate the path.
> 
> 
> So confirmed, but not likely something we'll fix in the near future.

Thanks for taking the time to explain the what-s and why-s. Dealing with a
long-time -O3-compiled codebase (always having optimizations at max prevents
nasty surprises later), I was originally trying to use -Og to improve the
quality of .debug_info for gdb (I read somewhere that that -Og's supposed to be
used for), but for anyone else that has the same Problem and finds this, I
managed to get it to work well enough by simply not passing any -O* flags for
the time being.

[Bug tree-optimization/90994] New: Bogus Wmaybe-uninitialized with fnon-call-exceptions

2019-06-25 Thread sagebar at web dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90994

Bug ID: 90994
   Summary: Bogus Wmaybe-uninitialized with fnon-call-exceptions
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

Created attachment 46517
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46517&action=edit
Minimal code that triggers the problem

Using a branch-dependent return value in an assembly block with at least 5
line-line or `;` characters, where one of the branches gets triggered by some
non-call-exception will result in values conditionally returned by only one of
the paths to be considered uninitialized.

This behavior seems to be _extremely_ specific, relying on any different
factors having to come together to actually trigger the problem. (The attached
file is a minimal code example that triggers this)

To proove to yourself just how inconsistent this problem appears to be, try
moving around the `asm`, or copying it after the second call to `readbyte` (or
even just deleting one of its empty lines), and you will see that the warning
will vanish.
The provided configuration seems to be the only one for which the problem can
be reproduced.

The problem surfaces with `-O[1-4]` and `-O`, however doesn't with `-Og` or no
`-O*` flag at all
Removing `-fnon-call-exceptions` and adding an external function call or a
conditional `throw`-statement within the `try`-block also seems to prevent the
problem.

Also note that the problem still happens when the assignment of `*presult` is
moved after the `try`-block within `readbyte`, so-long as the read from
`*(unsigned char volatile *)1234` stays inside the `try`-block.

Compile the attached file with: `g++ -O2 -Wall -fnon-call-exceptions -c
bogus.cc`

I can personally confirm this problem for:
 - i686-elf-g++(Version 9.1.0)
 - i686-pc-cygwin-g++  (Version 6.4.0)
 - i686-w64-mingw32-g++(Version 7.4.0)
 - x86_64-pc-cygwin-g++(Version 7.4.0)
 - x86_64-w64-mingw32-g++  (Version 7.4.0)

[Bug ipa/105682] [12/13 Regression] Both `-Wsuggest-attribute=pure` and `-Wsuggest-attribute=const` on same function since r12-5177-g494bdadf28d0fb35

2022-09-05 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105682

--- Comment #8 from sagebar at web dot de ---
(In reply to Jan Hubicka from comment #6)
> I think the conlcusion here is correct.  callee has pure attribute and that
> means that it has no side effects except for reading global memory. So
> whatever volatile assembly does has to satisfy this.
> 
> Now since assembly is not declared as reading memory, GCC concludes that the
> function has no side effects and does not read global memory and this can be
> uprgraded to const.

This assumes that reading memory is the only thing inline assembly can do to
access (part of) the global state. But consider the following example where the
ARM FPU control word is read:

```
#include  // HINT: this is arm assembly
//#define _FPU_GETCW(cw) __asm__ __volatile__("vmrs %0, fpscr" : "=r" (cw))
//#define _FPU_SETCW(cw) __asm__ __volatile__("vmsr fpscr, %0" : : "r" (cw))

__attribute__((pure))
fpu_control_t getcw() {
fpu_control_t result;
_FPU_GETCW(result);
return result;
}

int main() {
fpu_control_t before, after;
before = getcw();
_FPU_SETCW(0x1234);
after = getcw()
printf("oldcw: %d\n", before);
printf("newcw: %d\n", after);
}
```

If you're saying that a `__asm__ __volatile__` that doesn't access memory
should be considered as `const`, then gcc should be allowed to remove the first
`getcw()` and simply assign the same value to `before` and `after` (since a
`const` function's return value only depends on its arguments, meaning it calls
can be removed and re-ordered however gcc pleases).

I think you can see how that would be a problem in the above.

However: I would understand gcc doing this if `_FPU_GETCW` was implemented
using `__asm__` instead of `__asm__ __volatile__`.

(If I'm misunderstanding how `pure` is meant to work, please correct me. But as
far as I understand it, the above is a correct usage examle)

[Bug c/105676] New: Bogus `-Wsuggest-attribute=pure` on function marked `__attribute__((const))`

2022-05-20 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105676

Bug ID: 105676
   Summary: Bogus `-Wsuggest-attribute=pure` on function marked
`__attribute__((const))`
   Product: gcc
   Version: 12.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

When compiling with `-Wsuggest-attribute=pure`, gcc warns about missing
`__attribute__((pure))` on functions declared as `__attribute__((const))`.

It is common knowledge that any function marked as `__attribute__((const))`
also implicitly has the behavior of a function marked as
`__attribute__((pure))` (const implies pure).

Therefor, it stands to reason that such a warning is bogus (also: earlier
version of gcc didn't emit a warning in this case; know: gcc-9 already
supported these warnings, but didn't emit `-Wsuggest-attribute=pure` on a
`__attribute__((const))` function).

Example (`gcc -Wsuggest-attribute=pure -c -O2 input.c`):

```
__attribute__((const))
extern int do_expensive_calculation(void);

__attribute__((const))
int getval(void) {
static int cache = -1;
if (cache == -1)
cache = do_expensive_calculation();
return cache;
}
```

>test.c: In function 'getval':
>test.c:5:5: warning: function might be candidate for attribute 'pure' 
>>[-Wsuggest-attribute=pure]
>5 | int getval(void) {
>  | ^~

When trying to declare as both pure+const:
>test.c:5:1: warning: ignoring attribute 'const' because it conflicts with 
>attribute 'pure' [-Wattributes]
>5 | int getval(void) {
>  | ^~~


 Explaination of why using `__attribute__((const))` is valid here 

I see why gcc might think that `getval()` is *only* `pure`, but there is
nothing wrong with the `__attribute__((const))` annotation since we don't "read
global memory" (emphasis on the "global"), and thus don't depend on the global
state (also: what counts as "global" vs. "non-global" isn't something that can
be quantified. - It depends on the application and how memory is used).

As such, the use of `__attribute__((const))` is very much valid (and gcc might
even consider suggesting `__attribute__((const))` instead of
`__attribute__((pure))`, since because `cache` is scoped-static, it not being
used outside of `getval()` can actually be proven, though that isn't what this
bug report is about...). However, so-long as it believes that the function is
pure, there is no reason to ever emit a about that fact so-long as `getval()`
remains annotated as `__attribute__((const))`.

 End of Explaination 

[Bug c/105682] New: Both `-Wsuggest-attribute=pure` and `-Wsuggest-attribute=const` on same function

2022-05-21 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105682

Bug ID: 105682
   Summary: Both `-Wsuggest-attribute=pure` and
`-Wsuggest-attribute=const` on same function
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

The following example causes both a `-Wsuggest-attribute=pure` and
`-Wsuggest-attribute=const` warning for the same function. Additionally, in
this example, only `-Wsuggest-attribute=pure` would be correct (the
`-Wsuggest-attribute=const` is completely bogus):

Compile with `gcc -c -O2 -Wsuggest-attribute=const -Wsuggest-attribute=pure
input.c`:

```
__attribute__((pure))
int callee(int x) {
unsigned int a;
__asm__ __volatile__("");
__asm__ __volatile__("" : "=X" (a));
x &= 1;
if (a & 2)
__asm__ __volatile__("" : "=m" (x));
return x & 4;
}

int caller(int x) {
return callee(x);
}
```

Output (gcc-12.1.0):
>input.c: In function 'caller':
>input.c:12:5: warning: function might be candidate for attribute 'pure' 
>[-Wsuggest-attribute=pure]
>   12 | int caller(int x) {
>  | ^~
>input.c:12:5: warning: function might be candidate for attribute 'const' 
>[-Wsuggest-attribute=const]

Output (gcc-11.2.0; expected behavior):
>input.c: In function 'caller':
>input.c:12:5: warning: function might be candidate for attribute 'pure' 
>[-Wsuggest-attribute=pure]
>   12 | int caller(int x) {
>  | ^~


=== After adding `__attribute__((pure))` to `caller` ===

```
__attribute__((pure))
int caller(int x) {
return callee(x);
}
```

gcc-12.1.0 (bogus warning: `caller()` has no right to be const; it calls a pure
function, and that function even contains inline assembly):
>infile.c: In function 'caller':
>infile.c:13:5: warning: function might be candidate for attribute 'const' 
>[-Wsuggest-attribute=const]
>   13 | int caller(int x) {
>  | ^~

gcc-11.2.0 (expected behavior):
> (No warnings)

===

NOTES:
- Not only does gcc suggest to add both pure & const to the same function, the
later wouldn't even make any sense in this scenario (though suggesting `pure`
is correct).
- The strange-looking body of `callee()` is required to reproduce the bug. -
Trying to further simplify it tends to make the warning go away, suggesting a
problem with some kind of heuristic.
- I know I also just reported
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105676, but that one is about a
bogus `-Wsuggest-attribute=pure` warning, while this one is about a bogus
`-Wsuggest-attribute=const` warning. The two bugs may be related, but simply
suppressing `-Wsuggest-attribute=pure` on const-functions wouldn't be enough to
fix the bug addressed in this report.

[Bug c/105684] New: Bogus `-Warray-bounds` in partially allocated struct

2022-05-21 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105684

Bug ID: 105684
   Summary: Bogus `-Warray-bounds` in partially allocated struct
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

Accessing the fields of a partially allocated struct results in
`-Warray-bounds`, even when all accessed fields lie within the allocated
portion of the struct (a fact that can be proven to be known to gcc by asking
it for `__builtin_object_size()`)

Example (compile with `gcc -c infile.c -O2 -Warray-bounds -S -o -`):

```
struct obj {
unsigned long long kind;
union {
struct {
unsigned long long a;
} data0;
struct {
unsigned long long a;
unsigned long long b;
} data1;
};
};

extern __attribute__((alloc_size(1))) void *my_malloc(unsigned long);
#define offsetafter(s, m) (__builtin_offsetof(s, m) + sizeof(((s *)0)->m))

struct obj *create_object_kind_0(void) {
struct obj *result;
result = (struct obj *)my_malloc(offsetafter(struct obj, data0));
__asm__ __volatile__("# Object size is: %p0" : : "X"
(__builtin_object_size(result, 0)));
result->kind= 0;
result->data0.a = 1;
return result;
}
```

Real-world use-case & rationale: the idea is that access to `data1` vs. `data0`
is governed by the value of `kind` (`obj` is a "typed variant"), and by
allocating only the relevant portion of the object, we can save memory, and
create an environment where buggy code that wrongfully accesses (e.g.) certain
fields of `data1` of a `kind=0` object might cause the program to crash (rather
than remain unnoticed as would be the case when simply using `sizeof(struct
obj)` as allocation size).

Expected behavior: no warnings should be generated

== Actual behavior (Truncated) ===
>[stderr]infile.c: In function 'create_object_kind_0':
>[stderr]infile.c:22:15: warning: array subscript 'struct obj[0]' is partly 
>outside array bounds of 'unsigned char[16]' [-Warray-bounds]
>[stderr]   21 | result->kind= 0;
>[stderr]  |   ^~
>[stderr]infile.c:20:32: note: object of size 16 allocated by 'my_malloc'
>[stderr]   19 | result = (struct obj *)my_malloc(offsetafter(struct 
>obj, data0));
>[stderr]  |
>^
>[stderr]infile.c:23:15: warning: array subscript 'struct obj[0]' is partly 
>outside array bounds of 'unsigned char[16]' [-Warray-bounds]
>[stderr]   22 | result->data0.a = 1;
>[stderr]  |   ^~
>[stderr]infile.c:20:32: note: object of size 16 allocated by 'my_malloc'
>[stderr]   19 | result = (struct obj *)my_malloc(offsetafter(struct 
>obj, data0));
>[stderr]  |
>^
>[stdout][...]
>[stdout]/  22 "infile.c" 1
>[stdout]# Object size is: 16
>[stdout]/  0 "" 2
>[stdout]/NO_APP
>[stdout]movl$0, (%eax)
>[stdout]movl$0, 4(%eax)
>[stdout]movl$1, 8(%eax)
>[stdout]movl$0, 12(%eax)
>[stdout]leave
>[stdout]ret
>[stdout][...]

As can be seen by `# Object size is: 16` (and repeated in warning messages),
gcc knows that the allocated size of the object is 16 bytes, and as can be seen
by the offsets used by the `movl` instructions, this limit is never exceeded.

Judging by what the warnings state (and confirmed by replacing
`offsetafter(struct obj, data0)` with `sizeof(struct obj)`), the
`-Warray-bounds` warning will always be generated for any accessed field
(irregardless of that field's offset) so-long as `__builtin_object_size(result,
0) < sizeof(struct obj)`.

I am uncertain about the intended semantics of `-Warray-bounds`, and
technically speaking, the warning is stating the truth: "'struct obj[0]' is
partly outside array bounds" (emphasis on the "partly"). However, as it stands
right now, warning about this situation is less than useful (a warning might
arguably be useful when passing `result` -- or a pointer to one of its members
-- to some other function, but even in that situation a warning would probably
be a false positive). So in my opinion, at `-Warray-bounds[=1]`, a warning
should only be generated exactly in those cases where an out-of-bounds access
*actually* happens (*possible* out-of-bounds warnings may appear at
`-Warray-bounds=2`, but defini

[Bug ipa/105685] New: Still Bogus `-Wsuggest-attribute=cold` on function already marked as `__attribute__((cold))`

2022-05-21 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105685

Bug ID: 105685
   Summary: Still Bogus `-Wsuggest-attribute=cold` on function
already marked as `__attribute__((cold))`
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: ipa
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
CC: marxin at gcc dot gnu.org
  Target Milestone: ---

I would re-open https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93087, but I don't
think I can so a new bug report it is... - Anyways: while my test-case from
back then remains fixed, the same problem still happens for the following code:

Run (`gcc -c -O2 -Wsuggest-attribute=cold infile.c`)
```
extern void external_fun(char *, char const *, int);

__attribute__((cold)) char *my_cold_fun(int x) {
static char b[42];
external_fun(b, "Without me, the warning disappears?", x);
return b;
}

__attribute__((cold)) char *my_other_cold_fun(int x) {
return my_cold_fun(x);
}
```

 Output 
>infile.c: In function 'my_other_cold_fun':
>infile.c:9:29: warning: function might be candidate for attribute 'cold' 
>[-Wsuggest-attribute=cold]
>9 | __attribute__((cold)) char *my_other_cold_fun(int x) {
>  | ^


 Output (Expected) 
>

[Bug c/105689] New: Bogus `-Wstringop-overflow=` after accessing field, then containing struct (wrong "region size")

2022-05-22 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105689

Bug ID: 105689
   Summary: Bogus `-Wstringop-overflow=` after accessing field,
then containing struct (wrong "region size")
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

The following code wrongly produces a warning `[-Wstringop-overflow=`:

Compile (using `gcc -c -O2 infile.c`)

```
struct subobject {
int field1;
int field2;
};

struct myobject {
struct subobject sub;
};

extern void access_1(int *a);
extern __attribute__((access(read_write, 1))) void access_2(struct subobject
*);

void myfunc(struct myobject *me) {
// { void *p __attribute__((unused)) = &me->sub; }
access_1(&me->sub.field1);
access_2(&me->sub);
}
```

=== Output (gcc-12) ===
>infile.c: In function 'myfunc':
>infile.c:16:9: warning: 'access_2' accessing 8 bytes in a region of size 4 
>[-Wstringop-overflow=]
>   16 | access_2(&me->sub);
>  | ^~
>infile.c:11:52: note: in a call to function 'access_2' declared with attribute 
>'access (read_write, 1)'
>   11 | extern __attribute__((access(read_write, 1))) void access_2(struct 
> subobject *);
>  |^~~~

=== Output (expected) ===
>


=== Notes ===

- By uncommenting the line `{ void *p __attribute__((unused)) = &me->sub; }`,
the warning goes away, even though that line literally does nothing. (see
Theory below)
- I was able to observe this bug in gcc-12.1.0 and gcc-11.2.0


=== Theory ===

It seems that this has got something to do with some internal, hidden attribute
(relating to the "region size") attached to some field-expression the first
time that field is accessed, only that when accessing `me->sub.field1` (where
`offsetof(field1) == 0`) before `me->sub`, that "region size" attribute
wrongfully also gets attached to `me->sub`. Then, when an access to `me->sub`
actually happens, gcc seems to think that the "region size" of `me->sub` as a
whole matches the size of the previously accessed field (`me->sub.field1`).

This seems further compounded by the fact that this only happens when `field1`
is the first field of `subobject` (i.e. has offset 0). If we insert another
field `int field0;` before it, the warning also disappears (so something in
gcc's logic appears to make it think that `region_size_of()
== region_size_of()`)

[Bug tree-optimization/105684] Bogus `-Warray-bounds` in partially allocated struct

2022-05-23 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105684

--- Comment #3 from sagebar at web dot de ---
>The issue is that 'result->data0.a' is (*result).data0.a, and so to GCC you are
>accessing an object of type 'obj' for which there isn't enough allocated space.

Technically true, and yes: not dereferencing `result` while it's still a
`struct obj` makes the warning go away:
```
-   result->kind= 0;
-   result->data0.a = 1;
+   *(unsigned long long *)((char *)result + __builtin_offsetof(struct obj,
kind)) = 0;
+   *(unsigned long long *)((char *)result + __builtin_offsetof(struct obj,
data0.a)) = 1;
```

But that's like saying `int x = obj->field;` is the same as `int x = ({
typeof(*obj) c = *obj; c.field; })` (i.e. accessing 1 field is like accessing
_all_ fields) -- They're just not the same: accessing a single field simply
doesn't cause the rest of the containing struct to also be loaded (if there's
some weird arch where it does ???, fine; but then this should be an
arch-specific warning).



>A workaround might be to declare 'obj' as
>
>struct obj {
>   unsigned long long kind;
>   unsigned long long data[];
>};
>
>if in your case all data is really uniform 'unsigned long long'.  There's
>no way to union several different typed flexarrays though.

It would for the demo-code, but that's not the context where I encountered this
problem in the real world. For reference, the following is the "typed
variant"-style struct which lead me to create this bug report:
https://github.com/GrieferAtWork/KOSmk4/blob/master/kos/src/kernel/moddbx/include/ctype.h#L193

I simply crafted the minimal viable code that still causes the warning for the
sake of making this bug report.

[Bug debug/111080] New: restrict qualifier leaks debug info

2023-08-20 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111080

Bug ID: 111080
   Summary: restrict qualifier leaks debug info
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: debug
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

The the following code example, debug information is retained for `struct foo`
even though that structure doesn't end up used:

Compile as `gcc -g -S -o - in.c | grep field_number`

```
struct foo {
int field_number_1;
int field_number_2;
int field_number_3;
int field_number_4;
int field_number_5;
};

typedef int fun_t(struct foo *restrict);

int main() {
return 0;
}
```

Output:
gcc -g -S -o - test.c | grep field_number
.ascii "field_number_1\0"
.ascii "field_number_2\0"
.ascii "field_number_3\0"
.ascii "field_number_4\0"
.ascii "field_number_5\0"



When removing the `restrict` qualifier in the parameter of `funptr_t`, debug
information is not included in the produced assembly (as one would expect).

Here is a list of different declarations and where `struct foo` is leaked in
gcc 12.1.0:

> typedef int fun_t(struct foo *restrict);// Leak
> typedef int fun_t(struct foo *);// No leak
> typedef int (*fun_t)(struct foo *restrict); // Leak
> typedef int (*fun_t)(struct foo *); // No leak
> extern int fun_t(struct foo *restrict); // No leak
> extern int fun_t(struct foo *); // No leak
> extern int (*fun_t)(struct foo *restrict);  // Leak
> extern int (*fun_t)(struct foo *);  // No leak
> static int fun_t(struct foo *restrict); // No leak
> static int fun_t(struct foo *); // No leak
> static int (*fun_t)(struct foo *restrict);  // Leak
> static int (*fun_t)(struct foo *);  // Leak (even w/o restrict!)
> int fun_t(struct foo *restrict);// No leak
> int fun_t(struct foo *);// No leak
> int (*fun_t)(struct foo *restrict); // Leak
> int (*fun_t)(struct foo *); // Leak (even w/o restrict!)

There is no difference when using `__restrict` or `__restrict__` instead.

[Bug debug/111080] [11/12/13/14 Regression] restrict qualifier causes extra debug info to happen

2023-08-20 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111080

--- Comment #2 from sagebar at web dot de ---
@Andrew Pinski

Of course: yes. I did make a mistake there, but only for this case:

> int (*fun_t)(struct foo *); // Leak (even w/o restrict!)

asm:
...
.globl  fun_t
.section.bss
.align 4
.type   fun_t, @object
.size   fun_t, 4
fun_t:
.zero   4
...



In the other case:

> static int (*fun_t)(struct foo *);  // Leak (even w/o restrict!)

asm:
...
# No data-symbol is generated for `fun_t`
...



Gcc actually doesn't generate a .bss-symbol for the static variable (since it's
unused), but it still generates debug inforation for `struct foo`. So I guess
strike `int (*fun_t)(struct foo *);` from the list, but keep `static int
(*fun_t)(struct foo *);` which still leaks

[Bug driver/110607] New: Makefile.in build broken build-tools when CXXFLAGS is defined

2023-07-09 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110607

Bug ID: 110607
   Summary: Makefile.in build broken build-tools when CXXFLAGS is
defined
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: driver
  Assignee: unassigned at gcc dot gnu.org
  Reporter: sagebar at web dot de
  Target Milestone: ---

This part in the main makefile:

> 177 # These variables must be set on the make command line for directories
> 178 # built for the build system to override those in BASE_FLAGS_TO_PASS.
> 179 EXTRA_BUILD_FLAGS = \
> 180 CFLAGS="$(CFLAGS_FOR_BUILD)" \
> 181 LDFLAGS="$(LDFLAGS_FOR_BUILD)"

Should instead be:

> 177 # These variables must be set on the make command line for directories
> 178 # built for the build system to override those in BASE_FLAGS_TO_PASS.
> 179 EXTRA_BUILD_FLAGS = \
> 180 CFLAGS="$(CFLAGS_FOR_BUILD)" \
> 181 CXXFLAGS="$(CXXFLAGS_FOR_BUILD)" \
> 182 LDFLAGS="$(LDFLAGS_FOR_BUILD)"

Since some components of the build system are compiled as c++, if one wants to
define custom CXX-flags in cross-compilation situations, these flags then also
get used when building build-tools (which causes breakage)

[Bug bootstrap/110607] Makefile.in builds broken build-tools when CXXFLAGS is defined

2023-07-09 Thread sagebar at web dot de via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110607

--- Comment #2 from sagebar at web dot de ---
@Andrew Pinski

Sorry if this is a known bug. I simply checked the current gcc master
(https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=Makefile.tpl;h=d0fe7e2fb778b3c3fa2cc8742e06cf1f78fdc5f2;hb=HEAD#l183),
which is still affected. I was not aware that a fix was already pending but not
yet merged.