[Bug libstdc++/61761] [C++11] std::proj returns incorrect values

2019-04-30 Thread j.v.dijk at tue dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761

--- Comment #5 from Jan van Dijk  ---
Does the usage of numeric_limits<_Tp> in complex work well for user-defined
_Tp?

For complex, at present MyType can be required to be constructible from
INFINITY to make proj work. Wouldn't using numeric_limits<_Tp> dictate a
(forbidden) numeric_limits specialization to provide
numeric_limits::infinity()?

[Bug libstdc++/61761] [C++11] std::proj returns incorrect values

2019-04-30 Thread j.v.dijk at tue dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61761

Jan van Dijk  changed:

   What|Removed |Added

 CC||j.v.dijk at tue dot nl

--- Comment #2 from Jan van Dijk  ---
Is it not perfectly fine that your patch works only for _Tp equal to float,
double or long double? Anything else is unspecified per 24.5(2). Does libstdc++
advertise to go beyond the standard and support other scalar types as well?
(And if so: is that policy documented anywhere?)

That said, I think that the correct patch would be:

Index: libstdc++-v3/include/std/complex
===
--- libstdc++-v3/include/std/complex(revision 270684)
+++ libstdc++-v3/include/std/complex(working copy)
@@ -1902,11 +1902,9 @@
 std::complex<_Tp>
 __complex_proj(const std::complex<_Tp>& __z)
 {
-  const _Tp __den = (__z.real() * __z.real()
-+ __z.imag() * __z.imag() + _Tp(1.0));
-
-  return std::complex<_Tp>((_Tp(2.0) * __z.real()) / __den,
-  (_Tp(2.0) * __z.imag()) / __den);
+  if (isinf(__z.real()) || isinf(__z.imag()))
+return std::complex<_Tp>(INFINITY, copysign(0.0, __z.imag()));
+  return __z;
 }

 #if _GLIBCXX_USE_C99_COMPLEX

Note that the combinations finite,nan and nan,finite should return __z
unmodified. As the OP mentions, this was a problem in glibc as well that was
later fixed, see: https://sourceware.org/ml/libc-alpha/2013-08/msg00374.html
The patch above makes libstdc++ do exactly what is also found in current
glibc's implementation in s_cproj_template.c

[Bug libstdc++/87982] No error for std::generate_n(ptr, ptr, f)

2019-04-29 Thread j.v.dijk at tue dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87982

--- Comment #10 from Jan van Dijk  ---
Thanks a lot. And sorry for being pedantic, but I believe that the
documentation of the return value of generate_n is still wrong for negative __n
(see the first part of comment #5).

[Bug libstdc++/87982] No error for std::generate_n(ptr, ptr, f)

2019-04-28 Thread j.v.dijk at tue dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87982

--- Comment #5 from Jan van Dijk  ---
Thanks a lot for this change.

One more nit: the standard clause 28.6.7(2) allows (== does not forbid)
negative count arguments, in which case generate_n is a no-op returning
__first, but this is not reflected by the libstdc++ documentation of the return
value, which claims  __first+__n unconditionally.

Somewhat off-topic: IMHO the standard is not explicit about the fact that gen()
is (of course) to be invoked separately for every element in the range:
"The generate_n algorithms invoke the function object gen and assign the return
value of gen through all the iterators in the range...". But that may be me not
being a native English speaker. The libstdc++ docs are more helpful for sure.

And indeed, sorry for not being sufficiently precise: the standard does not say
to *which* integral type the conversion must be possible so that type could be
used internally, or better: simply used in the interface. Having the _Size
template argument allows, in principle, the loop to be written without the
conversion being actually done, but that would be such a pico-optimization that
I still do not understand why the standard did not just fix the count type to
(e.g.) std::ptrdiff_t --- but also that is outside the scope of this issue.

[Bug libstdc++/87982] No error for std::generate_n(ptr, ptr, f)

2019-04-28 Thread j.v.dijk at tue dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87982

Jan van Dijk  changed:

   What|Removed |Added

 CC||j.v.dijk at tue dot nl

--- Comment #3 from Jan van Dijk  ---
Isn't the real problem that the standard does not specify any requirements
about the type of the count argument (or a precondition on its value)? 

Should that be a built-in integral type? Then the issue is solved by doing a
static_assert> to the implementation.

One could also argue that the counter merely be convertible to a std::size_t,
and the question (to WG21) is why then the count type is a template argument in
the first place. (One could also argue that it should be a std::ptrdiff_t,
since the algorithm really operates on a range [ptr,ptr+count] --- that would
also allow an assert(count>=0) in the implementation.)

If the intention is really that also user-defined types are supported, the
requirements on such types should be spelled out (by WG21). As an example, the
code below uses a custom counter object that can can be converted to (=> and
compared with) an integer value. Reasonable enough. However, it does not
compile because of what really seems to be an undocumented implementation
detail in stl_algo.h: the usage of decltype(__n + 0) to compute a counter type
for internal usage. Is the code below valid or not?

It is remarkable how much Sunday morning can be spent on such an innocuous
issue :-)

