| Summary: | missing -Waddress in template code at definition time rather than instantiation | ||
|---|---|---|---|
| Product: | gcc | Reporter: | Martin Sebor <msebor> |
| Component: | c++ | Assignee: | Not yet assigned to anyone <unassigned> |
| Status: | ASSIGNED --- | ||
| Severity: | enhancement | CC: | webrown.cpp |
| Priority: | P3 | Keywords: | diagnostic |
| Version: | 12.0 | ||
| Target Milestone: | --- | ||
| Host: | Target: | ||
| Build: | Known to work: | ||
| Known to fail: | Last reconfirmed: | 2021-09-16 00:00:00 | |
| Bug Depends on: | |||
| Bug Blocks: | 103360 | ||
|
Description
Martin Sebor
2021-09-16 21:19:54 UTC
GCC warns only at instantiation time. (In reply to Andrew Pinski from comment #1) > GCC warns only at instantiation time. And it has been that way since at least 4.4.0. With the correct explicit instantiation directive things look much better: $ cat pr102378.C && gcc -S -Wall pr102378.C int f () { int a[2]; return &a == 0; // -Waddress (good) } template <class T> int g () { { int a[2]; return &a == 0; // missing -Waddress } { T t; return &t == 0; // no -Waddress for type-dependent expr (good) } { T a[2]; return &a == 0; // missing -Waddress } } template <class T> int h () { { int a[2]; return &a == 0; // -Waddress (good) } { T t; return &t == 0; // -Waddress (good) } { T a[2]; return &a == 0; // -Waddress (good) } } template int h<int> (); pr102378.C: In function ‘int f()’: pr102378.C:4:13: warning: the address of ‘a’ will never be NULL [-Waddress] 4 | return &a == 0; // -Waddress (good) | ~~~^~~~ pr102378.C: In instantiation of ‘int h() [with T = int]’: pr102378.C:45:22: required from here pr102378.C:31:15: warning: the address of ‘a’ will never be NULL [-Waddress] 31 | return &a == 0; // -Waddress (good) | ~~~^~~~ pr102378.C:36:15: warning: the address of ‘t’ will never be NULL [-Waddress] 36 | return &t == 0; // -Waddress (good) | ~~~^~~~ pr102378.C:41:15: warning: the address of ‘a’ will never be NULL [-Waddress] 41 | return &a == 0; // -Waddress (good) | ~~~^~~~ (In reply to Andrew Pinski from comment #2) > (In reply to Andrew Pinski from comment #1) > > GCC warns only at instantiation time. > > And it has been that way since at least 4.4.0. Not quite. It depends on where a warning is implemented. As the test case below shows, G++ does diagnose some problems in uninstantiated templates but not others. Jason's suggestion in the review I pointed to is to try to do better and the purpose of this bug is to capture that limitation and improvement for the work I'm doing. $ cat t.C && gcc -S -Wall -Wredundant-tags t.C struct A { A (); ~A (); }; template <class T> void f () { volatile struct A a; // -Wredundant-tags (good) register int n = sizeof a; // -Wregister (good) __builtin_memset (&a, 0, n); // missing -Wclass-memaccess and volatile A* to A* conversion warning } t.C: In function ‘void f()’: t.C:6:12: warning: redundant class-key ‘struct’ in reference to ‘struct A’ [-Wredundant-tags] 6 | volatile struct A a; // -Wredundant-tags (good) | ^~~~~~ | ------ t.C:7:16: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister] 7 | register int n = sizeof a; // -Wregister (good) | ^ GCC 12.1 is being released, retargeting bugs to GCC 12.2. GCC 12.2 is being released, retargeting bugs to GCC 12.3. GCC 12.3 is being released, retargeting bugs to GCC 12.4. GCC 12.4 is being released, retargeting bugs to GCC 12.5. |