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

clang incorrectly emits -Wundefined-func-template warning #92486

Open
ahatanak opened this issue May 17, 2024 · 5 comments
Open

clang incorrectly emits -Wundefined-func-template warning #92486

ahatanak opened this issue May 17, 2024 · 5 comments
Labels
clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer false-positive Warning fires when it should not

Comments

@ahatanak
Copy link
Collaborator

$ cat test.cpp

class c {
protected:
  virtual ~c();
  virtual int *d() const;
};

template <typename> class e : c {
  int *d() const override;
};

int t = sizeof(e<int>);

$ clang++ -c -std=gnu++2b -Wundefined-func-template test.cpp

test.cpp:7:27: warning: instantiation of function 'e::d' required here, but no definition is available [-Wundefined-func-template]
7 | template class e : c {

I don’t think instantiation of e::d is needed to compute the size of the class.

@ahatanak ahatanak added clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:diagnostics New/improved warning or error message in Clang, but not in clang-tidy or static analyzer labels May 17, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented May 17, 2024

@llvm/issue-subscribers-clang-frontend

Author: Akira Hatanaka (ahatanak)

$ cat test.cpp ``` class c { protected: virtual ~c(); virtual int *d() const; };

template <typename> class e : c {
int *d() const override;
};

int t = sizeof(e<int>);


$ clang++ -c -std=gnu++2b -Wundefined-func-template test.cpp

test.cpp:7:27: warning: instantiation of function 'e&lt;int&gt;::d' required here, but no definition is available [-Wundefined-func-template]
    7 | template &lt;typename&gt; class e : c {

I don’t think instantiation of e&lt;int&gt;::d is needed to compute the size of the class.
</details>

@EugeneZelenko EugeneZelenko added false-positive Warning fires when it should not and removed clang:frontend Language frontend issues, e.g. anything involving "Sema" labels May 17, 2024
@ahatanak
Copy link
Collaborator Author

It looks like clang started emitting the warning after 99500e8. clang doesn't warn if I revert the commit.

@shafik
Copy link
Collaborator

shafik commented May 17, 2024

CC @Fznamznon

@MitalAshok
Copy link
Contributor

This also happens in Clang 18 if we have https://godbolt.org/z/7GzabWKxq

class c {
protected:
  virtual ~c();
  virtual int d() const;
};

template <typename> class e : c {
  constexpr ~e() = default;
  int d() const override;
};

int t = sizeof(e<int>);

This appears to have just been exposed when the implicitly-declared destructor became constexpr via https://wg21.link/p2448r2#pnum_23

@zygoloid
Copy link
Collaborator

I think this is ill-formed NDR -- the class is required to be complete, so its virtual functions are ODR-used.

In practice, e<int> has a constexpr virtual destructor, so we instantiate it eagerly, and we instantiate the complete vtable with the destructor, so the behavior here makes some sense. But it would seem better if we could defer marking the vtable used until the destructor is actually used (not just instantiated because it might be used at compile time, which doesn't need the vtable).

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 false-positive Warning fires when it should not
Projects
None yet
Development

No branches or pull requests

6 participants