Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

-Wundefined-func-template warns that no definition is available for a pure virtual function #74016

Closed
ahatanak opened this issue Dec 1, 2023 · 12 comments · Fixed by #74510
Closed
Labels
clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer confirmed Verified by a second party false-positive Warning fires when it should not good first issue https://github.com/llvm/llvm-project/contribute

Comments

@ahatanak
Copy link
Collaborator

ahatanak commented Dec 1, 2023

The warning seems incorrect as B::bar is pure virtual and its definition isn't needed.

$ cat test.cpp
template <typename T> class B {
public:
  constexpr void foo(const T &) { bar(1); }
  virtual constexpr void bar(unsigned int) = 0;
};

template <typename T> class D : public B<T> {
public:
  constexpr void bar(unsigned int) override {}
};

void test() {
  auto t = D<int>();
  t.foo(0);
}
$ clang++ -std=c++20 test.cpp -Wundefined-func-template -c
test.cpp:4:35: warning: instantiation of function 'B<int>::bar' required here, but no definition is available [-Wundefined-func-template]
  constexpr void foo(const T &) { bar(1); }
                                  ^
test.cpp:5:26: note: forward declaration of template entity is here
  virtual constexpr void bar(unsigned int) = 0;
                         ^
test.cpp:4:35: note: add an explicit instantiation declaration to suppress this warning if 'B<int>::bar' is explicitly instantiated in another translation unit
  constexpr void foo(const T &) { bar(1); }
                                  ^
1 warning generated.
@ahatanak ahatanak added clang:frontend Language frontend issues, e.g. anything involving "Sema" false-positive Warning fires when it should not labels Dec 1, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Dec 1, 2023

@llvm/issue-subscribers-clang-frontend

Author: Akira Hatanaka (ahatanak)

The warning seems incorrect as `B::bar` is pure virtual and its definition isn't needed.

$ cat test.cpp

template &lt;typename T&gt; class B {
public:
  constexpr void foo(const T &amp;) { bar(1); }
  virtual constexpr void bar(unsigned int) = 0;
};

template &lt;typename T&gt; class D : public B&lt;T&gt; {
public:
  constexpr void bar(unsigned int) override {}
};

void test() {
  auto t = D&lt;int&gt;();
  t.foo(0);
}

$ clang++ -std=c++20 test.cpp -Wundefined-func-template -c
test.cpp:4:35: warning: instantiation of function 'B<int>::bar' required here, but no definition is available [-Wundefined-func-template]
constexpr void foo(const T &) { bar(1); }
^
test.cpp:5:26: note: forward declaration of template entity is here
virtual constexpr void bar(unsigned int) = 0;
^
test.cpp:4:35: note: add an explicit instantiation declaration to suppress this warning if 'B<int>::bar' is explicitly instantiated in another translation unit
constexpr void foo(const T &) { bar(1); }
^
1 warning generated.

@shafik shafik added the confirmed Verified by a second party label Dec 1, 2023
@shafik
Copy link
Collaborator

shafik commented Dec 1, 2023

Confirmed: https://godbolt.org/z/6a3vvveEG

@shafik shafik added clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer and removed clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Dec 1, 2023
@cor3ntin cor3ntin added the good first issue https://github.com/llvm/llvm-project/contribute label Dec 3, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Dec 3, 2023

Hi!

This issue may be a good introductory issue for people new to working on LLVM. If you would like to work on this issue, your first steps are:

  1. In the comments of the issue, request for it to be assigned to you.
  2. Fix the issue locally.
  3. Run the test suite locally. Remember that the subdirectories under test/ create fine-grained testing targets, so you can e.g. use make check-clang-ast to only run Clang's AST tests.
  4. Create a Git commit.
  5. Run git clang-format HEAD~1 to format your changes.
  6. Open a pull request to the upstream repository on GitHub. Detailed instructions can be found in GitHub's documentation.

If you have any further questions about this issue, don't hesitate to ask via a comment in the thread below.

@llvmbot
Copy link
Collaborator

llvmbot commented Dec 3, 2023

@llvm/issue-subscribers-good-first-issue

Author: Akira Hatanaka (ahatanak)

The warning seems incorrect as `B::bar` is pure virtual and its definition isn't needed.

$ cat test.cpp

template &lt;typename T&gt; class B {
public:
  constexpr void foo(const T &amp;) { bar(1); }
  virtual constexpr void bar(unsigned int) = 0;
};

template &lt;typename T&gt; class D : public B&lt;T&gt; {
public:
  constexpr void bar(unsigned int) override {}
};

void test() {
  auto t = D&lt;int&gt;();
  t.foo(0);
}

$ clang++ -std=c++20 test.cpp -Wundefined-func-template -c
test.cpp:4:35: warning: instantiation of function 'B<int>::bar' required here, but no definition is available [-Wundefined-func-template]
constexpr void foo(const T &) { bar(1); }
^
test.cpp:5:26: note: forward declaration of template entity is here
virtual constexpr void bar(unsigned int) = 0;
^
test.cpp:4:35: note: add an explicit instantiation declaration to suppress this warning if 'B<int>::bar' is explicitly instantiated in another translation unit
constexpr void foo(const T &) { bar(1); }
^
1 warning generated.

@charmitro
Copy link
Contributor

charmitro commented Dec 3, 2023

I'd like to pick this up. I'm sharing my thoughts so we can discuss them.

Where does this happen?

The warning is coming from

if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
!getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc())) {
Diag(PointOfInstantiation, diag::warn_func_template_missing)
<< Function;
Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);

