[Bug c/90036] [8/9/10 Regression] false positive: directive argument is null [-Werror=format-overflow=]

2020-01-24 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036

Jeffrey A. Law  changed:

   What|Removed |Added

   Target Milestone|10.0|11.0

--- Comment #9 from Jeffrey A. Law  ---
I still think extracting the predicate analysis bits out of tree-ssa-uninit.c
is the way to go.  Essentially we'd build the predicate guarding the
problematical sprintf call and realize it can never be true.

There's a slight chance the new VRP code could help here as it does have a
backwards substitution/solver engine.  I think we'd want to raise the query
what's the range of ownvptr_15 in bb4 and work backwards.  

Aldy, want to take a looksie and see if your work could help here.

In either case, I don't see this being resolved in gcc-10.

[Bug c/90036] [8/9/10 Regression] false positive: directive argument is null [-Werror=format-overflow=]

2019-04-29 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036

--- Comment #8 from Jeffrey A. Law  ---
extern int sprintf (char *__restrict __s,
const char *__restrict __format, ...)
  __attribute__ ((__nothrow__));

typedef int bfd_boolean;



struct stab_type_stack
{
  long index;
  bfd_boolean definition;
};



struct stab_write_handle
{
  struct stab_type_stack *type_stack;
};
extern char *stab_pop_type (struct stab_write_handle *);
bfd_boolean stab_start_struct_type (void *, const char *, unsigned int,
bfd_boolean, unsigned int);


bfd_boolean
stab_start_class_type (void *p, const char *tag, unsigned int id,
   bfd_boolean structp, unsigned int size,
   bfd_boolean vptr, bfd_boolean ownvptr)
{
  struct stab_write_handle *info = (struct stab_write_handle *) p;
  bfd_boolean definition;
  char *vstring;

  if (!vptr || ownvptr)
{
  definition = 0;
  vstring = ((void *) 0);
}
  else
{
  definition = info->type_stack->definition;
  vstring = stab_pop_type (info);
}



  if (vptr)
{
  if (ownvptr)
{

  sprintf (p, "~%%%ld", info->type_stack->index);
}
  else
{
  sprintf (p, "~%%%s", vstring);
}

}

  if (definition)
info->type_stack->definition = 1;

  return 1;
}

[Bug c/90036] [8/9/10 Regression] false positive: directive argument is null [-Werror=format-overflow=]

2019-04-29 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036

--- Comment #7 from Jeffrey A. Law  ---
Bah!  Lost my reduced testcase...

[Bug c/90036] [8/9/10 Regression] false positive: directive argument is null [-Werror=format-overflow=]

2019-04-29 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036

--- Comment #6 from Segher Boessenkool  ---
(In reply to Martin Sebor from comment #5)
> A conversion specification is what follows the % character (i.e., just the
> 's' in in something like "%3s", with the 's' being called a conversion
> specifier).

7.21.6.1/4.  's' is the "conversion specifier character", but the whole
thing is the "conversion specification", including the percent sign.

/3 says a directive is a conversion specification or an ordinary character,
so imho it isn't great to refer to directives in the warning (also it's the
first time I heard it called that; I hazard I'm not the only one.

> The use of plain here null comes -Wnonnull: null argument where non-null
> required.  I don't see that as a problem but I also wouldn't have an issue
> with changing both to "null pointer" (like -Wformat prints) just as long as
> it's done consistently.

Right.  There are two goals to warnings:

1) They should be *correct*;
2) they should be helpful.

Sometimes these two bite each other.  Rephrasing can help sometimes.

[Bug c/90036] [8/9/10 Regression] false positive: directive argument is null [-Werror=format-overflow=]

2019-04-29 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036