cat 87892_2.cpp
#include 

struct counter
{
counter(unsigned n);
operator unsigned() const;
counter& operator--();
private:
template  counter operator+(T v) const;
};

void foo()
{
  int a[2];
  std::generate_n(a, counter(2), []{ return 0;});
}

g++ -c 87892_2.cpp
In file included from /home/jan/local/gcc-head/include/c++/9.0.1/algorithm:62,
 from 87892_2.cpp:1:
/home/jan/local/gcc-head/include/c++/9.0.1/bits/stl_algo.h: In instantiation of
‘_OIter std::generate_n(_OIter, _Size, _Generator) [with _OIter = int*; _Size =
counter; _Generator = foo()::]’:
87892_2.cpp:15:48:   required from here
/home/jan/local/gcc-head/include/c++/9.0.1/bits/stl_algo.h:4448:27: error:
‘counter counter::operator+(T) const [with T = int]’ is private within this
context
 4448 |   for (__decltype(__n + 0) __niter = __n;
  |   ^~~
87892_2.cpp:9:29: note: declared private here
9 |  template  counter operator+(T v) const;
  |

[Bug libstdc++/11196] _GNU_SOURCE vs. M_PI

2016-05-16 Thread j.v.dijk at tue dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11196

Jan van Dijk  changed:

   What|Removed |Added

 CC||j.v.dijk at tue dot nl

--- Comment #10 from Jan van Dijk  ---
Has this been (partly) fixed in the meantime? The OP's test program compiles
just fine with:

  g++ (SUSE Linux) 4.8.3 20140627 [gcc-4_8-branch revision 212064]
  g++ (SUSE Linux) 5.3.1 20160412 [gcc-5-branch revision 234894]
  g++ (GCC) 7.0.0 20160516 (experimental)
  x86_64-w64-mingw32.shared-g++ (GCC) 4.9.3

I also see that GNU_SOURCE is no longer implicitly defined. At least, I do not
see that in the output of "g++ -dM -E - < /dev/null" anymore.

Are there any remaining issues, or should this report be closed?

[Bug c++/16106] Poor error message

2016-05-04 Thread j.v.dijk at tue dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=16106

Jan van Dijk  changed:

   What|Removed |Added

 CC||j.v.dijk at tue dot nl

--- Comment #2 from Jan van Dijk  ---
It appears this has been fixed long time ago already: both

g++ (SUSE Linux) 4.8.3 20140627 [gcc-4_8-branch revision 212064]
g++ (GCC) 7.0.0 20160504 (experimental)

print the desired error message:

16106.cpp: In constructor ‘A::A(T&) [with T = int]’:
16106.cpp:8:12: error: invalid initialization of non-const reference of type
‘int&’ from an rvalue of type ‘int’
 A a;
^
16106.cpp: In function ‘int main()’:
16106.cpp:8:12: error: invalid initialization of non-const reference of type
‘int&’ from an rvalue of type ‘int’
16106.cpp:3:9: note: in passing argument 1 of ‘A::A(T&) [with T = int]’
 A(T& t = T()) : tt(t) {}

[Bug c++/70933] New: [7.0 regression] ICE with -Wall on valid code in inchash::add_expr

2016-05-03 Thread j.v.dijk at tue dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70933

Bug ID: 70933
   Summary: [7.0 regression] ICE with -Wall on valid code in
inchash::add_expr
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: j.v.dijk at tue dot nl
  Target Milestone: ---

The reduced testcase at the end of this report makes rev. 235846 of the
compiler ice with -Wall. Maybe related to PR70906.

> g++ -c -Wall declarations.cpp 
declarations.cpp: In instantiation of ‘void test_declarations() [with T =
unsigned int]’:
declarations.cpp:22:30:   required from here
declarations.cpp:17:5: internal compiler error: in add_expr, at tree.c:7928
  T& param = evaluator.declare_parameter("p1")=T(4);
 ^
0x1020896 inchash::add_expr(tree_node const*, inchash::hash&, unsigned int)
../../gcc-head/gcc/tree.c:7928
0x10202f2 inchash::add_expr(tree_node const*, inchash::hash&, unsigned int)
../../gcc-head/gcc/tree.c:7997
0x101ff75 inchash::add_expr(tree_node const*, inchash::hash&, unsigned int)
../../gcc-head/gcc/tree.c:7997
0x101ff75 inchash::add_expr(tree_node const*, inchash::hash&, unsigned int)
../../gcc-head/gcc/tree.c:7997
0x10202f2 inchash::add_expr(tree_node const*, inchash::hash&, unsigned int)
../../gcc-head/gcc/tree.c:7997
0x101ff75 inchash::add_expr(tree_node const*, inchash::hash&, unsigned int)
../../gcc-head/gcc/tree.c:7997
0x10202f2 inchash::add_expr(tree_node const*, inchash::hash&, unsigned int)
../../gcc-head/gcc/tree.c:7997
0xa9bf68 operand_equal_p(tree_node const*, tree_node const*, unsigned int)
../../gcc-head/gcc/fold-const.c:2761
0x8ae46a candidate_equal_p
../../gcc-head/gcc/c-family/c-common.c:2926
0x8ae4fb candidate_equal_p
../../gcc-head/gcc/c-family/c-common.c:2926
0x8ae4fb merge_tlist
../../gcc-head/gcc/c-family/c-common.c:2831
0x8b2725 verify_tree
../../gcc-head/gcc/c-family/c-common.c:3135
0x8b66aa verify_sequence_points(tree_node*)
../../gcc-head/gcc/c-family/c-common.c:3159
0x7fa287 finish_expr_stmt(tree_node*)
../../gcc-head/gcc/cp/semantics.c:682
0x699f0d initialize_local_var
../../gcc-head/gcc/cp/decl.c:6428
0x699f0d cp_finish_decl(tree_node*, tree_node*, bool, tree_node*, int)
../../gcc-head/gcc/cp/decl.c:6977
0x6cc84f tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../gcc-head/gcc/cp/pt.c:15216
0x6c8f24 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../gcc-head/gcc/cp/pt.c:15105
0x6c9d27 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
../../gcc-head/gcc/cp/pt.c:15290
0x6c697d instantiate_decl(tree_node*, int, bool)
../../gcc-head/gcc/cp/pt.c:22019


jan@linux-pwd6:~/src/gum-cvs/plmathparser/testsuite> cat declarations.cpp 
struct string
{
string(const char*);
};

template 
struct expression_evaluator
{
typedef T result_type;
result_type& declare_parameter(const string& name);
};

template 
void test_declarations()
{
expression_evaluator evaluator;
T& param = evaluator.declare_parameter("p1")=T(4);
}

void foo()
{
test_declarations();
}

[Bug libstdc++/67375] abi::__cxa_demangle crashes demangling a lambda

2016-05-02 Thread j.v.dijk at tue dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67375

Jan van Dijk  changed:

   What|Removed |Added

 CC||j.v.dijk at tue dot nl

--- Comment #1 from Jan van Dijk  ---
Has this been fixed in the meantime? I tried to reproduce this on an x86_64 box
(OpenSuSE Tumbleweed) with both

 g++ (SUSE Linux) 5.3.1 20160301 [gcc-5-branch revision 233849]
 g++ (GCC) 7.0.0 20160502 (experimental)

Compilation with default options and running the test code does not dump core.
Output:

void
c::DD::(c::FF&)::{lambda()#1}*&
std::_AAA_::_M_bb(void
c::DD::(c::FF&)::{lambda()#1}*&)::{lambda()#1}*>()

[Bug middle-end/48323] [4.5/4.6/4.7 Regression] Lifetime of local variables: global versus member function

2011-03-28 Thread j.v.dijk at tue dot nl
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48323

--- Comment #4 from Jan van Dijk  2011-03-28 22:17:15 
UTC ---
(In reply to comment #3)
Sorry for being pedantic, but would you care to explain how your observation
renders this report invalid? I am afraid I do not understand this resolution. 

Do you assert that the two cases (static local in global vs. class scope
function) are deliberately treated differently? If so, is this an
implementation choice, or is it based on a document that I should have read
(which one)?

If this isn't changed back, shouldn't this change at least be documented? It
may break more user code, not just mine...

Thanks again for your time.


[Bug c++/48323] New: Lifetime of local variables: global versus member function

2011-03-28 Thread j.v.dijk at tue dot nl
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48323

   Summary: Lifetime of local variables: global versus member
function
   Product: gcc
   Version: 4.5.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: j.v.d...@tue.nl


[First presented on gcc-help. Submitted as per the suggestion of Ian Lance
Taylor, see http://gcc.gnu.org/ml/gcc-help/2011-03/msg00340.html ]

Consider the following shared object:

// g++ -o libtest.so -shared -fPIC dltestlib.cpp

#include 

int global_f() { static int i=0; return i; }

struct C
{
int class_scope_f() { static int i=0; return i; }
C()
{
global_f();
//  class_scope_f(); // CULPRIT
}
~C() { std::cout << "Destructor called" << std::endl; }
};

static C c;

Also consider the following test program, which merely loads and unloads this 
library using dlopen/dlclose.

// g++ dltest2.cpp -ldl

#include 
#include 

int main(int argc, const char* argv[])
{
if (argc!=2) return -1;

const char* fname = argv[1];
std::cout << "Opening: " << fname << std::endl;
void* handle = dlopen( fname, RTLD_NOW | RTLD_LOCAL);
std::cout << "Handle after dlopen: " << handle << std::endl;
if(!handle)
{
std::cout << dlerror() << std::endl;
}

dlclose(handle);
// do not load. Only check if the file is resident.
handle = dlopen( fname, RTLD_NOW | RTLD_NOLOAD);
std::cout << "Handle after dlclose: " << handle << std::endl;
std::cout << "Exiting..." << std::endl;
}

Providing the abovementioned library as argument, I get the expected result:

./a.out /home/jan/src/gum-cvs/ideas/jan/libtest.so

Opening: /home/jan/src/gum-cvs/ideas/jan/libtest.so
Handle after dlopen: 0x602050
Destructor called
Handle after dlclose: 0
Exiting...

In particular, the library *is* unloaded by dlclose (so the global destructor 
of object c in the library is called before the program is exiting.)

And now for the problem... 
If I comment in line 11 of the library module (marked CULPRIT), thus calling 
class_scope_f(), and try again, the result is:

Opening: /home/jan/src/gum-cvs/ideas/jan/libtest.so
Handle after dlopen: 0x602050
Handle after dlclose: 0x602050
Exiting...
Destructor called

Now the library unloading fails (the handle is still !=0, and indeed the 
destructor of c is not called before the program terminates).

I assume this is because there is a difference in lifetime between local 
static variables in functions in global scope vs. those of member functions. 
Is this the intended behaviour? (I say 'intended', not 'mandated', because I 
know so's are beyond the scope of ISO-C++.) If not, should I file a report?

I am on OpenSuSE 11.4; that is: glibc 2.11.3, gcc 4.5.1, binutils 2.21.