[Bug c++/91000] noexcept in constexpr context with std=c++11 and std=c++14

2019-06-26 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91000

--- Comment #4 from Federico Kircheis  ---
> As I explained in PR 87603 comment 6, and as the patch
> https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00466.html says, the old
> behaviour triggers unwanted instantiations and so causes valid code to not
> compile.

Ok, I did not really understood that part of the discussion, I thought it was
an issue in the code.
The comment states explicitly that the code fails when compiling with c++2a,
says nothing about c++11 and c++14 (of course I've could have tested it, my
fault).

> The old behaviour was not consistently implemented by other compilers so was
> never portable anyway.

Actually the old behaviour is implemented by GCC<9, MSVC and ICC, clang was the
notable exception on my list.
Testing with compiler explorer, every compiler that understands c++14 except
from gcc9, clang, elcc and zapcc can compile the sample.
So it seems to me that the majority got it right.

There are bugs where every compiler behaves differently, so it does not seem
like a big portability issue.

> The C++ committee decided that the old behaviour was
> not desirable, and removed it.

They removed it from c++17, not from the previous standards, and it has been
more by accident than by design (at least that's what I understood, also stated
in https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00466.html).

> How many reasons do you need?

Sorry, but I could not find *the* reason why the behaviour has been changed for
the previous standards.
The discussion starts with the c++17 change, then shows a failing sample in
c++2a, and then it's fixed retroactively for every standard.

Since now I've understood that PR 87603 comment 6 is also valid for previous
standards I suppose that that's why you meant that the old behaviour is not
consistent with the standards.
(For the record: it seems that no compiler can compile the code in PR 87603
comment 6 with c++14, so the behaviour is consistent with GCC<9).

[Bug c++/91000] noexcept in constexpr context with std=c++11 and std=c++14

2019-06-26 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91000