--- Comment #5 from Martin Sebor  ---
(In reply to Dmitry G. Dyachenko from comment #3)

The null pointer detection was added in r265648 so that would be the change
responsible for the warning.  As Jeff noted, the root cause of false positives
here isn't the warning itself but a missing optimization.  We will be making
some design changes to the printf warning pass in GCC 10 that could affect the
false positive rate so they might also give us an opportunity to look into the
missed dom optimization. 

(In reply to Segher Boessenkool from comment #4)

I agree the underlining could stand to be improved here (tracking is separately
would increase the odds of it getting fixed).

A conversion specification is what follows the % character (i.e., just the 's'
in in something like "%3s", with the 's' being called a conversion specifier). 
A directive either includes the % character and whatever follows up to the end
of the conversion specification, or is a plain character.  For simplicity,
-Wformat-overflow refers to whole strings of one or more ordinary characters
that don't form a conversion specification as directives.

The use of plain here null comes -Wnonnull: null argument where non-null
required.  I don't see that as a problem but I also wouldn't have an issue with
changing both to "null pointer" (like -Wformat prints) just as long as it's
done consistently.

[Bug c/90036] [8/9/10 Regression] false positive: directive argument is null [-Werror=format-overflow=]

2019-04-27 Thread segher at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036

Segher Boessenkool  changed:

   What|Removed |Added

 CC||segher at gcc dot gnu.org

--- Comment #4 from Segher Boessenkool  ---
x.cpp:22:11: error: ‘%s’ directive argument is null [-Werror=format-overflow=]
   22 | printf("%s = %s\n", [0], [0]); // warning
  | ~~^

Side issue...  It's not clear what a "directive" or a "directive argument"
is here, without guessing.  "%s" is called a "conversion specifier".  "null"
is not a defined anything either, and the highlight should ideally be on the
argument, with maybe an extra info one for the conversion spec.

So maybe something like

x.cpp:22:11: error: argument to ‘%s’ is a null pointer
[-Werror=format-overflow=]
   22 | printf("%s = %s\n", [0], [0]); // warning
  | ^~  ^~

[Bug c/90036] [8/9/10 Regression] false positive: directive argument is null [-Werror=format-overflow=]

2019-04-27 Thread dimhen at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036

--- Comment #3 from Dmitry G. Dyachenko  ---
I see smth may be similar starts at r265648 / PR87041

265647 NO warnings
265648 warnings
270581 warnings

$ cat x.cpp
#include 
#include 

extern void extf(char*);

extern unsigned U1;
extern unsigned U2;

void foo()
{
if(U1 == 0)
return;
if(U2 == 0)
return;

std::vector N1(U1);
extf([0]);

std::vector N2(U2);
extf([0]);

printf("%s = %s\n", [0], [0]); // warning
}

void foo_i(unsigned i)
{
if(i == 0)
return;
if(U2 == 0)
return;

std::vector N1(i);
extf([0]);

std::vector N2(U2);
extf([0]);

printf("%s = %s\n", [0], [0]); // warning
}

void foo_j(unsigned j)
{
if(U1 == 0)
return;
if(j == 0)
return;

std::vector N1(U1);
extf([0]);

std::vector N2(j);
extf([0]);

printf("%s = %s\n", [0], [0]); // NO warning
}

void foo_2(unsigned i, unsigned j)
{
if(i == 0)
return;
if(j == 0)
return;

std::vector N1(i);
extf([0]);

std::vector N2(j);
extf([0]);

printf("%s = %s\n", [0], [0]);  // NO warning
}

$ g++ -O2 -Wall -Werror -c x.cpp
x.cpp: In function ‘void foo()’:
x.cpp:22:11: error: ‘%s’ directive argument is null [-Werror=format-overflow=]
   22 | printf("%s = %s\n", [0], [0]); // warning
  | ~~^
x.cpp: In function ‘void foo_i(unsigned int)’:
x.cpp:38:11: error: ‘%s’ directive argument is null [-Werror=format-overflow=]
   38 | printf("%s = %s\n", [0], [0]); // warning
  | ~~^