[Bug c/30527] New: Use of input/output operands in __asm__ templates not fully documented

2007-01-21 Thread davmac at davmac dot org
It seems that I can use "%k0" (rather than just "%0") in an asm template to
force the (register) operand to "long" size (i.e. a value in %al referenced as
%k0 comes out as %eax in the generated assembly).

This doesn't seem to be documented anywhere. I presume there may be other such
character prefixes which have similar functions.


-- 
   Summary: Use of input/output operands in __asm__ templates not
fully documented
   Product: gcc
   Version: 4.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: davmac at davmac dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30527



[Bug c/30527] Use of input/output operands in __asm__ templates not fully documented

2007-01-21 Thread davmac at davmac dot org


--- Comment #1 from davmac at davmac dot org  2007-01-21 14:15 ---
I should add that I'm prepared to send a patch for the documentation if someone
will tell me what the operands are and what they do.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30527



[Bug inline-asm/30527] Use of input/output operands in __asm__ templates not fully documented

2007-01-21 Thread davmac at davmac dot org


--- Comment #3 from davmac at davmac dot org  2007-01-22 04:17 ---
You've got to be kidding - these things are genuinely useful. What sort of
abuse are you worried about?

In any case, I'd like to know if that is the general consensus among
maintainers. I'm not going to write documentation and submit a patch if it's
not going to be accepted.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30527



[Bug driver/41179] Documentation for "-fno-toplevel-reorder" is confusing (and wrong)

2009-10-28 Thread davmac at davmac dot org


--- Comment #1 from davmac at davmac dot org  2009-10-28 10:41 ---
Urgh. By "paragraph above" I am of course referring to the same paragraph.
However, the basic point - that "enabled" seems to be used with two different
meanings - stands.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41179



[Bug c/65892] gcc fails to implement N685 aliasing of union members

2018-04-30 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892

--- Comment #44 from Davin McCall  ---
> Well, perhaps not, but this is the language specification.

The "one special guarantee" clause appears in the section describing union
member access via the "." or "->" operators, implying that it only applies to
the access of union members via the union. As has been pointed out by others,
the guarantee is surely not meant to trump all other rules regarding access, so
this is a reasonable interpretation (since otherwise, it is totally unclear
when it does apply and what exactly "it is permitted" even means).

Note that without that clause, type punning structs via a union would
essentially be impossible (since layout is implementation defined or
unspecified). The "common initial sequence" requirement is the only part of the
standard which requires that structs with similar members have them layed out
in the same order and alignment. Since this only matters for type punning, it
again makes sense that this would be specified in the one section which
actually allows for type punning (even if only in a non-normative footnote) -
that is, union member access via a union. It's clear why it is needed for this,
but to extend that to any access of union members (including not via the union)
seems like a stretch. If that was intended, why isn't it specified in 6.5?

The only thing that suggests an alternative interpretation to what I've
described above is the requirement that the declaration of the completed type
of the union be visible, which is redundant if the access must be via the union
type. However, interpreting this to mean that the "special guarantee" applies
globally is far more problematic than assuming that the requirement is just
redundant.

[Bug c/65892] gcc fails to implement N685 aliasing of union members

2018-04-30 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892

--- Comment #52 from Davin McCall  ---
(In reply to James Kuyper Jr. from comment #48)
> > The "one special guarantee" clause appears in the section describing union
> > member access via the "." or "->" operators, implying that it only applies
> > to the access of union members via the union. ...
> 
> I find nothing objectionable about that statement - it is indeed impossible
> to create code which relies upon the special guarantee in 6.5.2.3p6 without
> accessing the union members via the '.' or '->' operators. However, I
> believe that you mean something more restricted than what you're actually
> saying, because the code given in the original bug report does in fact
> access the union members via '.' operator, in the expressions &u.s1 and
> &u.s2, to create a situation where, as I understand it, that special
> guarantee is fully applicable.
> Could you expand on your description of what you think is required, to make
> it clear why it doesn't apply in this case?

It isn't clear that "&u.s1" for example actually accesses either "u" or its
member "s1", and I would argue that it doesn't for either. I read it how (if I
understand correctly) GCC has up until now interpreted it: the "special
guarantee" is for expressions directly involving member access via the union.
Once you take the address of the member, and later dereference it via "*", you
are dealing with a different operator and the guarantee doesn't apply.

I'll admit that this is still making some assumptions, but it's an
interpretation that is far more at peace with the rest of the standard.

