FS#28329 - [gcc] Cannot compile program with a line like V = sqrt(pow(cos(A+atan(-B)), 2)); in it

Attached to Project: Arch Linux
Opened by Y Gator (YGator) - Wednesday, 08 February 2012, 22:11 GMT
Last edited by Allan McRae (Allan) - Saturday, 17 November 2012, 04:04 GMT
Task Type Bug Report
Category Packages: Core
Status Closed
Assigned To Allan McRae (Allan)
Architecture All
Severity Medium
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 1
Private No

Details

Description:
Cannot compile program.
On Arch on PC get
cc: internal compiler error: Killed (program cc1)
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://bugs.archlinux.org/> for instructions.
On Arch on ARM get
cc1: out of memory allocating 392426232 bytes after a total of 831488 bytes

Steps to reproduce:
cc test.c -o test -lm

#include <stdio.h>
#include <tgmath.h>

float A;
float B;
float V;

int main(int argc, char *argv[])
{
A = 5;
B = 3;
printf("A= %lf\n", A);
printf("B= %lf\n", B);
V = sqrt(pow(cos(A+atan(-B)), 2));
printf("V= %lf\n", V);

return(0);
}

Will not compile but this will.

#include <stdio.h>
#include <tgmath.h>

float A;
float B;
float V;

int main(int argc, char *argv[])
{
A = 5;
B = 3;
printf("A= %lf\n", A);
printf("B= %lf\n", B);
V = cos(A+atan(-B));
V = pow(V, 2);
V = sqrt(V);
printf("V= %lf\n", V);

return(0);
}
This task depends upon

Closed by  Allan McRae (Allan)
Saturday, 17 November 2012, 04:04 GMT
Reason for closing:  Not a bug
Comment by Dave Reisner (falconindy) - Saturday, 11 February 2012, 20:12 GMT
Specifically, the pow and sqrt macros defined in /usr/include/tgmath.h are infinitely recursing when passed through the preprocessor.
Comment by Y Gator (YGator) - Sunday, 12 February 2012, 04:55 GMT
Looks like it has to do with how many of the math functions are nested.
I can do (3) sqrt(sqrt(sqrt(A))) fine, but not (4) sqrt(sqrt(sqrt(sqrt(A)))).

I took this program
#include <stdio.h>
#include <tgmath.h>

float A;
float V;

int main(int argc, char *argv[])
{
A = 5;
printf("A= %lf\n", A);
V = sqrt(A);
printf("V= %lf\n", V);

return(0);
}
For this program with nested sqrt the preprocessor output in bytes was
sqrt(A) - 75405
sqrt(sqrt(A)) - 262080
sqrt(sqrt(sqrt(A))) - 10902555
sqrt(sqrt(sqrt(sqrt(A)))) - ran out of memory

It looks to do the same for all the functions defined with __TGMATH_UNARY_REAL_IMAG macro.
Comment by philomath (archadmirer) - Monday, 23 July 2012, 19:10 GMT
Seems like it's fixed now (4.7.1-5)?
Comment by Allan McRae (Allan) - Monday, 23 July 2012, 22:01 GMT
Does not look fixed to me...
Comment by Y Gator (YGator) - Sunday, 29 July 2012, 21:03 GMT
Not fixed!
Comment by Jonathan Liu (net147) - Friday, 09 November 2012, 12:15 GMT
Has this been reported upstream?
Comment by Allan McRae (Allan) - Friday, 16 November 2012, 13:24 GMT
We need to figure out which upstream. To quote falconindy:

It could be 1 of 3 things
1) the macro really is recursive. glibc bug.
2) the macro isn't recursive, but there's a bug in cpp. gcc bug.
3) the macro is recursive, but cpp i supposed to catch this. gcc bug.

I'll get to figuring out which one day, if someone does not beat me to it (hint, hint)
Comment by Ivan Delalande (colona) - Saturday, 17 November 2012, 02:55 GMT
These macros are not infinitely recursive, they just expand to a single ternary expression that grows *really* fast in size.

With the same test as YGator these are the sizes of the expanded ternary expression in characters I get :
sqrt(A) : 3284
sqrt(sqrt(A)) : 190073
sqrt(sqrt(sqrt(A))) : 10837046
sqrt(sqrt(sqrt(sqrt(A)))) : 617714507, which cc1 is not able to compile.

Thus it is not really a surprise if gcc run out of memory with complex composition of these macros. The problem is that there is not any bug in the two upstreams involved.
The real solution would be to rewrite these macros to reduce the size of the expanded expression, if it is possible, so we may fill a bug report for glibc.
Comment by Allan McRae (Allan) - Saturday, 17 November 2012, 04:04 GMT
OK. Closing as "Not a bug" as there is nothing actually broken here... Will ask upstream glibc if anything can be done here.

Loading...