[clang] [llvm] Add macro to suppress -Wunnecessary-virtual-specifier (PR #139614)
Devon Loehr via cfe-commits
cfe-commits at lists.llvm.org
Thu May 15 07:40:02 PDT 2025
https://github.com/DKLoehr updated https://github.com/llvm/llvm-project/pull/139614
>From 7a6f1155b617ed460cffe00246a961022ac82a29 Mon Sep 17 00:00:00 2001
From: Devon Loehr <dloehr at google.com>
Date: Mon, 12 May 2025 19:54:33 +0000
Subject: [PATCH 1/2] Add warning suppression macro
---
clang/include/clang/AST/Decl.h | 6 +++---
clang/include/clang/AST/DeclCXX.h | 2 +-
clang/include/clang/AST/DeclFriend.h | 2 +-
clang/include/clang/AST/DeclOpenMP.h | 6 +++---
clang/include/clang/Driver/Action.h | 2 +-
clang/include/clang/Sema/Sema.h | 2 +-
clang/lib/AST/ByteCode/InterpFrame.h | 2 +-
clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp | 2 +-
clang/lib/CodeGen/CGStmtOpenMP.cpp | 2 +-
clang/lib/Driver/ToolChains/Hexagon.h | 4 ++--
llvm/cmake/modules/HandleLLVMOptions.cmake | 5 -----
llvm/include/llvm/Analysis/InstSimplifyFolder.h | 2 +-
llvm/include/llvm/Analysis/TargetFolder.h | 2 +-
llvm/include/llvm/IR/ConstantFolder.h | 2 +-
llvm/include/llvm/IR/NoFolder.h | 2 +-
llvm/include/llvm/Support/Compiler.h | 13 +++++++++++++
llvm/include/llvm/Transforms/Scalar/GVNExpression.h | 2 +-
.../Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp | 2 +-
llvm/lib/Target/X86/X86InstrInfo.h | 2 +-
19 files changed, 35 insertions(+), 27 deletions(-)
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 9290ff3764c8c..69ad18f4c0581 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -173,7 +173,7 @@ class PragmaCommentDecl final
PragmaMSCommentKind CommentKind)
: Decl(PragmaComment, TU, CommentLoc), CommentKind(CommentKind) {}
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
public:
static PragmaCommentDecl *Create(const ASTContext &C, TranslationUnitDecl *DC,
@@ -207,7 +207,7 @@ class PragmaDetectMismatchDecl final
size_t ValueStart)
: Decl(PragmaDetectMismatch, TU, Loc), ValueStart(ValueStart) {}
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
public:
static PragmaDetectMismatchDecl *Create(const ASTContext &C,
@@ -5024,7 +5024,7 @@ class ImportDecl final : public Decl,
/// export void foo();
/// \endcode
class ExportDecl final : public Decl, public DeclContext {
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
private:
friend class ASTDeclReader;
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index fa58ed59484ad..64ba684306d01 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -3296,7 +3296,7 @@ class LifetimeExtendedTemporaryDecl final
mutable APValue *Value = nullptr;
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
LifetimeExtendedTemporaryDecl(Expr *Temp, ValueDecl *EDecl, unsigned Mangling)
: Decl(Decl::LifetimeExtendedTemporary, EDecl->getDeclContext(),
diff --git a/clang/include/clang/AST/DeclFriend.h b/clang/include/clang/AST/DeclFriend.h
index 1578580c89cd8..3435f5933314b 100644
--- a/clang/include/clang/AST/DeclFriend.h
+++ b/clang/include/clang/AST/DeclFriend.h
@@ -52,7 +52,7 @@ class ASTContext;
class FriendDecl final
: public Decl,
private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> {
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
public:
using FriendUnion = llvm::PointerUnion<NamedDecl *, TypeSourceInfo *>;
diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h
index cf383889c0ad9..2d07f9d9f5d8c 100644
--- a/clang/include/clang/AST/DeclOpenMP.h
+++ b/clang/include/clang/AST/DeclOpenMP.h
@@ -110,7 +110,7 @@ template <typename U> class OMPDeclarativeDirective : public U {
class OMPThreadPrivateDecl final : public OMPDeclarativeDirective<Decl> {
friend class OMPDeclarativeDirective<Decl>;
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
OMPThreadPrivateDecl(DeclContext *DC = nullptr,
SourceLocation L = SourceLocation())
@@ -418,7 +418,7 @@ class OMPRequiresDecl final : public OMPDeclarativeDirective<Decl> {
friend class OMPDeclarativeDirective<Decl>;
friend class ASTDeclReader;
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
OMPRequiresDecl(DeclContext *DC, SourceLocation L)
: OMPDeclarativeDirective<Decl>(OMPRequires, DC, L) {}
@@ -475,7 +475,7 @@ class OMPAllocateDecl final : public OMPDeclarativeDirective<Decl> {
friend class OMPDeclarativeDirective<Decl>;
friend class ASTDeclReader;
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
OMPAllocateDecl(DeclContext *DC, SourceLocation L)
: OMPDeclarativeDirective<Decl>(OMPAllocate, DC, L) {}
diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h
index 92bb19314e3d6..7aecfd886adb8 100644
--- a/clang/include/clang/Driver/Action.h
+++ b/clang/include/clang/Driver/Action.h
@@ -267,7 +267,7 @@ class BindArchAction : public Action {
/// programming model implementation needs and propagates the offloading kind to
/// its dependences.
class OffloadAction final : public Action {
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
public:
/// Type used to communicate device actions. It associates bound architecture,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 5ec67087aeea4..beeb5c79cec72 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -895,7 +895,7 @@ class Sema final : public SemaBase {
/// with a vtable when the vtable is emitted. Sema is final and not
/// polymorphic, but the debug info size savings are so significant that it is
/// worth adding a vtable just to take advantage of this optimization.
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
const LangOptions &getLangOpts() const { return LangOpts; }
OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; }
diff --git a/clang/lib/AST/ByteCode/InterpFrame.h b/clang/lib/AST/ByteCode/InterpFrame.h
index 360e6bff12327..cfebe936cd468 100644
--- a/clang/lib/AST/ByteCode/InterpFrame.h
+++ b/clang/lib/AST/ByteCode/InterpFrame.h
@@ -119,7 +119,7 @@ class InterpFrame final : public Frame {
CodePtr getRetPC() const { return RetPC; }
/// Map a location to a source.
- virtual SourceInfo getSource(CodePtr PC) const;
+ SourceInfo getSource(CodePtr PC) const;
const Expr *getExpr(CodePtr PC) const;
SourceLocation getLocation(CodePtr PC) const;
SourceRange getRange(CodePtr PC) const;
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
index aa97422d54ede..6aca31f8b4427 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -323,7 +323,7 @@ class CheckVarsEscapingDeclContext final
CheckVarsEscapingDeclContext(CodeGenFunction &CGF,
ArrayRef<const ValueDecl *> TeamsReductions)
: CGF(CGF), EscapedDecls(llvm::from_range, TeamsReductions) {}
- virtual ~CheckVarsEscapingDeclContext() = default;
+ ~CheckVarsEscapingDeclContext() = default;
void VisitDeclStmt(const DeclStmt *S) {
if (!S)
return;
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 803c7ed37635e..89a79a7579e03 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4783,7 +4783,7 @@ class CheckVarsEscapingUntiedTaskDeclContext final
public:
explicit CheckVarsEscapingUntiedTaskDeclContext() = default;
- virtual ~CheckVarsEscapingUntiedTaskDeclContext() = default;
+ ~CheckVarsEscapingUntiedTaskDeclContext() = default;
void VisitDeclStmt(const DeclStmt *S) {
if (!S)
return;
diff --git a/clang/lib/Driver/ToolChains/Hexagon.h b/clang/lib/Driver/ToolChains/Hexagon.h
index e35a224dced41..033d9b48cae10 100644
--- a/clang/lib/Driver/ToolChains/Hexagon.h
+++ b/clang/lib/Driver/ToolChains/Hexagon.h
@@ -42,8 +42,8 @@ class LLVM_LIBRARY_VISIBILITY Linker final : public Tool {
bool hasIntegratedCPP() const override { return false; }
bool isLinkJob() const override { return true; }
- virtual void RenderExtraToolArgs(const JobAction &JA,
- llvm::opt::ArgStringList &CmdArgs) const;
+ void RenderExtraToolArgs(const JobAction &JA,
+ llvm::opt::ArgStringList &CmdArgs) const;
void ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output, const InputInfoList &Inputs,
const llvm::opt::ArgList &TCArgs,
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
index 2912f45953c41..9721dacbcbe84 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -882,11 +882,6 @@ if (LLVM_ENABLE_WARNINGS AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL))
# The LLVM libraries have no stable C++ API, so -Wnoexcept-type is not useful.
append("-Wno-noexcept-type" CMAKE_CXX_FLAGS)
- # LLVM has a policy of including virtual "anchor" functions to control
- # where the vtable is emitted. In `final` classes, these are exactly what
- # this warning detects: unnecessary virtual methods.
- add_flag_if_supported("-Wno-unnecessary-virtual-specifier" CXX_SUPPORTS_UNNECESSARY_VIRTUAL_FLAG)
-
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
append("-Wnon-virtual-dtor" CMAKE_CXX_FLAGS)
endif()
diff --git a/llvm/include/llvm/Analysis/InstSimplifyFolder.h b/llvm/include/llvm/Analysis/InstSimplifyFolder.h
index d4ae4dcc918cf..fbf6764212167 100644
--- a/llvm/include/llvm/Analysis/InstSimplifyFolder.h
+++ b/llvm/include/llvm/Analysis/InstSimplifyFolder.h
@@ -36,7 +36,7 @@ class InstSimplifyFolder final : public IRBuilderFolder {
TargetFolder ConstFolder;
SimplifyQuery SQ;
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
public:
explicit InstSimplifyFolder(const DataLayout &DL) : ConstFolder(DL), SQ(DL) {}
diff --git a/llvm/include/llvm/Analysis/TargetFolder.h b/llvm/include/llvm/Analysis/TargetFolder.h
index 4c78211b5c935..57a883e16dd25 100644
--- a/llvm/include/llvm/Analysis/TargetFolder.h
+++ b/llvm/include/llvm/Analysis/TargetFolder.h
@@ -39,7 +39,7 @@ class TargetFolder final : public IRBuilderFolder {
return ConstantFoldConstant(C, DL);
}
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
public:
explicit TargetFolder(const DataLayout &DL) : DL(DL) {}
diff --git a/llvm/include/llvm/IR/ConstantFolder.h b/llvm/include/llvm/IR/ConstantFolder.h
index a75cdf97f6ed3..a1d9a8faf69e1 100644
--- a/llvm/include/llvm/IR/ConstantFolder.h
+++ b/llvm/include/llvm/IR/ConstantFolder.h
@@ -28,7 +28,7 @@ namespace llvm {
/// ConstantFolder - Create constants with minimum, target independent, folding.
class ConstantFolder final : public IRBuilderFolder {
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
public:
explicit ConstantFolder() = default;
diff --git a/llvm/include/llvm/IR/NoFolder.h b/llvm/include/llvm/IR/NoFolder.h
index c4631a9ba1cbf..2a2318dfd7863 100644
--- a/llvm/include/llvm/IR/NoFolder.h
+++ b/llvm/include/llvm/IR/NoFolder.h
@@ -33,7 +33,7 @@ namespace llvm {
/// NoFolder - Create "constants" (actually, instructions) with no folding.
class NoFolder final : public IRBuilderFolder {
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
public:
explicit NoFolder() = default;
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index 4864071ed87a8..c46a139b34728 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -710,4 +710,17 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
#define LLVM_PREFERRED_TYPE(T)
#endif
+/// \macro LLVM_VIRTUAL_ANCHOR_FUNCTION
+/// This macro is used to adhere to LLVM's policy that each class with a vtable
+/// must have at least one out-of-line virtual function. This macro allows us
+/// to declare such a function in `final` classes without triggering a warning.
+// clang-format off
+// Autoformatting makes this look awful.
+#define LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wunnecessary-virtual-specifier\"") \
+ virtual void anchor() \
+ _Pragma("clang diagnostic pop")
+// clang-format on
+
#endif
diff --git a/llvm/include/llvm/Transforms/Scalar/GVNExpression.h b/llvm/include/llvm/Transforms/Scalar/GVNExpression.h
index 50cd6ceb9fc0d..1629aacbae45c 100644
--- a/llvm/include/llvm/Transforms/Scalar/GVNExpression.h
+++ b/llvm/include/llvm/Transforms/Scalar/GVNExpression.h
@@ -452,7 +452,7 @@ class AggregateValueExpression final : public BasicExpression {
IntOperands[NumIntOperands++] = IntOperand;
}
- virtual void allocateIntOperands(BumpPtrAllocator &Allocator) {
+ void allocateIntOperands(BumpPtrAllocator &Allocator) {
assert(!IntOperands && "Operands already allocated");
IntOperands = Allocator.Allocate<unsigned>(MaxIntOperands);
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
index eb768ed9ad5a1..a67c3762df78f 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULowerBufferFatPointers.cpp
@@ -1212,7 +1212,7 @@ class FatPtrConstMaterializer final : public ValueMaterializer {
ValueToValueMapTy &UnderlyingMap)
: TypeMap(TypeMap),
InternalMapper(UnderlyingMap, RF_None, TypeMap, this) {}
- virtual ~FatPtrConstMaterializer() = default;
+ ~FatPtrConstMaterializer() = default;
Value *materialize(Value *V) override;
};
diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h
index e53f2566dd892..9dc5f4b0e086e 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.h
+++ b/llvm/lib/Target/X86/X86InstrInfo.h
@@ -225,7 +225,7 @@ class X86InstrInfo final : public X86GenInstrInfo {
X86Subtarget &Subtarget;
const X86RegisterInfo RI;
- virtual void anchor();
+ LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
bool analyzeBranchImpl(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
>From ff1a01ec09685c254c0d9bbf3a74778048c036b1 Mon Sep 17 00:00:00 2001
From: Devon Loehr <dloehr at google.com>
Date: Wed, 14 May 2025 15:14:27 +0000
Subject: [PATCH 2/2] Avoid unknown pragma for non-clang compilers
---
llvm/include/llvm/Support/Compiler.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index c46a139b34728..ce16143a86567 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -716,11 +716,16 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
/// to declare such a function in `final` classes without triggering a warning.
// clang-format off
// Autoformatting makes this look awful.
+#if defined(__clang__) && __has_warning("-Wunnecessary-virtual-specifier")
#define LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wunnecessary-virtual-specifier\"") \
virtual void anchor() \
_Pragma("clang diagnostic pop")
+#else
+#define LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \
+ virtual void anchor()
+#endif
// clang-format on
#endif
More information about the cfe-commits
mailing list