--- Comment #2 from Federico Kircheis  ---
(In reply to Jonathan Wakely from comment #1)
> This would be more appropriate on the gcc-help mailing list, as you're
> asking a question not reporting a bug.
> 
> The behaviour is as intended, for all -std versions. The standard was
> changed to remove this feature and no other compilers implemented it anyway.

Well I'm actually reporting a regression, since g++ is not c++11 and c++14
standard compliant and it's behaviour changed from previous versions.

I've discovered through https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87603 that
it was not by accident (I guess with dialect are meant the different c++
versions), but there is no motivation why the regression was introduced by
design.

[Bug c++/91000] New: noexcept in constexpr context with std=c++11 and std=c++14

2019-06-25 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91000

Bug ID: 91000
   Summary: noexcept in constexpr context with std=c++11 and
std=c++14
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

I've used following snippet of code for testing if inside a constepxr context:


template constexpr void test_constexpr_helper(T&&) {}
constexpr bool test_fun(bool expr) {
return noexcept(test_constexpr_helper(expr));
}
static_assert(test_fun(true), "inside static_assert it's always constexpr");
int main(){}



But since g++9 (I've tested with different version on compiler explorer, with
-std=c++14 and -std=c++11) this piece of code does not compile anymore.

>From what I've seen from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87603,
the new behaviour is not accidental, at least for -std=c++17.

But since I'm compiling with -std=c++11 and -std=c++14, the code should behave
as it did with g++-8, fro reading the comments further, this breaking change
has not been an accident.


So:
 * Does g++-9 provide a mechanism/extension that also works with c++11 and
c++14? If not, is it possible to restore the "old" behaviour?
 * Is there an extension that works for c++17 too?

Thanks

Federico

[Bug c++/90881] -Wunused-value false positive in SFINAE context

2019-06-22 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90881

--- Comment #9 from Federico Kircheis  ---
Hi,

did you consider my last comment (Comment 6)?

I find it unfortunate that gcc will not warn anymore about unused variables in
some circumstances.

Maybe my example was not a good one, but I guess that a warning in
`decltype(0,0)` would be useful if one intended `decltype(0.0)`.

[Bug c++/90881] -Wunused-value false positive in SFINAE context

2019-06-14 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90881

--- Comment #6 from Federico Kircheis  ---
> With my patch, we wouldn't warn on this second testcase.  But clang++
> doesn't warn, either.

Yes, I just wanted to point out that giving warning in unevaluated contexts has
some benefits too.
I believe gcc is doing a better job than clang or msvc.

I actually thought about this bug, and would like to rephrase it.
It's not a false positive, it's an usability bug.



It's not problematic that gcc gives a warning, the text is
problematic/misleading.

It says "left operand of comma operator has no effect", and as I showed this is
wrong.

It should say "left operand of comma operator is not used" or something in that
direction, since the warning should be about unused variables
(`-Wunused-value`), and it would be correct.


As a programmer I can see more easily what gcc is trying to say, and I would be
less tempted to remove the unused variable because gcc did not told me it was
useless.


Now you might think, that this does not help me as programmer at all, since I
would like to write warning-free code, and I might be tempted to remove the
unused variable also in this situation.


Therefore, just add the hint (as actually documented), to cast the variable to
void!
Exactly as on would normally do for other unused variables.
I did not think about it, because I payed too much attention at the error text,
and not the cause of the warning.

This sample does compile, works as expected, and does not generate any warning.


#include 

template  struct status : std::false_type{};

template  struct status :
std::true_type {};

struct s1{int member;};
struct s2{int _member;};

int main(){
static_assert(status::value, "has member");
static_assert(!status::value, "has no member");
}


What do you think?

[Bug c++/90881] -Wunused-value false positive in SFINAE context

2019-06-14 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90881

--- Comment #4 from Federico Kircheis  ---
(In reply to Jonathan Wakely from comment #1)
> Confirmed. We shouldn't give that warning in unevaluated contexts (decltype,
> sizeof, etc.) because unevaluated operands have no effects at all, with or
> without the comma operator.

The compiler flag is about unused variables, not statements without effects.

I guess it would be nice for


int main(){
decltype(short(), int()) a = 1;
return a;
}


to have a warning that the left operand is unused (as of today), since here 
SFINAE does not kick in:

--
: In function 'int main()':
:2:21: warning: left operand of comma operator has no effect
[-Wunused-value]
2 | decltype(short(), int()) a = 1;
  | ^
--

But maybe there are not enough use-cases to be worth to diagnostic it.

[Bug c++/90880] compile error instead of SFINAE with non-public member variables

2019-06-13 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90880

--- Comment #3 from Federico Kircheis  ---
(In reply to Jonathan Wakely from comment #2)
> (In reply to Federico Kircheis from comment #1)
> > After researching a little bit more, I've convinced myself that
> > `status::value` should be false, as `decltype` has no special rules for
> > accessing private data, thus clang is correct.
> 
> Agreed. And G++ should accept it.


Thank you.

Sorry if linking to external bug trackers in comments is bad practice, but I
did not saw any rule about it.
Since it could be interesting for those having this issue, here is the bug
report for MSVC: 

https://developercommunity.visualstudio.com/content/problem/607019/incorrect-decltype-on-non-public-member-variables.html

[Bug c++/90880] compile error instead of SFINAE with non-public member variables

2019-06-13 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90880

--- Comment #1 from Federico Kircheis  ---
After researching a little bit more, I've convinced myself that
`status::value` should be false, as `decltype` has no special rules for
accessing private data, thus clang is correct.

If someone could confirm this, I could try to make a bug report to the msvc
team

[Bug c++/90881] New: -Wunused-value false positive with

2019-06-13 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90881

Bug ID: 90881
   Summary: -Wunused-value false positive with
   Product: gcc
   Version: 9.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

Hello,

consider


#include 

template  struct status : std::false_type{};

template  struct status :
std::true_type {};

struct s1{int member;};
struct s2{int _member;};

int main(){
static_assert(status::value, "has member");
static_assert(!status::value, "has no member");
}


When compiling with `-Wall` (or `-Wunused-value`), g++ generates following
warning:


--
bug.cpp: In instantiation of ‘struct status’:
bug.cpp:11:26:   required from here
bug.cpp:5:58: warning: left operand of comma operator has no effect
[-Wunused-value]
 template  struct status :
std::true_type {};
 ~^~~~
bug.cpp:5:58: warning: left operand of comma operator has no effect
[-Wunused-value]
--


The warning is incorrect, as removing the left operand changes the behaviour of
the program, thus it has effect:


#include 

template  struct status : std::false_type{};

template  struct status : std::true_type {};
// ! removed left operand

struct s1{int member;};
struct s2{int _member;};

int main(){
static_assert(status::value, "has member");
static_assert(!status::value, "has no member");
}


Does not compile:

--
bug.cpp: In function ‘int main()’:
bug.cpp:12:16: error: static assertion failed: has no member
  static_assert(!status::value, "has no member");
--

because `status` does not detect anymore if the member-variable `member` is
present or not.

[Bug c++/90880] New: compile error instead of SFINAE with non-public member variables

2019-06-13 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90880

Bug ID: 90880
   Summary: compile error instead of SFINAE with non-public member
variables
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

Hello, 

I searched for bugs related to SFINAE, and I do not think that this one has
already reported:


#include 
#include 

template  struct status : std::false_type{};

template  struct status :
std::true_type {};

struct s1{int member;};
struct s2{int _member;};
class c1{int member;};
class c2{int _member;};
int main(){
static_assert(status::value, "has member");
static_assert(!status::value, "has no member");
(void) status::value;
//static_assert(status::value, "has member");
static_assert(!status::value, "has no member");
}
-

This code compiles fine with msvc and clang, but with g++ it triggers following
compiler error:

--
bug.cpp: In substitution of ‘template struct status [with T = c1]’:  
bug.cpp:15:19:   required from here
bug.cpp:6:58: error: ‘int c1::member’ is private within this context
 template  struct status :
std::true_type {};
 ~^~~~
bug.cpp:10:14: note: declared private here
 class c1{int member;};
  ^~
bug.cpp: In instantiation of ‘struct status’:
bug.cpp:15:19:   required from here
bug.cpp:6:58: error: ‘int c1::member’ is private within this context
 template  struct status :
std::true_type {};
 ~^~~~
bug.cpp:10:14: note: declared private here
 class c1{int member;};
  ^~
bug.cpp:6:58: error: ‘int c1::member’ is private within this context
 template  struct status :
std::true_type {};
 ~^~~~
bug.cpp:10:14: note: declared private here
 class c1{int member;};
--

While the error message could be correct (more on that later), the issue is
that because of SFINAE, this should never be compile-error (just like for `s2`
and `c2`).


I've commented `static_assert(status::value, "has member");` out, because
clang++ compiles `status::value` to false, while msvc to true.

I'm not 100% sure which of the compiler is correct, but `status::value`
should definitively compile.

[Bug c++/90029] optimizing local exceptions, or are they an observable side effect

2019-04-09 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90029

--- Comment #2 from Federico Kircheis  ---
Thank you for your answer, I need to learn better how to search for related
bugs.

The bugs you linked do surely answer my question, but they do not cover exactly
the same requests.

1) optimize dead call to `std::terminate`.


2) remove typeinfo information for types that can never escape the local scope 

The other tickets are more generic, in the general case it will not be possible
to remove the typeinfo by just looking at a function.
In my example `foo` is defined, thrown and captured inside `bar_ex*`, which is
not the common case when using exception (normally the error class is defined
globally or in a namespace)


Should I maybe open a feature request with those two missed optimization?
They are related to optimizing exceptions, but not completely dependent (I
think at least).

[Bug c++/90029] New: optimizing local exceptions, or are they an observable side effect

2019-04-09 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90029

Bug ID: 90029
   Summary: optimizing local exceptions, or are they an observable
side effect
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

Hello, 

this is partly a question, and partly a feature request

Consider following functions


int bar_ex_noexcept(int i) noexcept {
struct foo{};
try {
if(i<0){
throw foo{};
}
return i;
}catch(foo){
return -1;
}
}

int bar_ex(int i) {
struct foo{};
try {
if(i<0){
throw foo{};
}
return i;
}catch(foo){
return -1;
}
}

int bar_ret(int i) noexcept {
if(i<0){
return -1;
}
return i;
}

int bar_goto(int i) noexcept {
if(i<0){
goto ex;
}
return i;
ex: return -1;
}


All this functions, unless I overlooked something, do exactly the same with
different control structure (goto, exception, early return): return the given
value i positive or 0, -1 if less than 0.
gcc is smart, and all functions, except those that use as implementation detail
an exception, generate the same assembly with (testing with `-O3`).
`bar_ex_noexcept` also has a call to `std::terminate`, even if it will never
get executed (example here: https://godbolt.org/z/XVtgXG).
Since `foo` is defined locally to `bar_ex`/`bar_ex_noexcept`, I expected that
gcc would have been able to optimize the throw and catch clause completely
(calls to `__cxa_allocate_exception` and `__cxa_throw`), but it's not the case.
Also the conditional call to `std::terminate` in `bar_ex_noexcept` surprised
me, since the only thrown exception is always caught and ignored.

Therefore my question: are exceptions an observable behavior, and thus the
compiler can't optimize them completely away, or is simply gcc "not smart
enough" to do those optimization.

If they are not observable, the feature request would be to
 * optimize local exceptions
 * thus remove typeinfo information for types that can never escape the local
scope (since if the exceptions are optimized, those information are not used by
anyone)
 * remove dead calls to `std::terminate`

[Bug c++/89718] _Pragma GCC diagnostic ignored inside macro

2019-03-14 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89718

--- Comment #4 from Federico Kircheis  ---
(In reply to Jakub Jelinek from comment #2)
> The tokens on which you expect the warning come from an area of the code
> that is not in between the pragmas, so the gcc behavior looks good to me
> here.  Maybe clang doesn't do macro origin tracking here?

I do not think I understand what you mean, could you elaborate please?

(In reply to Andrew Pinski from comment #3)
> I think this is a dup of bug 55578.

Yes, seems to be a duplicate (retested with `error` instead of `ignored`),
sorry for not noticing it.

[Bug c++/89718] _Pragma GCC diagnostic ignored inside macro

2019-03-14 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89718

--- Comment #1 from Federico Kircheis  ---
I've missed a line while copy-pasting the test program, there was a missing ')'
at the end:


#define DIAGNOSTIC_HELPER0(x) #x
#define DIAGNOSTIC_HELPER1(kind, y) DIAGNOSTIC_HELPER0(GCC diagnostic kind #y)

#define DIAGNOSTIC(kind, warning, statements)\
_Pragma("GCC diagnostic push")\
_Pragma(DIAGNOSTIC_HELPER1(kind, warning))\
statements \
_Pragma("GCC diagnostic pop")

DIAGNOSTIC(error, -Wuninitialized,
int foo(int a, int b){return a;}
int main(){
int i;
return foo(i, i);
}
)


[Bug c++/89718] New: _Pragma GCC diagnostic ignored inside macro

2019-03-14 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89718

Bug ID: 89718
   Summary: _Pragma GCC diagnostic ignored inside macro
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

Given following piece of code


#define DIAGNOSTIC_HELPER0(x) #x
#define DIAGNOSTIC_HELPER1(kind, y) DIAGNOSTIC_HELPER0(GCC diagnostic kind #y)

#define DIAGNOSTIC(kind, warning, statements)\
_Pragma("GCC diagnostic push")\
_Pragma(DIAGNOSTIC_HELPER1(kind, warning))\
statements \
_Pragma("GCC diagnostic pop")

DIAGNOSTIC(error, -Wuninitialized,
int foo(int a, int b){return a;}
int main(){
int i;
return foo(i, i);
}


I would expect it not to compile when executing `g++ main.cpp`, but it compiles
without any issues.

With clang++ (expected behavior):

--
clang++ main.cpp
main.cpp:15:16: error: variable 'i' is uninitialized when used here
[-Werror,-Wuninitialized]
return foo(i, i);
   ^
main.cpp:7:5: note: expanded from macro 'DIAGNOSTIC'
statements \
^~
main.cpp:14:5: note: variable 'i' is declared here
int i;
^
1 error generated.
--

When manually "expanding" the macros to


_Pragma("GCC diagnostic push")\
_Pragma(DIAGNOSTIC_HELPER1(error, -Wuninitialized))
int foo(int a, int b){return a;}
int main(){
int i;
return foo(i, i);
}
_Pragma("GCC diagnostic pop")


The behavior is the expected:

--
g++ main.cpp
main.cpp: In function ‘int main()’:
main.cpp:26:15: error: ‘i’ is used uninitialized in this function
[-Werror=uninitialized]
 return foo(i, i);
~~~^~
cc1plus: some warnings being treated as errors
--

and no file is generated.


Notice that the same behavior (__pragma not taken into account) is reproducible
when using "ignored" or "warning" instead of "error".

Some other considerations/information:
msvc works like clang (with other pragmas obviously).
With the provided code, also (tested on https://godbolt.org/) elcc (any
version), djggp4.9.4, and zapcc, all behaves like clang (pragma is taken into
account).

While testing different compilers, I discovered that this seems to be a
"partial" regression, since gcc 4.9.4.
Here the compiler triggers a warning (and not error) when using "GCC diagnostic
error", but does not ignore the warning when using "GCC diagnostic ignored".

It is a regression compared to gcc 4.4.7, since it triggers an error (when
using "GCC diagnostic error", I'm unsure why the warnings are generated):

--
:16: warning: expected [error|warning|ignored] after '#pragma GCC
diagnostic'
:16: warning: expected [error|warning|ignored] after '#pragma GCC
diagnostic'
: In function 'int main()':
:10: error: 'i' is used uninitialized in this function
Compiler returned: 1
--

My local gcc version:
--
g++ (Debian 8.3.0-2) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--

but the behavior is consistent since gcc5 on different operating systems.

Notice that this is not a duplicate of
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69543, since 


# define ERR_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic error \"-Wuninitialized\"")\
_Pragma ("GCC diagnostic error \"-Wmaybe-uninitialized\"")
# define ERR_END \
_Pragma ("GCC diagnostic pop")

int main (int yylval, char**)
{
  char *yyvsp;
  ERR_BEGIN
  *++yyvsp = yylval;
  ERR_END
}


triggers a compile error:

--
g++ /tmp/main.cpp
/tmp/main.cpp: In function ‘int main(int, char**)’:
/tmp/main.cpp:12:12: error: ‘yyvsp’ is used uninitialized in this function
[-Werror=uninitialized]
   *++yyvsp = yylval;
   ~^~~~
cc1plus: some warnings being treated as errors
--

[Bug libgcc/89417] New: helgrind detects a lock order violation inside std::scoped_lock

2019-02-20 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89417

Bug ID: 89417
   Summary: helgrind detects a lock order violation inside
std::scoped_lock
   Product: gcc
   Version: 8.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libgcc
  Assignee: unassigned at gcc dot gnu.org
  Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

Created attachment 45776
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45776=edit
helgrind log output

Hello,

Im unsure if this is a bug or feature request, depending on who is "wrong"
(g++/valgrind)

I'm using g++ (Debian 8.2.0-14) 8.2.0, and the program is compiled with
following flags: "-std=c++17 -lpthread"

Consider following snippet of code:


int main(){
std::mutex m1;
std::mutex m2;
int data1{};
int data2{};
auto f1 = std::async(std::launch::async, [&](){
std::scoped_lock sl{m1, m2};
++data1;
++data2;
return data1;
});
auto f2 = std::async(std::launch::async, [&](){
std::scoped_lock sl{m2, m1};
++data1;
++data2;
return data2;
});
return f1.get() + f2.get(); // result should be 3
}


helgrind (valgrind-3.14.0) reports that the lock order is violated: error
message attached)


it prints exactly the same error for


int main(){
std::mutex m1;
std::mutex m2;
int data1{};
int data2{};
auto f1 = std::async(std::launch::async, [&](){
std::lock_guard lg1{m1};std::lock_guard lg2{m2};
++data1;
++data2;
return data1;
});
auto f2 = std::async(std::launch::async, [&](){
std::lock_guard lg1{m1};std::lock_guard lg2{m2};
++data1;
++data2;
return data2;
});
return f1.get() + f2.get(); // result should be 3
}


In case helgrind is correct, it seems that there are some issues behind
std::scoped_lock, since it was explicitly designed for solving issues with lock
order.

In case helgrind (and possibly for the same reason other tools) is wrong, this
is would be a feature request.


A possible fix (or improvement) would be for `std::scoped_lock` to sort its
arguments by address (since std::mutex are not copyable or movable, and thus
their address should remain constant):


auto make_lock(std::mutex& m1_, std::mutex& m2_) {
const auto mless = std::less{};
return std::scoped_lock{*std::min(_, _, mless), *std::max(_,
_, mless)}; 
}

int main(){
std::mutex m1;
std::mutex m2;
int data1{};
int data2{};
auto f1 = std::async(std::launch::async, [&](){
auto sl = make_lock(m1,m2);
++data1;
++data2;
return data1;
});
auto f2 = std::async(std::launch::async, [&](){
auto sl = make_lock(m2,m1);
++data1;
++data2;
return data2;
});
return f1.get() + f2.get(); // result should be 3
}


in this case, helgrind does not generate any warning.
I do not know the internal algorithm of `std::scoped_lock`, so it might be
completely wrong, but sorting by address might also avoid possible live-lock
issues.

[Bug c++/87760] New: Unable to delete overloads of std::memset on arm

2018-10-25 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87760

Bug ID: 87760
   Summary: Unable to delete overloads of std::memset on arm
   Product: gcc
   Version: 6.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

Hello,

I know this is technically speaking undefined behavior (not allowed to change
things inside namespace std), and thus not a bug but more a feature request.
Since all version of gcc I've tested (x86 and x64), clang, icc and msvc accept
following code, I think it makes sense to open this bug because it would be
nice for gcc to be more consistent, since it's just gcc on arm rejecting it.


#include 

namespace std{
void* memset(void*, std::size_t count, int ch) = delete;
}

struct foo{ // POD
int a;
int* b;
char c;
};

int main() {
foo b[10];
std::memset(, 0, sizeof b);
std::memset(, 0u, sizeof b);
}


This code on arm64 fails to compile with following error message:


:4:7: error: deleted definition of 'void* std::memset(void*,
std::size_t, int)'

 void* memset(void*, std::size_t count, int ch) = delete;

   ^~

: note: previous declaration of 'void* std::memset(void*, int, long
unsigned int)'

Compiler returned: 1


As already mentioned, this hack works with different compilers and helps to
avoid common errors like forgetting the right order of parameter of memset, ie
it helps at compile time to spot errors where someone writes `std::memset(,
sizeof b, 0);` instead of `std::memset(, 0, sizeof b);`.

Since I do not have locally an arm version, I tested it on compiler explorer:
https://godbolt.org/z/aTX9FZ


Also note that removing the overload from the global namespace is not an issue
on arm64, ie


#include 

void* memset(void*, std::size_t count, int ch) = delete;

struct foo{ // POD
int a;
int* b;
char c;
};

int main() {
foo b[10];
memset(, 0, sizeof b);
memset(, 0u, sizeof b);
}


compiles fine (except on arm non x64 because the overload is ambiguous, but
AFAIK there is nothing we can do about it).

[Bug c++/82736] -Wl not wrapping all functions call

2017-10-26 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82736

--- Comment #4 from Federico Kircheis  ---
Thank you very much for your feedback.

With "-static" or "-static-libstdc++" i got the expected (at least for me)
result.

I guess that I'll need to register to https://sourceware.org/bugzilla/ to ask
if the behavior is correct, since it would be nice if it would work without
linking statically.

[Bug c++/82736] New: -Wl not wrapping all functions call

2017-10-26 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82736

Bug ID: 82736
   Summary: -Wl not wrapping all functions call
   Product: gcc
   Version: 7.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

AFAIK, std::chrono::system_clock::now(); uses clock_gettime internally.

For various reasons (unit testing), I would like to "mock" time calls, so I
tried to use the -Wl option, but it does not seem to work as expected.

Given the following program:

#include 
#include 
#include 

extern "C" {
#if USE_WRAP
int __wrap_clock_gettime(clockid_t, struct timespec *tp) {
#else
int clock_gettime(clockid_t, struct timespec *tp) {
#endif
*tp = {};
tp->tv_sec = 123;
return 0;
}
}

int main(){
clockid_t clk_id{};
struct timespec tp;
auto res = clock_gettime(clk_id, );

assert(res == 0);
assert(tp.tv_sec == 123);

auto now = std::chrono::system_clock::now();
auto now_t = std::chrono::system_clock::to_time_t(now);
assert(now_t == 123);
}
---

When executing "g++ -std=c++11 main.cpp && ./a.out" the program runs and
returns 0, while when executing "g++ -std=c++11 -DUSE_WRAP
"-Wl,-wrap=clock_gettime" main.cpp && ./a.out" the program crashes with "int
main(): Assertion `now_c == 123' failed.".


AFAIK the version compiled without the macro USE_WRAP is UB , even if it works.
Therefore I would prefer to use the "-Wl" compiler option.

The statement "assert(tp.tv_sec == 123);" assures that the "mocked" version of
the function is called. This happens in both cases.


I've also tried to implement wrapping functions for time() and gettimeofday()
(with and without the wrap option), but it did not made any difference.

I've also tried to compile those functions in a shared library, but it did not
made a difference either.

I would like to find a robust way for wrapping all OS functions call for
querying what time it is and eventually call the original function through
dlsym(RTLD_NEXT, funcname)).
Simply overwriting them seems to work, but is AFAIK UB.
Using "-Wl" works too, but only if using the C functions, not when using
std::chrono.

If it may be somehow relevant, clang++ (version 3.8.1-24) behaves exactly the
same way.

[Bug c++/79791] New: -Werror=write-strings ignored with -Wpedantic

2017-03-01 Thread federico.kircheis at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79791

Bug ID: 79791
   Summary: -Werror=write-strings ignored with -Wpedantic
   Product: gcc
   Version: 6.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

Given following program:

int main(){
  char* str = "hello world!";
  (void)str;
}

When compiling with "-Werror=write-strings", the expected output would be a
compiler error. This is what happens when compiling with:
"g++ -Werror=write-strings main.cpp"
The output on the command line contains (an no executable is produced):
"error: ISO C++ forbids converting a string constant to ‘char*’
[-Werror=write-strings]"

The problem is that apparently "-Wpedantic" overwrites "-Werror=write-strings",
even if that option is given after pedantic:

g++ -v -Wpedantic -Werror=write-strings main.cpp
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 6.3.0-6'
--with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared
--enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/
--enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object
--disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie
--with-system-zlib --disable-browser-plugin --enable-java-awt=gtk
--enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre
--enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64
--with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--with-target-system-zlib --enable-objc-gc=auto --enable-multiarch
--with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32
--enable-multilib --with-tune=generic --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 6.3.0 20170205 (Debian 6.3.0-6) 
COLLECT_GCC_OPTIONS='-v' '-Wpedantic' '-Werror=write-strings' '-shared-libgcc'
'-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/6/cc1plus -quiet -v -imultiarch x86_64-linux-gnu
-D_GNU_SOURCE main.cpp -quiet -dumpbase main.cpp -mtune=generic -march=x86-64
-auxbase main -Wpedantic -Werror=write-strings -version -o /tmp/ccPbVEN2.s
GNU C++14 (Debian 6.3.0-6) version 6.3.0 20170205 (x86_64-linux-gnu)
compiled by GNU C version 6.3.0 20170205, GMP version 6.1.2, MPFR
version 3.1.5, MPC version 1.0.3, isl version 0.15
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/6"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-linux-gnu/6/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/6
 /usr/include/x86_64-linux-gnu/c++/6
 /usr/include/c++/6/backward
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
GNU C++14 (Debian 6.3.0-6) version 6.3.0 20170205 (x86_64-linux-gnu)
compiled by GNU C version 6.3.0 20170205, GMP version 6.1.2, MPFR
version 3.1.5, MPC version 1.0.3, isl version 0.15
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: f4480661534e17ad26830674f037f8fe
main.cpp: In function ‘int main()’:
main.cpp:2:14: warning: ISO C++ forbids converting a string constant to ‘char*’
[-Wpedantic]
  char* str = "hello world!";
  ^~
COLLECT_GCC_OPTIONS='-v' '-Wpedantic' '-Werror=write-strings' '-shared-libgcc'
'-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/ccE9VOo8.o /tmp/ccPbVEN2.s
GNU assembler version 2.27.90 (x86_64-linux-gnu) using BFD version (GNU
Binutils for Debian) 2.27.90.20170124
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/6/:/usr/lib/gcc/x86_64-linux-gnu/6/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/6/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/6/:/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gn