Issue 958 in include-what-you-use: iwyu removes necessary header files when forward declaring template function

5 views
Skip to first unread message

notifi...@include-what-you-use.org

unread,
Oct 20, 2021, 8:07:01 AM10/20/21
to include-wh...@googlegroups.com
New issue 958 by iwansmith: iwyu removes necessary header files when forward declaring template function
https://github.com/include-what-you-use/include-what-you-use/issues/958

Consider this example:

file1.h
```
struct X{};
```

file2.h
```
template<typename T>
void templFunc();
```

file2.cxx
```
#include "file2.h"
#include "file1.h"

template<typename T>
void templFunc() {}

template<>
void templFunc<X>();

```

And the output of iwyu:
```
[iwans@home]$ include-what-you-use file2.cxx

file2.cxx should add these lines:
struct X;

file2.cxx should remove these lines:
- #include "file1.h" // lines 1-1

The full include-list for file2.cxx:
struct X;
---

iwyu has incorrectly removed file1.h and forward declared the struct X



notifi...@include-what-you-use.org

unread,
Oct 20, 2021, 12:05:08 PM10/20/21
to include-wh...@googlegroups.com
Comment #1 on issue 958 by kimgr: iwyu removes necessary header files when forward declaring template function
https://github.com/include-what-you-use/include-what-you-use/issues/958

After accepting IWYU's changes, I get:
```
$ include-what-you-use tests/958/file2.cxx

(tests/958/file2.h has correct #includes/fwd-decls)

(tests/958/file2.cxx has correct #includes/fwd-decls)

$ clang++-13 -fsyntax-only -c tests/958/file2.cxx
$
```

So it seems like that reduced example still compiles. Is there another reason you prefer the include for `X`, or does the repro need to be larger?


notifi...@include-what-you-use.org

unread,
Oct 21, 2021, 5:36:26 AM10/21/21
to include-wh...@googlegroups.com
Comment #1 on issue 958 by iwansmith: iwyu removes necessary header files when forward declaring template function
https://github.com/include-what-you-use/include-what-you-use/issues/958

My bad, the example doesn't work. Here's a more complete example I've verified fails to compile:

file1.h
```
struct X{
int x = 42;
};
```

file2.h
```
template<typename T>
int templFunc(T);
```

file2.cxx
```
#include "file2.h"
#include "file1.h"

template<typename T>
int templFunc(T val) { return val.x;}

template
int templFunc<X>(X val);
```

[iwans@home ~/Projects/C++]$ include-what-you-use file2.cxx

(file2.h has correct #includes/fwd-decls)

file2.cxx should add these lines:

file2.cxx should remove these lines:
- #include "file1.h" // lines 2-2

The full include-list for file2.cxx:
#include "file2.h"
---

After removing #include "file1.h"

```
[iwans@home ~/Projects/C++]$ g++ -c -fPIC file2.cxx
file2.cxx:7:15: error: 'X' was not declared in this scope
int templFunc<X>(X val);
^
```



notifi...@include-what-you-use.org

unread,
Oct 21, 2021, 5:37:00 AM10/21/21
to include-wh...@googlegroups.com
Comment #2 on issue 958 by iwansmith: iwyu removes necessary header files when forward declaring template function
https://github.com/include-what-you-use/include-what-you-use/issues/958

My bad, the example doesn't work. Here's a more complete example I've verified fails to compile:

file1.h
```
struct X{
int x = 42;
};
```

file2.h
```
template<typename T>
int templFunc(T);
```

file2.cxx
```
#include "file2.h"
#include "file1.h"

template<typename T>
int templFunc(T val) { return val.x;}

template
int templFunc<X>(X val);
```

Running iwyu

notifi...@include-what-you-use.org

unread,
Oct 21, 2021, 5:38:12 AM10/21/21
to include-wh...@googlegroups.com

notifi...@include-what-you-use.org

unread,
Oct 24, 2021, 11:47:59 AM10/24/21
to include-wh...@googlegroups.com
Comment #3 on issue 958 by kimgr: iwyu removes necessary header files when forward declaring template function
https://github.com/include-what-you-use/include-what-you-use/issues/958

I wasn't aware that was valid code, I expected:
```
template<> // note the <> brackets
int templFunc<X>(X val);
```
for a function template specialization, but it appears
```
template
int templFunc<X>(X val);
```
is a valid explicit instantiation: https://en.cppreference.com/w/cpp/language/function_template#Explicit_instantiation

That instantiation is kind of hidden away in the AST, and I suspect we don't take action on its template arguments in IWYU. I'm going to have to experiment more with that, but this does look like an omission bug.


Reply all
Reply to author
Forward
0 new messages