On 11/27/19 6:43 PM, Jakub Jelinek wrote:
Hi!
While working on the PR92695 bug, I've noticed a weird warning, when
the testcase contained (pointless, but not invalid) constexpr specifier on
pure virtual function. constexpr implies DECL_DECLARED_INLINE_P and
we would note_vague_linkage_fn and later complain that the inline
function wasn't ever defined.
As can be seen in the testcase, for inline pure virtual we warn the same.
The specifiers don't make much sense, but Jonathan nor I could find anything
that would say that inline pure virtual or constexpr pure virtual is
invalid. clang++ accepts those without warnings too.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?
OK.
2019-11-27 Jakub Jelinek <ja...@redhat.com>
PR c++/92695
* decl2.c (mark_used): Don't call note_vague_linkage_fn for pure
virtual functions, even if they are declared inline.
* g++.dg/warn/inline3.C: New test.
--- gcc/cp/decl2.c.jj 2019-11-12 09:09:33.658814862 +0100
+++ gcc/cp/decl2.c 2019-11-27 18:26:53.698018564 +0100
@@ -5596,8 +5596,11 @@ mark_used (tree decl, tsubst_flags_t com
vec_safe_push (no_linkage_decls, decl);
}
- if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)
- && !DECL_INITIAL (decl) && !DECL_ARTIFICIAL (decl))
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (decl)
+ && !DECL_INITIAL (decl)
+ && !DECL_ARTIFICIAL (decl)
+ && !DECL_PURE_VIRTUAL_P (decl))
/* Remember it, so we can check it was defined. */
note_vague_linkage_fn (decl);
--- gcc/testsuite/g++.dg/warn/inline3.C.jj 2019-11-27 18:13:46.685074239 +0100
+++ gcc/testsuite/g++.dg/warn/inline3.C 2019-11-27 18:18:40.688577837 +0100
@@ -0,0 +1,20 @@
+struct S {
+ inline virtual void foo () = 0; // { dg-bogus "used but never defined" }
+#if __cplusplus > 201703L
+ constexpr virtual void bar () = 0; // { dg-bogus "used but never defined"
"" { target c++2a } }
+#else
+ inline virtual void bar () = 0; // { dg-bogus "used but never defined"
"" { target c++17_down } }
+#endif
+ S () {}
+};
+struct T : public S {
+ inline virtual void foo () {}
+#if __cplusplus > 201703L
+ constexpr virtual void bar () {}
+#else
+ inline virtual void bar () {}
+#endif
+ T () {}
+};
+T t;
+void foo (S *s) { s->foo (); s->bar (); }
Jakub