(In reply to Andrew Haley from comment #45)
> (In reply to Davin McCall from comment #44)
> > The "one special guarantee" clause appears in the section describing union
> > member access via the "." or "->" operators, implying that it only applies
> > to the access of union members via the union.
> 
> I don't believe that's what is intended, or that you can make such a
> conclusion based on the section in which the rule appears.  It applies
> to other accesses too, as is (somewhat) made clear by the rationale in
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n685.htm:

It certainly may not be what is intended by N685, but I think it's normally
reasonable to conclude that a statement in a particular section of a document
applies to that section and not more universally than that; in this case, the
"universal" interpretation flatly contradicts the strict aliasing rule and any
other rule which would otherwise disallow access, which seems extremely
problematic to me.

In general it appears the committee have asserted that the "universal"
interpretation (which since N685 requires visibility of the union declaration
to be effective) is the correct one, but my argument is that the actual text of
the standard strongly implies something different, and that the interpretation
being pushed instead turns another portion of the standard text into nonsense.
It's extremely problematic in my view that a more reasonable reading is
considered incorrect and that this can only be known with external knowledge
outside the text of the specification itself.

Never the less, I take your point.

[Bug c/65892] gcc fails to implement N685 aliasing of union members

2018-04-30 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892

--- Comment #54 from Davin McCall  ---
(In reply to James Kuyper Jr. from comment #53)
> [...] However, because those
> pointers are passed to f(), which does dereference them, f() does accesses
> those members, and it does so via the use of the '.' operator in the calling
> routine. Therefore, you need, at a minimum, to modify "accesses via" to
> "accesses directly via", in order to convey your intended meaning.

I thought it was clear that I was referring to access via the union. That is
certainly what I did mean.

> 
> I don't see anything in the standard's wording of 6.5.2.3p6 to justify
> restricting what it says to direct accesses - it says "it is permitted to
> inspect", without specifying restrictions on how the inspection may be
> performed.

As I have said, it is in a section regarding access and in a paragraph
discussing "use of unions". While I understand what you are saying, I don't
feel my own interpretation is really that difficult to fathom, and I'm not the
only one to take it. See http://archive.is/PnW28 (DR 257).

> The words "anywhere that a declaration of the completed type of the union
> is visible." would become pointless with your interpretation.

Yes, as I already said.

[Bug c/65892] gcc fails to implement N685 aliasing of union members

2018-05-01 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892

--- Comment #56 from Davin McCall  ---
(In reply to James Kuyper Jr. from comment #55)
> The problem is, you're using a statement that the access must occur via a
> union, with the implication that the code in question does not access the
> member through the union.

If "via a union" allows that at some point that the address of a union member
was taken and that pointer is then dereferenced, and type punning via a union
is allowed (as is implied by another footnote in the same section), then:

1) all type-based alias analysis is effectively impossible
2) the "special guarantee" clause is completely redundant, and the requirement
for visibility of the union declaration doubly so.

The real problem is that "it is permitted to inspect" doesn't say how one
should perform an "inspection" nor what the result should be. You want it to
mean "access (read) the structure member in the normal way and have its value
match that of the corresponding structure member from the common initial
sequence of the active member". But the "special guarantee" grants a
permission, which is most easily read as not doing anything other than
specifying that a certain action (reading a struct member) doesn't have
undefined behaviour in certain circumstances.

It's not even actually explicated that the value read should match that of the
corresponding common-initial-sequence member of the struct object that is the
active member of the union object in question; in thinking that it should be,
we're already making the assumption that this clause is intended to permit a
certain case of type-punning. But, as I noted above, if type-punning is
generally allowed, and if accessing via the union "immediately" has the same 
semantics as taking the address of the union member and accessing via the
resulting pointer - then the clause isn't necessary anyway, except to mandate
that the common-initial-sequence layout is identical between distinct structs
which are punned in this way, and in that case what is the point of requiring
that the union declaration be visible? (Unless you want to argue that the point
is to mandate the common initial sequence layout is necessarily identical only
if the union declaration is visible; however, since the layout necessarily
applies to the rest of the program also, why should it matter where the union
declaration is?).

So for your interpretation I believe you need that either:

1) type punning via a union is not normally permissible, despite the footnote
claiming it is, and
2) a lot of production code is broken.

or

1) type punning via a union is permissible and the "special guarantee" clause
serves only to enforce common layout of structs, and the union declaration
amendment is not sensible, and
2) TBAA is impossible and most current compilers are broken.

or

1) type punning via a union is permissible, but the semantics of accessing a
member of the union "immediately" do differ to those of taking the address of
the member and later dereferencing it, despite the fact that the text does not
explicate this, and
2) the "special guarantee" clause changes the semantics of "indirect" union
member access to match those of "direct" member access, in specified cases,
despite that the present wording only dances around this topic without ever
touching it.

> The standard explicitly says, referring to the same example mentioned in DR
> 257, that the second code fragment is not valid, but only "because the union
> type is not visible within function f", implying that it would be valid if
> the declaration of the union type were moved so that it would be visible
> inside f(). If it were so moved, it would be essentially equivalent to the
> code which was the original defect report. While examples are non-normative,
> that example implies that the visibility clause was intended to actually
> serve a purpose (and it seems obvious to me that it actually does so).

I'm not arguing that N685 wasn't intended to do exactly as you suggest, but I'm
not sure the wording pre-amendment really suffered from the problem that N685
supposedly addresses, and I certainly don't agree that the amended wording is
clear in meaning.

[Bug c/65892] gcc fails to implement N685 aliasing of union members

2018-05-01 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892