We do not check if the function is a pure virtual function via FunctionDecl::isVirtualAsWritten().

Issue fix

IMO we should just add another condition in the if statement checking for this, such as:

      if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
          !getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc()) &&
          !Function->isVirtualAsWritten()) { ... }

Finally we should add a test-case for this under clang/test/SemaTemplate/ called instantiate-virtual-function.cpp (I'm not good at naming).

if all these sound good, I'll start implementing it.

@dwblaikie
Copy link
Collaborator

if all these sound good, I'll start implementing it.

Sounds about right/plausible to me, thanks!

@ahatanaka
Copy link
Contributor

We still want to emit the warning if B::bar(1) was called instead of bar(1) in B::foo, right?

The patch silences the warning.

@charmitro
Copy link
Contributor

We still want to emit the warning if B::bar(1) was called instead of bar(1) in B::foo, right?

The patch silences the warning.

Sorry I didn't get this. Are we talking about the following?

  constexpr void foo(const T &) { B::bar(1); }

instead of:

  constexpr void foo(const T &) { bar(1); }

@ahatanak
Copy link
Collaborator Author

ahatanak commented Dec 7, 2023

Yes, that's what I meant.

@charmitro
Copy link
Contributor

Yes, that's what I meant.

This is what we get with the patch:

$ ./bin/clang++ main.cc -Wundefined-func-template 
main.cc:10:26: warning: inline function 'B<int>::bar' is not defined [-Wundefined-inline]
   10 |   virtual constexpr void bar(unsigned int) = 0;
      |                          ^
main.cc:9:38: note: used here
    9 |   constexpr void foo(const T &) { B::bar(1); }
      |                                      ^
1 warning generated.
/usr/bin/ld: /tmp/main-c89dda.o: in function `B<int>::foo(int const&)':
main.cc:(.text._ZN1BIiE3fooERKi[_ZN1BIiE3fooERKi]+0x1a): undefined reference to `B<int>::bar(unsigned int)'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

@ahatanak
Copy link
Collaborator Author

ahatanak commented Dec 7, 2023

I meant the patch was silencing the -Wundefined-func-template warning.

Note that ToT clang emits the warning for the following code, but with the patch, it doesn't emit any warnings:

template <typename T> class B {
public:
  const void foo(const T &) { B::bar(1); }
  virtual const void bar(unsigned int) = 0;
};

template <typename T> class D : public B<T> {
public:
  const void bar(unsigned int) override {}
};

void test() {
  auto t = D<int>();
  t.foo(0);
}

charmitro added a commit to charmitro/llvm-project that referenced this issue Jan 5, 2024
Warning '-Wundefined-func-template' incorrectly indicates that no
definition is available for a pure virtual function. However, a
definition is not needed for a pure virtual function.

Fixes llvm#74016

Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
@charmitro
Copy link
Contributor

I meant the patch was silencing the -Wundefined-func-template warning.

Note that ToT clang emits the warning for the following code, but with the patch, it doesn't emit any warnings:

template <typename T> class B {
public:
  const void foo(const T &) { B::bar(1); }
  virtual const void bar(unsigned int) = 0;
};

template <typename T> class D : public B<T> {
public:
  const void bar(unsigned int) override {}
};

void test() {
  auto t = D<int>();
  t.foo(0);
}

Thanks for pinging me about this @ahatanak.

I revisited the patch based on your recommendation (thanks) and added a test case for it.
Please check!

charmitro added a commit to charmitro/llvm-project that referenced this issue Mar 23, 2024
Warning '-Wundefined-func-template' incorrectly indicates that no
definition is available for a pure virtual function. However, a
definition is not needed for a pure virtual function.

Fixes llvm#74016

Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
charmitro added a commit to charmitro/llvm-project that referenced this issue Apr 5, 2024
Warning '-Wundefined-func-template' incorrectly indicates that no
definition is available for a pure virtual function. However, a
definition is not needed for a pure virtual function.

Fixes llvm#74016

Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
charmitro added a commit to charmitro/llvm-project that referenced this issue Apr 5, 2024
Warning '-Wundefined-func-template' incorrectly indicates that no
definition is available for a pure virtual function. However, a
definition is not needed for a pure virtual function.

Fixes llvm#74016

Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
charmitro added a commit to charmitro/llvm-project that referenced this issue Apr 5, 2024
Warning '-Wundefined-func-template' incorrectly indicates that no
definition is available for a pure virtual function. However, a
definition is not needed for a pure virtual function.

Fixes llvm#74016

Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
charmitro added a commit to charmitro/llvm-project that referenced this issue Apr 5, 2024
Warning '-Wundefined-func-template' incorrectly indicates that no
definition is available for a pure virtual function. However, a
definition is not needed for a pure virtual function.

Fixes llvm#74016

Signed-off-by: Charalampos Mitrodimas <charmitro@posteo.net>
AaronBallman pushed a commit that referenced this issue Apr 9, 2024
…74510)

Warning '-Wundefined-func-template' incorrectly indicates that no
definition is available for a pure virtual function. However, a
definition is not needed for a pure virtual function.

Fixes #74016
ahatanaka pushed a commit to apple/llvm-project that referenced this issue Apr 9, 2024
…lvm#74510)

Warning '-Wundefined-func-template' incorrectly indicates that no
definition is available for a pure virtual function. However, a
definition is not needed for a pure virtual function.

Fixes llvm#74016

(cherry picked from commit 0c92f86)

Conflicts:
	clang/docs/ReleaseNotes.rst
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer confirmed Verified by a second party false-positive Warning fires when it should not good first issue https://github.com/llvm/llvm-project/contribute
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants