Hi Martin, > PR 78521 notes that the gimple-ssa-sprintf pass doesn't do the right > thing (i.e., the -Wformat-length and -fprintf-return-value options > behave incorrectly) when a conversion specification includes a width > or precision with a non-constant value. The code treats such cases > as if they were not provided which is incorrect and results in > the wrong bytes counts in warning messages and in the wrong ranges > being generated for such calls (or in the case sprintf(0, 0, ...) > for some such calls being eliminated). > > The attached patch corrects the handling of these cases, plus a couple > of other edge cases in the same area: it adjusts the parser to accept > precision in the form of just a period with no asterisk or decimal > digits after it (this sets the precision to zero), and corrects the > handling of zero precision and zero argument in integer directives > to produce no bytes on output. > > Finally, the patch also tightens up the constraint on the upper bound > of bounded functions like snprintf to be INT_MAX. The functions cannot > produce output in excess of INT_MAX + 1 bytes and some implementations > (e.g., Solaris) fail with EINVAL when the bound is INT_MAX or more. > This is the subject of PR 78520.
this patch broke Solaris bootstrap: /vol/gcc/src/hg/trunk/local/gcc/gimple-ssa-sprintf.c: In function 'void {anonymous}::get_width_and_precision(const {anonymous}::conversion_spec&, long long int*, long long int*)': /vol/gcc/src/hg/trunk/local/gcc/gimple-ssa-sprintf.c:777:45: error: call of overloaded 'abs(long long int)' is ambiguous width = abs (tree_to_shwi (spec.star_width)); ^ /vol/gcc/src/hg/trunk/local/gcc/gimple-ssa-sprintf.c:777:45: note: candidates are: In file included from /usr/include/stdlib.h:12:0, from /vol/gcc/src/hg/trunk/local/gcc/system.h:258, from /vol/gcc/src/hg/trunk/local/gcc/gimple-ssa-sprintf.c:49: /usr/include/iso/stdlib_iso.h:205:16: note: long int std::abs(long int) inline long abs(long _l) { return labs(_l); } ^ /usr/include/iso/stdlib_iso.h:160:12: note: int std::abs(int) extern int abs(int); ^ The following patch fixed this for me, but I've no idea if it's right. It bootstrapped successfully on sparc-sun-solaris2.12, i386-pc-solaris2.12, and x86_64-pc-linux-gnu. Rainer -- ----------------------------------------------------------------------------- Rainer Orth, Center for Biotechnology, Bielefeld University 2016-12-02 Rainer Orth <r...@cebitec.uni-bielefeld.de> * gimple-ssa-sprintf.c (get_width_and_precision): Use std::abs.
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -774,7 +774,7 @@ get_width_and_precision (const conversio if (spec.star_width) { if (TREE_CODE (spec.star_width) == INTEGER_CST) - width = abs (tree_to_shwi (spec.star_width)); + width = std::abs (tree_to_shwi (spec.star_width)); else width = HOST_WIDE_INT_MIN; }