--- Comment #58 from Davin McCall  ---
(In reply to Andrew Haley from comment #57)
> (In reply to Davin McCall from comment #52)
> > (In reply to Andrew Haley from comment #45)
> > > (In reply to Davin McCall from comment #44)
> > > > The "one special guarantee" clause appears in the section describing 
> > > > union
> > > > member access via the "." or "->" operators, implying that it only 
> > > > applies
> > > > to the access of union members via the union.
> > > 
> > > I don't believe that's what is intended, or that you can make such a
> > > conclusion based on the section in which the rule appears.  It applies
> > > to other accesses too, as is (somewhat) made clear by the rationale in
> > > http://www.open-std.org/jtc1/sc22/wg14/www/docs/n685.htm:
> > 
> > It certainly may not be what is intended by N685, but I think it's normally
> > reasonable to conclude that a statement in a particular section of a
> > document applies to that section and not more universally than that; in this
> > case, the "universal" interpretation flatly contradicts the strict aliasing
> > rule and any other rule which would otherwise disallow access, which seems
> > extremely problematic to me.
> > 
> > In general it appears the committee have asserted that the "universal"
> > interpretation (which since N685 requires visibility of the union
> > declaration to be effective) is the correct one, but my argument
> 
> ... doesn't really matter from a practical point of view, does it?
> That ship has sailed.

Well, if the amendment doesn't make sense, I'd say it matters from a practical
point of view, yes. It can always be amended again.

> > is that the actual text of the standard strongly implies something
> > different, and that the interpretation being pushed instead turns
> > another portion of the standard text into nonsense.
> 
> I don't think that's it really does, but I think we're done.

I've laid it out as best as I can in comment #56, and certainly don't have more
to add.

[Bug c/65892] gcc fails to implement N685 aliasing of union members

2018-05-01 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892

--- Comment #61 from Davin McCall  ---
(In reply to James Kuyper Jr. from comment #59)
> (In reply to Davin McCall from comment #56)
> > (In reply to James Kuyper Jr. from comment #55)
> > > The problem is, you're using a statement that the access must occur via a
> > > union, with the implication that the code in question does not access the
> > > member through the union.
> > 
> > If "via a union" allows that at some point that the address of a union
> > member was taken and that pointer is then dereferenced, and type punning via
> > a union is allowed (as is implied by another footnote in the same section),
> > then:
> 
> Footnote 95 is the only one I can find which allows type punning via a union
> - is that the one you're referring to? Footnote 95 makes absolutely no use
> of the word "via". It says, quite explicitly, "the member used to read the
> contents of a union", and therefore can't apply when not directly using an
> actual member to read it.

Since footnote 95 is a footnote, and therefore non-normative, so actual text
that would limit type punning to only direct union member access would have to
appear in the normative text, but doesn't. In an expression "u.a" where u is a
union object, the result "is an lvalue if" (u) "is an lvalue" (assume for this
example that it is) and also the value is "that of the named member" (a). To
apply the "&" operator to that (as in "&u.a"), then "the result is a pointer to
the object or function designated by its operand". When I then de-reference
that pointer, "the result is an lvalue designating the object", exactly as the
result of the member access operator. When the lvalue is used as per 6.3.2.1 it
is "converted to the value stored in the designated object" which, if it is
referring to a member object, seems to me to be the same as saying that it is
converted to the value "of the named member", as with direct member access.

Since the rest of my points hinged on the idea that is inconsistent to believe
that the clause regarding the common initial sequence applies universally while
type punning requires direct/immediate use of the union, and you disagree with
that tenet, then I don't see a need to go through the other points one by one
and I will let the matter rest unless you would like to discuss it privately
via email (to avoid making even more noise here).

[Bug tree-optimization/86259] [8/9 Regression] min(4, strlen(s)) optimized to strlen(s) with -flto

2018-07-11 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259

Davin McCall  changed:

   What|Removed |Added

 CC||davmac at davmac dot org

--- Comment #19 from Davin McCall  ---
(In reply to rguent...@suse.de from comment #16)
> On Mon, 25 Jun 2018, glisse at gcc dot gnu.org wrote:
> 
> As a general comment I find it disturbing that the user
> is required to write (char *)&s2 + offsetof(S, a) instead
> of plain &s2.a

Even worse, the proposal doesn't mention the provenance of "offsetof" at all.
If the result of offsetof has no provenance even the long form won't work. That
seems like a big oversight to me. Also, code doing something like the following
can't be terribly uncommon:

type struct { int a; int b; } s;
s s_o;
// start with address of contained member:
char *b_cp = &s_o.b;
// subtract its offset:
char *s_o_cp = b_cp - offsetof(s,b);
s * s_o_p = (s *) s_o_cp;
// access the containing object:
s s2 = *s_o_p;

It would only work generally if an offsetof result is given wildcard
provenance.

[Bug tree-optimization/86259] [8/9 Regression] min(4, strlen(s)) optimized to strlen(s) with -flto

2018-07-11 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259

--- Comment #20 from Davin McCall  ---
(In reply to Davin McCall from comment #19)
> [...] If the result of offsetof has no provenance even the long form won't
> work.

"no provenance" meaning "empty provenance", and of course this is not actually
correct; shouldn't have posted before coffee. However, if it had provenance of
the member, that would be problematic. Having provenance of the compound object
(s2') would be ok for Richard Biener's example of ((char *)&s2 + offsetof(S,
a)) but not for my extended example of determining the address of the
containing object using a pointer to a member object and offsetof.

[Bug tree-optimization/86259] [8/9 Regression] min(4, strlen(s)) optimized to strlen(s) with -flto

2018-07-12 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259

--- Comment #21 from Davin McCall  ---
Looking at this further, the proposal actually states, for the address-of
operator:

> When the operand designates an object, the result has the single provenance 
> of the outermost object containing that object.

That's "outermost" object; it implies that taking the address of an
inner/contained object, and manipulating it to point at other parts of the
containing object, should actually be fine (adding an integer offset with empty
provenance should not affect the provenance of the pointer, according to the
proposal). Martin Sebor: doesn't that contradict what you said in comment #8 ?
In any case it seems it should allow the case I was concerned about, i.e
calculating the containing object address from a contained object address.

While we can agree that it is anyway not allowed to advance a pointer past the
end of an array, including an "array" consisting of a single object not
actually declared as an array, surely casting the pointer to an integer type
should get around that problem - but doesn't, in the program below, for which
GCC 8.1 bizarrely generates code that prints "NO" (indicating that it has
determined that len != 7) and then returns 7 (indicating that len == 7).
Clearly this could only be "correct" if there is undefined behaviour - though
it is somewhat bad handling even then - however I cannot see the U.B. in this
program and no warnings are generated (which is at least a QOI issue). Note
that by the provenance proposal the 'sp_ip' variable should have the provenance
of the containing object, 'u', and so when cast to char * should be perfectly
capable of navigating the entire union object:

---8>---
#include 
#include 
#include 
#include 

struct S {
char a[4];
char b[4];
char c[4];
};

union U {
struct S s;
char xx[12];
};

int main()
{
union U u;
u.s = (struct S){0, 0, 0};
char *bp = u.s.b;
uintptr_t sp_ip = (uintptr_t)bp - offsetof(struct S,b);
strcpy(u.xx, "abcdefghijk");
size_t len = strlen((char *)(union U *)sp_ip + 4);
puts(len == 7 ? "YES" : "NO");
return len;
}
---<8---

[Bug tree-optimization/86259] [8/9 Regression] min(4, strlen(s)) optimized to strlen(s) with -flto

2018-07-13 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259

--- Comment #23 from Davin McCall  ---
(In reply to Martin Sebor from comment #22)
> The test cases in this report are variations on this theme. [...]

Ok, except that the one I posted in comment #21 specifically copies the string
into a union member which is long enough to contain it, and while it takes the
address of a subobject from the other union member, it does so while that
member is active, and it casts to uintptr_t before subtracting the offset (so
as to obtain a pointer to the containing object in a way that doesn't involve
advancing a pointer beyond the bounds of the object it points into). It even
casts this back to the union type before casting to (char *) again. At that
stage it either:

- points at the union object itself and its active member, which is a char[12],
or
- points at the union object but not its active member
- points at the union object (and possibly its active member) but dereference
is illegal due to provenance rules.

The 3rd case would be greatly disturbing to myself and, I think, to many
others; it would mean that you cannot meaningfully obtain a pointer to a
containing object from a contained member other than the first one.

The 1st case would mean that GCC is in error in compiling that code, since it
gives the wrong result.

Only the 2nd case avoids both those issues, but only if we allow that strlen on
(part of) a non-char[] object has undefined behaviour even if the relevant
portion of that object contains a suitably-sized char[] as a subobject in the
relevant range. That seems tenuous and certainly not directly supported by the
wording of the current specification, unless I've missed something.

[Bug tree-optimization/86259] [8/9 Regression] min(4, strlen(s)) optimized to strlen(s) with -flto

2018-07-14 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259

--- Comment #27 from Davin McCall  ---
(In reply to Martin Sebor from comment #24)
> The code in example #21 has the same bug:
> [...]

... due to provenance, you are claiming, if I understand correctly. But I don't
see anything in the current language standard that allows or even supports this
reasoning (perhaps I'm missing it). For the other examples you can say that the
result of the pointer arithmetic is not defined (because it is not specified by
6.5.6). But for this case, the pointer was cast to an integer type before any
arithmetic was performed.

> The strlen call is undefined because (char*)sp_ip is known to point just
> past the last element of u.s.b.

It actually points at the first element of u.s.b - we start with &u.s.b,
subtract the offset of that element from the container object (the offset will
be 4), then add 4. I don't think this by itself invalidates what you have said,
though.

>  It wouldn't matter if there happened to be
> a valid string at that address -- there isn't in this case because what's
> there is a char[4] with no terminating NUL.

That is true only if "address" means something more than "pointer value". I can
assert that ((char *)sp_ip + 4) and (u.xx + 4) are equal before the strlen, and
the compiler optimises away the assert. Furthermore, there is definitely a
valid string at u.xx + 4 and therefore at ((char *)&u) + 4. The provenance
rules you're suggesting lead to the conclusion that I can check (via an '=='
comparison) if a pointer refers to a particular object, and find that it does,
but then invoke undefined behaviour when dereferencing it [*]. While there may
be changes in the committee pipeline that would make this the case, in the
language as defined now I don't see how this interpretation can be justified.

[*] or if such a pointer comparison would also be undefined, i could anyway
cast both pointers to an integer type and compare them then.

>  The pointer wasn't derived from
> that address.  The pointer was derived from u.s.b and points to u.s.b +
> sizeof u.s.b, and there can never be anything valid beyond the end of an
> object.

(It points at u.s.b, actually).

> 
> [...]  Just like it's not valid to increment a pointer from
> a[0][1] to a[1][0] and dereference the latter in 'char a[2][2]; it's not
> valid to increment a pointer to one struct member to point to another and
> dereference it.

Again, there was no pointer arithmetic (other than the line containing
'strlen', but that particular case the pointer has the address of the union
object, which has been cast to (char *), and the '+ 4' should be valid then,
surely, by 6.3.2.7 paragraph 7 (ignoring that it requires 'successive
increments' rather than arbitrary addition, or is that supposed to be
significant?).

I believe I understand the point of the provenance rules, but I do not think it
is right to implement provenance as transferring to integers, on-by-default, in
a compiler for the current language specification.

[Bug libstdc++/66145] [5/6/7 Regression] std::ios_base::failure objects thrown from libstdc++.so use old ABI

2016-11-08 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145

Davin McCall  changed:

   What|Removed |Added

 CC||davmac at davmac dot org

--- Comment #27 from Davin McCall  ---
> Another option is to decide which to throw based on an environment variable, 
> so > applications can choose whether they want the types thrown by the 
> library to be > catchable by new code or old code.

Please don't do this. It will mean programs that require wrapper scripts just
to work properly, or problems with old-abi programs launching new-abi programs
and vice-versa, and will undoubtedly cause confusion when programs seem to work
correctly some of the time and not otherwise.

> But we might end up just throwing the new type, and saying old code needs to 
> be > recompiled, or just to catch it as std::exception not 
> std::ios_base::failure.

If you are going to mandate that old code needs to be recompiled (including if
you say that it should catch std::exception, since that requires altering the
code and therefore implies recompilation), I would suggest that you also bump
the soname; this is definitely an ABI break. At that point you can remove the
dual ABI anyway, since you only need to support the new one.

If you do not plan on bumping the soname, but will change the thrown exception
type to the new type, I would suggest that this change be made as soon as is
practically possible to avoid the production of further software being compiled
against the old ABI - which will then need to be recompiled when this change is
made. The less that needs to be recompiled the better, especially since that
was IIUC the reason for the creation of the dual ABI in the first place.

[Bug c/65892] gcc fails to implement N685 aliasing of union members

2016-11-11 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892

Davin McCall  changed:

   What|Removed |Added

 CC||davmac at davmac dot org

--- Comment #25 from Davin McCall  ---
(In reply to Tim Rentsch from comment #21)
>
> Three:  The "one special guarantee" rule is independent of the
> rules for effective types.  This observation is obviously right
> because effective type rules matter only for access to objects.
> The only objects being accessed under the "one special guarantee"
> rule are guaranteed to have compatible types, which is always
> allowed by effective type rules.

However, the two structures are not compatible types; in a union as per the
example at the head of this PR -

union U {
struct t1 { int m; } s1;
struct t2 { int m; } s2;
};

- the types 'struct t1' and 'struct t2' are not compatible. This line:

p2->m = -p2->m;

- is accessing the active union member (s1) via an incompatible type. From
6.5.2.3:

"A postfix expression followed by the -> operator and an identifier designates
a member of a structure or union object. The value is that of the named member
of the object to which the first expression points"

This makes it IMO clear enough that the structure object is being accessed,
since you can't extract the member of an object without the object existing. If
that were not the case, then you could *always* use p2->m to access the 'm'
member of a 'struct t1' object regardless of the existence of a suitable union
declaration, unless you interpret the "special guarantee" just to mean that the
layout of a C.I.S. need only be identical between two structs if those structs
are part of the same union. In that case however there is no reason for
visibility of the union to matter at point of access, since the struct layout
surely cannot be different in different parts of the program (i.e. if two
structs are visible in a union anywhere and this forces common layout of the
C.I.S, then the C.I.S must have the same common layout throughout the program;
it doesn't make sense to require visibility of the union declaration to make
use of the "special guarantee").

> Four:  The "one special guarantee" rule is related to the area of
> "type punning" through unions, but seen by WG14 as a separate
> issue relative to the general topic.  This is evident from the
> committee response in DR 257.

It's problematic though that the committee response doesn't really follow from
the text. You cannot access the member of one structure via a pointer to
another structure with the same layout, as I have shown above, due to the
aliasing rules. If you (or WG14) are claiming that the "special guarantee" is
not directly concerned with aliasing, then the only way you could make use of
the rule is anyway via type punning, and the only way we can do that without
violating aliasing rules is to go via the union object, at which point the
question of union declaration visibility is moot.

> Five:  The footnote added in C99 TC3 about type punning is seen
> by WG14 not as a change but just as a clarifying comment noting
> what behavior was intended all along.  This is evident from the
> text and response in DR 283.  Note that Clark Nelson, the author
> of this DR, is a long-standing member of WG14, and the suggested
> revision given in the text was adopted verbatim for the TC.

While I agree that this is what WG14 seem to believe, I see no normative part
of the text which supports the footnote, and I see some parts which contradict
it (such as 6.7.2.1 "The value of at most one of the members can be stored in a
union object at any time" / 6.5.2.3 "The value is that of the named member of
the object to which the first expression points" - if the value of only one
member can be stored, how can the value of any other member be defined?).

[Bug rtl-optimization/81423] [6/7 Regression] Wrong code at -O2

2017-10-14 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81423

Davin McCall  changed:

   What|Removed |Added

 CC||davmac at davmac dot org

--- Comment #15 from Davin McCall  ---
Apologies if I'm wrong and just making noise but doesn't the test case involve
a left shift of a value greater than the bit width of the left operand and
therefore invoke UB?

  ll = -5597998501375493990LL;

  ll = (5677365550390624949L - ll) - (ull1 > 0);
  //ull3 = (unsigned int)
  //  (2067854353L <<
  //   (((ll + -2129105131L) ^ 10280750144413668236ULL) -
  //10280750143997242009ULL)) >> ((2873442921854271231ULL | ull2)
  //- 12098357307243495419ULL);

  // Above broken down:

  unsigned long long int t1 = ll + -2129105131L;
  unsigned long long int t2 = t1 ^ 10280750144413668236ULL;
  unsigned long long int t3 = t2 - 10280750143997242009ULL;
  // t3 = 9523455470476460042 !!!
  long t4 = 2067854353L << t3;  // UB!!
  unsigned int t5 = (unsigned int)t4;

  unsigned long long int t6 = 2873442921854271231ULL | ull2;
  unsigned long long int t7 = t6 - 12098357307243495419ULL;
  ull3 = t5 >> t7;

Fixed test case would be:

--- begin ---
unsigned long long int ll = 0;
unsigned long long int ull1 = 1ULL;
unsigned long long int ull2 = 12008284144813806346ULL;
unsigned long long int ull3;

void
foo ()
{
  ll = -5597998501375493990LL;

  ll = (5677365550390624949L - ll) - (ull1 > 0);
  ull3 = (unsigned int)
(2067854353L <<
 (((ll + -2129105131L) ^ 10280750144413668236ULL) +
  17089282532945401191ULL)) >> ((2873442921854271231ULL | ull2)
- 12098357307243495419ULL);
}

int
main ()
{
  foo ();
  printf ("%llu expected 3998784)\n", ull3);
  printf ("%llx expected 3d0440)\n", ull3);
  return 0;
}
--- end ---

This still demonstrates the bug.

[Bug target/80569] New: i686: "shrx" instruction generated in 16-bit mode

2017-04-29 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80569

Bug ID: 80569
   Summary: i686: "shrx" instruction generated in 16-bit mode
   Product: gcc
   Version: 6.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davmac at davmac dot org
  Target Milestone: ---

The following code, compiled with -m16 -O2 -c, fails at assembly:

--- begin ---
void load_kernel(void *setup_addr)
{
unsigned int seg = (unsigned int)setup_addr >> 4;
asm("movl %0, %%es" : : "r"(seg));
}
--- end ---

$ gcc -m16 -O2 -c shrxdtestcase.i 
/tmp/ccGS34WK.s: Assembler messages:
/tmp/ccGS34WK.s:11: Error: instruction `shrx' isn't supported in 16-bit mode.

[Bug target/80569] i686: "shrx" instruction generated in 16-bit mode

2017-04-29 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80569

--- Comment #1 from Davin McCall  ---
(Prevents building Qemu).

[Bug c++/80916] New: Spurious "declared 'static' but never defined" warning

2017-05-29 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80916

Bug ID: 80916
   Summary: Spurious "declared 'static' but never defined" warning
   Product: gcc
   Version: 7.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
      Reporter: davmac at davmac dot org
  Target Milestone: ---

The following code (reduced via creduce) gives a warning, when compiled with:
g++ -std=c++11 -Os -Wall -Wno-invalid-offsetof -c dinit-warn.cc

dinit-warn.cc:20:40: warning: 'void b::i< 
>::dispatch(void*) [with  = {anonymous}::l]' declared
'static' but never defined [-Wunused-function]
 template  class i : j { void dispatch(void *); };
^~~~

However, the highlighted function, "dispatch", is not declared 'static' (and
indeed nothing in the code is declared static). Occurs at -Os and -O2, -O3, not
at -O1/-O0.

--- begin ---
class a;
namespace b {
template  class i;
class j {
  friend a;
  virtual void dispatch(void *);
};
}
class a {
  using d = b::j;

public:
  template  using c = b::i;
  void f() {
d *k = nullptr;
k->dispatch(this);
  }
};
namespace b {
template  class i : j { void dispatch(void *); };
}
using g = a;
g h;
namespace {
class l : g::c {};
}
void m() { h.f(); }
--- end ---

[Bug c++/80916] Spurious "declared 'static' but never defined" warning

2017-05-30 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80916

--- Comment #1 from Davin McCall  ---
(Does not actually require -Wno-invalid-offsetof to reproduce; that was just me
copying my command line literally. Problem first appears in GCC 6.1, not in
5.x, still present in 7.1).

[Bug target/81516] New: Wrong code with -m32 -O2 on x86_64-linux-gnu

2017-07-22 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81516

Bug ID: 81516
   Summary: Wrong code with -m32 -O2 on x86_64-linux-gnu
   Product: gcc
   Version: 7.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davmac at davmac dot org
  Target Milestone: ---

Created attachment 41809
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41809&action=edit
reduced test case

Attached file (reduced test case from string-to-double conversion routine in
Firefox 54.0.1) aborts when compiled with:

  gcc -m32 -O2 wrong-code.c

It's fine when compiled with -O1 or without -m32.

[Bug target/81516] Wrong code with -m32 -O2 on x86_64-linux-gnu

2017-07-22 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81516

--- Comment #1 from Davin McCall  ---
(triggers with -march=prescott|haswell, not with -march=i686)

[Bug target/80569] i686: "shrx" instruction generated in 16-bit mode

2017-07-22 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80569

--- Comment #2 from Davin McCall  ---
Still happening in 7.1.

-march=core2 suppresses, generation of the problematic instruction happens with
-march=haswell.

[Bug target/81516] Wrong code with -m32 -O2 on x86_64-linux-gnu

2017-07-22 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81516

--- Comment #4 from Davin McCall  ---
(In reply to Andrew Pinski from comment #3)
> Most likely a dup of bug 323.

I don't think so, unless I'm misunderstanding something. There's no rounding in
the test case, just a store of an int value to a double variable, and
furthermore the result is _completely_ wrong, not just off by a bit.

[Bug target/81516] Wrong code with -m32 -O2 on x86_64-linux-gnu

2017-07-22 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81516

--- Comment #7 from Davin McCall  ---
(In reply to Uroš Bizjak from comment #6)
> 
> Works OK for me with:
> 
> .ident  "GCC: (GNU) 7.1.1 20170718 [gcc-7-branch revision 250314]"

Reported against 7.1.0. It may well be fixed already on the branch/trunk; in
that case I would suggest adding a regression test if it is not otherwise a
known bug and closing as resolved.

[Bug target/80569] i686: "shrx" instruction generated in 16-bit mode

2017-07-23 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80569

--- Comment #4 from Davin McCall  ---
(In reply to Uroš Bizjak from comment #3)
> Can you please test attached patch?

That seems to fix the problem, yes. Thanks.

[Bug target/81516] Wrong code with -m32 -O2 on x86_64-linux-gnu

2017-07-23 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81516

--- Comment #8 from Davin McCall  ---
This problem disappears when I apply the fix for #80706 (as applied to GCC 7
branch). Possibly this is a duplicate of that issue.

[Bug c++/80916] [7/8/9 Regression] Spurious "declared 'static' but never defined" warning

2019-01-07 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80916

--- Comment #6 from Davin McCall  ---
> The wording could be improved, but why do you think the warning is spurious?

I guess I think that the warning is spurious given the current wording? It may
well be legitimate to warn that there is a declaration of a function with
internal linkage but no definition, which may be what triggered this warning
originally (it no longer triggers in my current code base, so I can't easily
verify). But that's not what the warning does say.

If you'd prefer to change the title to reflect that the wording of the warning
doesn't match its cause, I have no issue with that.

[Bug c++/80916] [7/8/9 Regression] Spurious "declared 'static' but never defined" warning

2019-01-08 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80916

--- Comment #8 from Davin McCall  ---
(In reply to ensadc from comment #7)
> Note that the "never defined" part is also misleading: the warning persists
> when `i::dispatch` does have a definition

Yes; and actually, I note that in the original test case I supplied, the
dispatch function doesn't have a definition, but it doesn't have internal
linkage either.

So, I think the warning really is spurious and it's not just a case of it
saying "declared static" where it should say "has internal linkage".

[Bug driver/41179] New: Documentation for "-fno-toplevel-reorder" is confusing (and wrong)

2009-08-27 Thread davmac at davmac dot org
Where it says:

 Enabled at level `-O0'.  When disabled explicitly, it also imply
 `-fno-section-anchors' that is otherwise enabled at `-O0' on some
 targets.

Firstly, "imply" should be "implies".

Secondly, what does "disabling" the option mean ("When disabled explicitly...")
- does it mean using "ftoplevel-reordering" (enabling reordering), in which
case wouldn't it be better to say "When top-level reordering is enabled
explicitly..." or "When -ftoplevel-reordering is used..." and be less ambiguous
(and avoid the double negative)?

Thirdly, "it also imply `-fno-section-anchors' that is otherwise enabled at
`-O0' on some targets" seems to use the opposite interpretation of "enabled"
compared to the paragraph above (unless I'm getting it wrong). What it's trying
to say is that -fno-toplevel-reorder implies -fno-section-anchors which is
otherwise *disabled* on some targets, i.e. some targets otherwise assume
-fsection-anchors).


-- 
   Summary: Documentation for "-fno-toplevel-reorder" is confusing
(and wrong)
   Product: gcc
   Version: 4.4.1
Status: UNCONFIRMED
  Severity: trivial
          Priority: P3
 Component: driver
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: davmac at davmac dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41179



[Bug inline-asm/30527] Use of input/output operands in __asm__ templates not fully documented

2015-07-17 Thread davmac at davmac dot org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30527

--- Comment #4 from Davin McCall  ---
I recently stumbled across section 6.43.2.7 of the manual, which does in fact
document the operand modifiers for (and only for) x86. Modifiers for other
architectures are not documented.


[Bug c/102268] New: Wrong code with aliasing union pointers

2021-09-09 Thread davmac at davmac dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102268

Bug ID: 102268
   Summary: Wrong code with aliasing union pointers
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: davmac at davmac dot org
  Target Milestone: ---

The following code is adapted from an LLVM PR: 
https://bugs.llvm.org/show_bug.cgi?id=34632

The "test" function is called with all three pointers pointing to the same
union object. Note there are only reads from the active union object so this is
not a type-punning issue. I've also changed the original test case to show that
the issue is present even if changing the active union object requires
assignment directly to the corresponding union member, though it's not clear if
this should be necessary.

Runs ok with GCC 9.4; fails with every version since and on trunk.

--- begin ---
struct s1 {unsigned short x;};
struct s2 {unsigned short x;};
union s1s2 { struct s1 v1; struct s2 v2; };

static int read_s1x(struct s1 *p) { return p->x; }
static void write_s2x(struct s2 *p, int v) { p->x=v;}

int test(union s1s2 *p1, union s1s2 *p2, union s1s2 *p3)
{
  if (read_s1x(&p1->v1))
  {
unsigned short temp;

// Active member is v1, so this is fine:
temp = p3->v1.x;
struct s2 t2 = { temp };

// now change active member to v2, and write to it:
p3->v2 = t2;
write_s2x(&p2->v2,1234);
temp = p3->v2.x;

// now change active member back to v1:
struct s1 t1 = { temp };
p3->v1 = t1;
  }
  return read_s1x(&p1->v1);
}
int test2(int x)
{
  union s1s2 q[2];
  struct s1 t1 =  { 4321 };
  q->v1 = t1; // ensure active member is v1
  return test(q,q+x,q+x);
}

int main(void)
{
  if(test2(0) == 4321) __builtin_abort();
}
--- end ---

[Bug c/102268] Wrong code with aliasing union pointers

2021-09-09 Thread davmac at davmac dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102268

--- Comment #1 from Davin McCall  ---
(fails with -O2)

[Bug c/102268] Wrong code with aliasing union pointers

2021-09-10 Thread davmac at davmac dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102268

--- Comment #5 from Davin McCall  ---
Hi Richard,
I think you marked as a duplicate of the wrong bug. It is indeed a duplicate of
82224 - sorry, I didn't realise that there was already a bug filed, also this
test case is "fixed" by version 8.1 and then regresses again in 10.1 (but I
assume that is coincidental rather than the underlying issue was fixed).

[Bug middle-end/95189] [9/10 Regression] memcmp being wrongly stripped like strcmp

2021-01-01 Thread davmac at davmac dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189

Davin McCall  changed:

   What|Removed |Added

 CC||davmac at davmac dot org

--- Comment #28 from Davin McCall  ---
Created attachment 49866
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49866&action=edit
My backport of fix to 9.3.0

For the benefit of anyone that needs it, I've attached my own attempt to
backport the fix directly to the 9.3.0 release (maybe it will apply against the
current 9.4 branch, not sure, haven't tried). It seems to fix the issue but I'm
not a GCC developer.

[Bug middle-end/109967] [10/11/12/13/14 Regression] Wrong code at -O2 on x86_64-linux-gnu

2023-06-05 Thread davmac at davmac dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109967

Davin McCall  changed:

   What|Removed |Added

 CC||davmac at davmac dot org

--- Comment #3 from Davin McCall  ---
-fdisable-tree-cunroll avoids it.

This is the take of someone who is new to poking GCC internals, so take this
with a grain of salt, but:

It looks like cunroll duplicates (partially unrolls, I suppose) the inner loop,
meaning that `g' is live in two disjoint ranges, with a CLOBBER between them.

Then later passes (fre5, but disabling it doesn't seem to help) recognise that
&g and &g are the same in both ranges and so use a single temporary for both.
This confuses cfgexpand (as Andrew Pinski notes) because the memory dereference
of the temporary isn't seen as an access of g (in
add_scope_conflicts()/add_scope_conflicts_1()/visit_conflict()). 

I don't understand the IR semantics well enough to know the right fix - perhaps
cunroll should be removing the clobber (does a clobber affect storage lifetime
or only value?), or perhaps cfgexpand should be more conservative when it sees
a memory access.