Skip to content

Conversation

kazutakahirata
Copy link
Contributor

This patch replaces LLVM_ATTRIBUTE_UNUSED with [[maybe_unused]],
introduced as part of C++17.

This patch replaces LLVM_ATTRIBUTE_UNUSED with [[maybe_unused]],
introduced as part of C++17.
@kazutakahirata kazutakahirata requested a review from lanza as a code owner October 17, 2025 06:40
@kazutakahirata kazutakahirata requested a review from arsenm October 17, 2025 06:40
@kazutakahirata kazutakahirata requested a review from kuhar October 17, 2025 06:40
@llvmbot llvmbot added clang Clang issues not falling into any other category clang-format clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:codegen IR generation bugs: mangling, exceptions, etc. clang:static analyzer ClangIR Anything related to the ClangIR project clang:bytecode Issues for the clang bytecode constexpr interpreter labels Oct 17, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 17, 2025

@llvm/pr-subscribers-clang-format
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clangir

Author: Kazu Hirata (kazutakahirata)

Changes

This patch replaces LLVM_ATTRIBUTE_UNUSED with [[maybe_unused]],
introduced as part of C++17.


Full diff: https://github.com/llvm/llvm-project/pull/163914.diff

16 Files Affected:

  • (modified) clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h (+6-8)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+1-1)
  • (modified) clang/lib/AST/Comment.cpp (+4-4)
  • (modified) clang/lib/AST/Stmt.cpp (+10-6)
  • (modified) clang/lib/AST/StmtPrinter.cpp (+2-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+1-1)
  • (modified) clang/lib/CIR/CodeGen/CIRGenValue.h (+3-3)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+1-2)
  • (modified) clang/lib/Format/UnwrappedLineParser.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp (+3-4)
  • (modified) clang/lib/Tooling/CompilationDatabase.cpp (+1-1)
  • (modified) clang/lib/Tooling/Execution.cpp (+2-2)
  • (modified) clang/lib/Tooling/Syntax/BuildTree.cpp (+4-2)
  • (modified) clang/unittests/StaticAnalyzer/RangeSetTest.cpp (+7-7)
  • (modified) clang/unittests/StaticAnalyzer/SValTest.cpp (+3-4)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h b/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h
index 17fddaee871b3..dbd030446a6fc 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h
@@ -54,10 +54,10 @@ static bool isLocalLinkage(GlobalLinkageKind linkage) {
 static bool isExternalWeakLinkage(GlobalLinkageKind linkage) {
   return linkage == GlobalLinkageKind::ExternalWeakLinkage;
 }
-LLVM_ATTRIBUTE_UNUSED static bool isCommonLinkage(GlobalLinkageKind linkage) {
+[[maybe_unused]] static bool isCommonLinkage(GlobalLinkageKind linkage) {
   return linkage == GlobalLinkageKind::CommonLinkage;
 }
-LLVM_ATTRIBUTE_UNUSED static bool
+[[maybe_unused]] static bool
 isValidDeclarationLinkage(GlobalLinkageKind linkage) {
   return isExternalWeakLinkage(linkage) || isExternalLinkage(linkage);
 }
@@ -65,8 +65,7 @@ isValidDeclarationLinkage(GlobalLinkageKind linkage) {
 /// Whether the definition of this global may be replaced by something
 /// non-equivalent at link time. For example, if a function has weak linkage
 /// then the code defining it may be replaced by different code.
-LLVM_ATTRIBUTE_UNUSED static bool
-isInterposableLinkage(GlobalLinkageKind linkage) {
+[[maybe_unused]] static bool isInterposableLinkage(GlobalLinkageKind linkage) {
   switch (linkage) {
   case GlobalLinkageKind::WeakAnyLinkage:
   case GlobalLinkageKind::LinkOnceAnyLinkage:
@@ -89,8 +88,7 @@ isInterposableLinkage(GlobalLinkageKind linkage) {
 
 /// Whether the definition of this global may be discarded if it is not used
 /// in its compilation unit.
-LLVM_ATTRIBUTE_UNUSED static bool
-isDiscardableIfUnused(GlobalLinkageKind linkage) {
+[[maybe_unused]] static bool isDiscardableIfUnused(GlobalLinkageKind linkage) {
   return isLinkOnceLinkage(linkage) || isLocalLinkage(linkage) ||
          isAvailableExternallyLinkage(linkage);
 }
@@ -99,7 +97,7 @@ isDiscardableIfUnused(GlobalLinkageKind linkage) {
 /// Using this method outside of the code generators is almost always a
 /// mistake: when working at the IR level use isInterposable instead as it
 /// knows about ODR semantics.
-LLVM_ATTRIBUTE_UNUSED static bool isWeakForLinker(GlobalLinkageKind linkage) {
+[[maybe_unused]] static bool isWeakForLinker(GlobalLinkageKind linkage) {
   return linkage == GlobalLinkageKind::WeakAnyLinkage ||
          linkage == GlobalLinkageKind::WeakODRLinkage ||
          linkage == GlobalLinkageKind::LinkOnceAnyLinkage ||
@@ -108,7 +106,7 @@ LLVM_ATTRIBUTE_UNUSED static bool isWeakForLinker(GlobalLinkageKind linkage) {
          linkage == GlobalLinkageKind::ExternalWeakLinkage;
 }
 
-LLVM_ATTRIBUTE_UNUSED static bool isValidLinkage(GlobalLinkageKind gl) {
+[[maybe_unused]] static bool isValidLinkage(GlobalLinkageKind gl) {
   return isExternalLinkage(gl) || isLocalLinkage(gl) || isWeakLinkage(gl) ||
          isLinkOnceLinkage(gl);
 }
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index a0d2c764121d9..0ee18be166845 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -23,7 +23,7 @@
 namespace clang {
 namespace interp {
 
-LLVM_ATTRIBUTE_UNUSED static bool isNoopBuiltin(unsigned ID) {
+[[maybe_unused]] static bool isNoopBuiltin(unsigned ID) {
   switch (ID) {
   case Builtin::BIas_const:
   case Builtin::BIforward:
diff --git a/clang/lib/AST/Comment.cpp b/clang/lib/AST/Comment.cpp
index 37e21c340c316..361a8a7e68990 100644
--- a/clang/lib/AST/Comment.cpp
+++ b/clang/lib/AST/Comment.cpp
@@ -56,16 +56,16 @@ good implements_child_begin_end(Comment::child_iterator (T::*)() const) {
   return good();
 }
 
-LLVM_ATTRIBUTE_UNUSED
-static inline bad implements_child_begin_end(
-                      Comment::child_iterator (Comment::*)() const) {
+[[maybe_unused]]
+static inline bad
+implements_child_begin_end(Comment::child_iterator (Comment::*)() const) {
   return bad();
 }
 
 #define ASSERT_IMPLEMENTS_child_begin(function) \
   (void) good(implements_child_begin_end(function))
 
-LLVM_ATTRIBUTE_UNUSED
+[[maybe_unused]]
 static inline void CheckCommentASTNodes() {
 #define ABSTRACT_COMMENT(COMMENT)
 #define COMMENT(CLASS, PARENT) \
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 9ae8aea3ab37a..11ece494490de 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -252,7 +252,7 @@ namespace {
   template <class T> good implements_children(children_t T::*) {
     return good();
   }
-  LLVM_ATTRIBUTE_UNUSED
+  [[maybe_unused]]
   static bad implements_children(children_t Stmt::*) {
     return bad();
   }
@@ -261,15 +261,19 @@ namespace {
   template <class T> good implements_getBeginLoc(getBeginLoc_t T::*) {
     return good();
   }
-  LLVM_ATTRIBUTE_UNUSED
-  static bad implements_getBeginLoc(getBeginLoc_t Stmt::*) { return bad(); }
+  [[maybe_unused]]
+  static bad implements_getBeginLoc(getBeginLoc_t Stmt::*) {
+    return bad();
+  }
 
   typedef SourceLocation getLocEnd_t() const;
   template <class T> good implements_getEndLoc(getLocEnd_t T::*) {
     return good();
   }
-  LLVM_ATTRIBUTE_UNUSED
-  static bad implements_getEndLoc(getLocEnd_t Stmt::*) { return bad(); }
+  [[maybe_unused]]
+  static bad implements_getEndLoc(getLocEnd_t Stmt::*) {
+    return bad();
+  }
 
 #define ASSERT_IMPLEMENTS_children(type) \
   (void) is_good(implements_children(&type::children))
@@ -282,7 +286,7 @@ namespace {
 
 /// Check whether the various Stmt classes implement their member
 /// functions.
-LLVM_ATTRIBUTE_UNUSED
+[[maybe_unused]]
 static inline void check_implementations() {
 #define ABSTRACT_STMT(type)
 #define STMT(type, base)                                                       \
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 586c3000f105c..ff8ca01ec5477 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -151,11 +151,11 @@ namespace {
       else StmtVisitor<StmtPrinter>::Visit(S);
     }
 
-    void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
+    [[maybe_unused]] void VisitStmt(Stmt *Node) {
       Indent() << "<<unknown stmt type>>" << NL;
     }
 
-    void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
+    [[maybe_unused]] void VisitExpr(Expr *Node) {
       OS << "<<unknown expr type>>";
     }
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 81e5fe200c793..19ed6560245b4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -871,7 +871,7 @@ bool ConstRecordBuilder::updateRecord(ConstantEmitter &emitter,
 class ConstExprEmitter
     : public StmtVisitor<ConstExprEmitter, mlir::Attribute, QualType> {
   CIRGenModule &cgm;
-  LLVM_ATTRIBUTE_UNUSED ConstantEmitter &emitter;
+  [[maybe_unused]] ConstantEmitter &emitter;
 
 public:
   ConstExprEmitter(ConstantEmitter &emitter)
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h b/clang/lib/CIR/CodeGen/CIRGenValue.h
index 25b6ecb503a6e..08d9913c09c38 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -308,7 +308,7 @@ class AggValueSlot {
   /// destructor for the slot.  Otherwise the code which constructs it should
   /// push the appropriate cleanup.
   LLVM_PREFERRED_TYPE(bool)
-  LLVM_ATTRIBUTE_UNUSED unsigned destructedFlag : 1;
+  [[maybe_unused]] unsigned destructedFlag : 1;
 
   /// This is set to true if the memory in the slot is known to be zero before
   /// the assignment into it.  This means that zero fields don't need to be set.
@@ -327,7 +327,7 @@ class AggValueSlot {
   /// object, it's important that this flag never be set when
   /// evaluating an expression which constructs such an object.
   LLVM_PREFERRED_TYPE(bool)
-  LLVM_ATTRIBUTE_UNUSED unsigned aliasedFlag : 1;
+  [[maybe_unused]] unsigned aliasedFlag : 1;
 
   /// This is set to true if the tail padding of this slot might overlap
   /// another object that may have already been initialized (and whose
@@ -335,7 +335,7 @@ class AggValueSlot {
   /// store up to the dsize of the type. Otherwise we can widen stores to
   /// the size of the type.
   LLVM_PREFERRED_TYPE(bool)
-  LLVM_ATTRIBUTE_UNUSED unsigned overlapFlag : 1;
+  [[maybe_unused]] unsigned overlapFlag : 1;
 
 public:
   enum IsDestructed_t { IsNotDestructed, IsDestructed };
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 4e29d8ae36f01..cd08f3ec397a0 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -609,8 +609,7 @@ llvm::MDNode *CodeGenTBAA::getValidBaseTypeInfo(QualType QTy) {
   // First calculate the metadata, before recomputing the insertion point, as
   // the helper can recursively call us.
   llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
-  LLVM_ATTRIBUTE_UNUSED auto inserted =
-      BaseTypeMetadataCache.insert({Ty, TypeNode});
+  [[maybe_unused]] auto inserted = BaseTypeMetadataCache.insert({Ty, TypeNode});
   assert(inserted.second && "BaseType metadata was already inserted");
 
   return TypeNode;
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index dec71191d7356..5e2584edac8f4 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -60,7 +60,7 @@ void printLine(llvm::raw_ostream &OS, const UnwrappedLine &Line,
     OS << "\n";
 }
 
-LLVM_ATTRIBUTE_UNUSED static void printDebugInfo(const UnwrappedLine &Line) {
+[[maybe_unused]] static void printDebugInfo(const UnwrappedLine &Line) {
   printLine(llvm::dbgs(), Line);
 }
 
diff --git a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
index 02f34bc30f554..c905ee6bc9fc9 100644
--- a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -173,7 +173,7 @@ const PointerToMemberData *BasicValueFactory::getPointerToMemberData(
   return D;
 }
 
-LLVM_ATTRIBUTE_UNUSED static bool hasNoRepeatedElements(
+[[maybe_unused]] static bool hasNoRepeatedElements(
     llvm::ImmutableList<const CXXBaseSpecifier *> BaseSpecList) {
   llvm::SmallPtrSet<QualType, 16> BaseSpecSeen;
   for (const CXXBaseSpecifier *BaseSpec : BaseSpecList) {
diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index ab45e678bafd5..245a73047513b 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -983,7 +983,7 @@ class EquivalenceClass : public llvm::FoldingSetNode {
   }
 
   /// Check equivalence data for consistency.
-  [[nodiscard]] LLVM_ATTRIBUTE_UNUSED static bool
+  [[nodiscard]] [[maybe_unused]] static bool
   isClassDataConsistent(ProgramStateRef State);
 
   [[nodiscard]] QualType getType() const {
@@ -1041,8 +1041,7 @@ class EquivalenceClass : public llvm::FoldingSetNode {
 //                             Constraint functions
 //===----------------------------------------------------------------------===//
 
-[[nodiscard]] LLVM_ATTRIBUTE_UNUSED bool
-areFeasible(ConstraintRangeTy Constraints) {
+[[nodiscard]] [[maybe_unused]] bool areFeasible(ConstraintRangeTy Constraints) {
   return llvm::none_of(
       Constraints,
       [](const std::pair<EquivalenceClass, RangeSet> &ClassConstraint) {
@@ -1134,7 +1133,7 @@ template <class EndTy>
   return End;
 }
 
-[[nodiscard]] LLVM_ATTRIBUTE_UNUSED inline std::optional<RangeSet>
+[[nodiscard]] [[maybe_unused]] inline std::optional<RangeSet>
 intersect(RangeSet::Factory &F, const RangeSet *End) {
   // This is an extraneous conversion from a raw pointer into
   // std::optional<RangeSet>
diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp
index 860457acced85..4070bb81c6f74 100644
--- a/clang/lib/Tooling/CompilationDatabase.cpp
+++ b/clang/lib/Tooling/CompilationDatabase.cpp
@@ -403,7 +403,7 @@ namespace tooling {
 // This anchor is used to force the linker to link in the generated object file
 // and thus register the JSONCompilationDatabasePlugin.
 extern volatile int JSONAnchorSource;
-static int LLVM_ATTRIBUTE_UNUSED JSONAnchorDest = JSONAnchorSource;
+[[maybe_unused]] static int JSONAnchorDest = JSONAnchorSource;
 
 } // namespace tooling
 } // namespace clang
diff --git a/clang/lib/Tooling/Execution.cpp b/clang/lib/Tooling/Execution.cpp
index 247b260b97edc..d0499fa364cfe 100644
--- a/clang/lib/Tooling/Execution.cpp
+++ b/clang/lib/Tooling/Execution.cpp
@@ -96,9 +96,9 @@ createExecutorFromCommandLineArgs(int &argc, const char **argv,
 // and thus register the StandaloneToolExecutorPlugin etc.
 extern volatile int StandaloneToolExecutorAnchorSource;
 extern volatile int AllTUsToolExecutorAnchorSource;
-static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
+[[maybe_unused]] static int StandaloneToolExecutorAnchorDest =
     StandaloneToolExecutorAnchorSource;
-static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
+[[maybe_unused]] static int AllTUsToolExecutorAnchorDest =
     AllTUsToolExecutorAnchorSource;
 
 } // end namespace tooling
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 90fd1f91b9ef2..9d49d72dea69b 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -77,8 +77,10 @@ static Expr *IgnoreImplicit(Expr *E) {
                          IgnoreCXXFunctionalCastExprWrappingConstructor);
 }
 
-LLVM_ATTRIBUTE_UNUSED
-static bool isImplicitExpr(Expr *E) { return IgnoreImplicit(E) != E; }
+[[maybe_unused]]
+static bool isImplicitExpr(Expr *E) {
+  return IgnoreImplicit(E) != E;
+}
 
 namespace {
 /// Get start location of the Declarator from the TypeLoc.
diff --git a/clang/unittests/StaticAnalyzer/RangeSetTest.cpp b/clang/unittests/StaticAnalyzer/RangeSetTest.cpp
index 9e36aabcf6644..a8c7626dec6f2 100644
--- a/clang/unittests/StaticAnalyzer/RangeSetTest.cpp
+++ b/clang/unittests/StaticAnalyzer/RangeSetTest.cpp
@@ -27,21 +27,21 @@ template <class RangeOrSet> static std::string toString(const RangeOrSet &Obj) {
   Obj.dump(SS);
   return ObjRepresentation;
 }
-LLVM_ATTRIBUTE_UNUSED static std::string toString(const llvm::APSInt &Point) {
+[[maybe_unused]] static std::string toString(const llvm::APSInt &Point) {
   return toString(Point, 10);
 }
 // We need it here for better fail diagnostics from gtest.
-LLVM_ATTRIBUTE_UNUSED static std::ostream &operator<<(std::ostream &OS,
-                                                      const RangeSet &Set) {
+[[maybe_unused]] static std::ostream &operator<<(std::ostream &OS,
+                                                 const RangeSet &Set) {
   return OS << toString(Set);
 }
 // We need it here for better fail diagnostics from gtest.
-LLVM_ATTRIBUTE_UNUSED static std::ostream &operator<<(std::ostream &OS,
-                                                      const Range &R) {
+[[maybe_unused]] static std::ostream &operator<<(std::ostream &OS,
+                                                 const Range &R) {
   return OS << toString(R);
 }
-LLVM_ATTRIBUTE_UNUSED static std::ostream &operator<<(std::ostream &OS,
-                                                      APSIntType Ty) {
+[[maybe_unused]] static std::ostream &operator<<(std::ostream &OS,
+                                                 APSIntType Ty) {
   return OS << (Ty.isUnsigned() ? "u" : "s") << Ty.getBitWidth();
 }
 
diff --git a/clang/unittests/StaticAnalyzer/SValTest.cpp b/clang/unittests/StaticAnalyzer/SValTest.cpp
index db4b01b79c6cf..f96456a3d620e 100644
--- a/clang/unittests/StaticAnalyzer/SValTest.cpp
+++ b/clang/unittests/StaticAnalyzer/SValTest.cpp
@@ -34,13 +34,12 @@ namespace clang {
 // getType() tests include whole bunch of type comparisons,
 // so when something is wrong, it's good to have gtest telling us
 // what are those types.
-LLVM_ATTRIBUTE_UNUSED std::ostream &operator<<(std::ostream &OS,
-                                               const QualType &T) {
+[[maybe_unused]] std::ostream &operator<<(std::ostream &OS, const QualType &T) {
   return OS << T.getAsString();
 }
 
-LLVM_ATTRIBUTE_UNUSED std::ostream &operator<<(std::ostream &OS,
-                                               const CanQualType &T) {
+[[maybe_unused]] std::ostream &operator<<(std::ostream &OS,
+                                          const CanQualType &T) {
   return OS << QualType{T};
 }
 

@llvmbot
Copy link
Member

llvmbot commented Oct 17, 2025

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Kazu Hirata (kazutakahirata)

Changes

This patch replaces LLVM_ATTRIBUTE_UNUSED with [[maybe_unused]],
introduced as part of C++17.


Full diff: https://github.com/llvm/llvm-project/pull/163914.diff

16 Files Affected:

  • (modified) clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h (+6-8)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+1-1)
  • (modified) clang/lib/AST/Comment.cpp (+4-4)
  • (modified) clang/lib/AST/Stmt.cpp (+10-6)
  • (modified) clang/lib/AST/StmtPrinter.cpp (+2-2)
  • (modified) clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp (+1-1)
  • (modified) clang/lib/CIR/CodeGen/CIRGenValue.h (+3-3)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+1-2)
  • (modified) clang/lib/Format/UnwrappedLineParser.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp (+3-4)
  • (modified) clang/lib/Tooling/CompilationDatabase.cpp (+1-1)
  • (modified) clang/lib/Tooling/Execution.cpp (+2-2)
  • (modified) clang/lib/Tooling/Syntax/BuildTree.cpp (+4-2)
  • (modified) clang/unittests/StaticAnalyzer/RangeSetTest.cpp (+7-7)
  • (modified) clang/unittests/StaticAnalyzer/SValTest.cpp (+3-4)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h b/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h
index 17fddaee871b3..dbd030446a6fc 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIROpsEnums.h
@@ -54,10 +54,10 @@ static bool isLocalLinkage(GlobalLinkageKind linkage) {
 static bool isExternalWeakLinkage(GlobalLinkageKind linkage) {
   return linkage == GlobalLinkageKind::ExternalWeakLinkage;
 }
-LLVM_ATTRIBUTE_UNUSED static bool isCommonLinkage(GlobalLinkageKind linkage) {
+[[maybe_unused]] static bool isCommonLinkage(GlobalLinkageKind linkage) {
   return linkage == GlobalLinkageKind::CommonLinkage;
 }
-LLVM_ATTRIBUTE_UNUSED static bool
+[[maybe_unused]] static bool
 isValidDeclarationLinkage(GlobalLinkageKind linkage) {
   return isExternalWeakLinkage(linkage) || isExternalLinkage(linkage);
 }
@@ -65,8 +65,7 @@ isValidDeclarationLinkage(GlobalLinkageKind linkage) {
 /// Whether the definition of this global may be replaced by something
 /// non-equivalent at link time. For example, if a function has weak linkage
 /// then the code defining it may be replaced by different code.
-LLVM_ATTRIBUTE_UNUSED static bool
-isInterposableLinkage(GlobalLinkageKind linkage) {
+[[maybe_unused]] static bool isInterposableLinkage(GlobalLinkageKind linkage) {
   switch (linkage) {
   case GlobalLinkageKind::WeakAnyLinkage:
   case GlobalLinkageKind::LinkOnceAnyLinkage:
@@ -89,8 +88,7 @@ isInterposableLinkage(GlobalLinkageKind linkage) {
 
 /// Whether the definition of this global may be discarded if it is not used
 /// in its compilation unit.
-LLVM_ATTRIBUTE_UNUSED static bool
-isDiscardableIfUnused(GlobalLinkageKind linkage) {
+[[maybe_unused]] static bool isDiscardableIfUnused(GlobalLinkageKind linkage) {
   return isLinkOnceLinkage(linkage) || isLocalLinkage(linkage) ||
          isAvailableExternallyLinkage(linkage);
 }
@@ -99,7 +97,7 @@ isDiscardableIfUnused(GlobalLinkageKind linkage) {
 /// Using this method outside of the code generators is almost always a
 /// mistake: when working at the IR level use isInterposable instead as it
 /// knows about ODR semantics.
-LLVM_ATTRIBUTE_UNUSED static bool isWeakForLinker(GlobalLinkageKind linkage) {
+[[maybe_unused]] static bool isWeakForLinker(GlobalLinkageKind linkage) {
   return linkage == GlobalLinkageKind::WeakAnyLinkage ||
          linkage == GlobalLinkageKind::WeakODRLinkage ||
          linkage == GlobalLinkageKind::LinkOnceAnyLinkage ||
@@ -108,7 +106,7 @@ LLVM_ATTRIBUTE_UNUSED static bool isWeakForLinker(GlobalLinkageKind linkage) {
          linkage == GlobalLinkageKind::ExternalWeakLinkage;
 }
 
-LLVM_ATTRIBUTE_UNUSED static bool isValidLinkage(GlobalLinkageKind gl) {
+[[maybe_unused]] static bool isValidLinkage(GlobalLinkageKind gl) {
   return isExternalLinkage(gl) || isLocalLinkage(gl) || isWeakLinkage(gl) ||
          isLinkOnceLinkage(gl);
 }
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index a0d2c764121d9..0ee18be166845 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -23,7 +23,7 @@
 namespace clang {
 namespace interp {
 
-LLVM_ATTRIBUTE_UNUSED static bool isNoopBuiltin(unsigned ID) {
+[[maybe_unused]] static bool isNoopBuiltin(unsigned ID) {
   switch (ID) {
   case Builtin::BIas_const:
   case Builtin::BIforward:
diff --git a/clang/lib/AST/Comment.cpp b/clang/lib/AST/Comment.cpp
index 37e21c340c316..361a8a7e68990 100644
--- a/clang/lib/AST/Comment.cpp
+++ b/clang/lib/AST/Comment.cpp
@@ -56,16 +56,16 @@ good implements_child_begin_end(Comment::child_iterator (T::*)() const) {
   return good();
 }
 
-LLVM_ATTRIBUTE_UNUSED
-static inline bad implements_child_begin_end(
-                      Comment::child_iterator (Comment::*)() const) {
+[[maybe_unused]]
+static inline bad
+implements_child_begin_end(Comment::child_iterator (Comment::*)() const) {
   return bad();
 }
 
 #define ASSERT_IMPLEMENTS_child_begin(function) \
   (void) good(implements_child_begin_end(function))
 
-LLVM_ATTRIBUTE_UNUSED
+[[maybe_unused]]
 static inline void CheckCommentASTNodes() {
 #define ABSTRACT_COMMENT(COMMENT)
 #define COMMENT(CLASS, PARENT) \
diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 9ae8aea3ab37a..11ece494490de 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -252,7 +252,7 @@ namespace {
   template <class T> good implements_children(children_t T::*) {
     return good();
   }
-  LLVM_ATTRIBUTE_UNUSED
+  [[maybe_unused]]
   static bad implements_children(children_t Stmt::*) {
     return bad();
   }
@@ -261,15 +261,19 @@ namespace {
   template <class T> good implements_getBeginLoc(getBeginLoc_t T::*) {
     return good();
   }
-  LLVM_ATTRIBUTE_UNUSED
-  static bad implements_getBeginLoc(getBeginLoc_t Stmt::*) { return bad(); }
+  [[maybe_unused]]
+  static bad implements_getBeginLoc(getBeginLoc_t Stmt::*) {
+    return bad();
+  }
 
   typedef SourceLocation getLocEnd_t() const;
   template <class T> good implements_getEndLoc(getLocEnd_t T::*) {
     return good();
   }
-  LLVM_ATTRIBUTE_UNUSED
-  static bad implements_getEndLoc(getLocEnd_t Stmt::*) { return bad(); }
+  [[maybe_unused]]
+  static bad implements_getEndLoc(getLocEnd_t Stmt::*) {
+    return bad();
+  }
 
 #define ASSERT_IMPLEMENTS_children(type) \
   (void) is_good(implements_children(&type::children))
@@ -282,7 +286,7 @@ namespace {
 
 /// Check whether the various Stmt classes implement their member
 /// functions.
-LLVM_ATTRIBUTE_UNUSED
+[[maybe_unused]]
 static inline void check_implementations() {
 #define ABSTRACT_STMT(type)
 #define STMT(type, base)                                                       \
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 586c3000f105c..ff8ca01ec5477 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -151,11 +151,11 @@ namespace {
       else StmtVisitor<StmtPrinter>::Visit(S);
     }
 
-    void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
+    [[maybe_unused]] void VisitStmt(Stmt *Node) {
       Indent() << "<<unknown stmt type>>" << NL;
     }
 
-    void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
+    [[maybe_unused]] void VisitExpr(Expr *Node) {
       OS << "<<unknown expr type>>";
     }
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 81e5fe200c793..19ed6560245b4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -871,7 +871,7 @@ bool ConstRecordBuilder::updateRecord(ConstantEmitter &emitter,
 class ConstExprEmitter
     : public StmtVisitor<ConstExprEmitter, mlir::Attribute, QualType> {
   CIRGenModule &cgm;
-  LLVM_ATTRIBUTE_UNUSED ConstantEmitter &emitter;
+  [[maybe_unused]] ConstantEmitter &emitter;
 
 public:
   ConstExprEmitter(ConstantEmitter &emitter)
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h b/clang/lib/CIR/CodeGen/CIRGenValue.h
index 25b6ecb503a6e..08d9913c09c38 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -308,7 +308,7 @@ class AggValueSlot {
   /// destructor for the slot.  Otherwise the code which constructs it should
   /// push the appropriate cleanup.
   LLVM_PREFERRED_TYPE(bool)
-  LLVM_ATTRIBUTE_UNUSED unsigned destructedFlag : 1;
+  [[maybe_unused]] unsigned destructedFlag : 1;
 
   /// This is set to true if the memory in the slot is known to be zero before
   /// the assignment into it.  This means that zero fields don't need to be set.
@@ -327,7 +327,7 @@ class AggValueSlot {
   /// object, it's important that this flag never be set when
   /// evaluating an expression which constructs such an object.
   LLVM_PREFERRED_TYPE(bool)
-  LLVM_ATTRIBUTE_UNUSED unsigned aliasedFlag : 1;
+  [[maybe_unused]] unsigned aliasedFlag : 1;
 
   /// This is set to true if the tail padding of this slot might overlap
   /// another object that may have already been initialized (and whose
@@ -335,7 +335,7 @@ class AggValueSlot {
   /// store up to the dsize of the type. Otherwise we can widen stores to
   /// the size of the type.
   LLVM_PREFERRED_TYPE(bool)
-  LLVM_ATTRIBUTE_UNUSED unsigned overlapFlag : 1;
+  [[maybe_unused]] unsigned overlapFlag : 1;
 
 public:
   enum IsDestructed_t { IsNotDestructed, IsDestructed };
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 4e29d8ae36f01..cd08f3ec397a0 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -609,8 +609,7 @@ llvm::MDNode *CodeGenTBAA::getValidBaseTypeInfo(QualType QTy) {
   // First calculate the metadata, before recomputing the insertion point, as
   // the helper can recursively call us.
   llvm::MDNode *TypeNode = getBaseTypeInfoHelper(Ty);
-  LLVM_ATTRIBUTE_UNUSED auto inserted =
-      BaseTypeMetadataCache.insert({Ty, TypeNode});
+  [[maybe_unused]] auto inserted = BaseTypeMetadataCache.insert({Ty, TypeNode});
   assert(inserted.second && "BaseType metadata was already inserted");
 
   return TypeNode;
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index dec71191d7356..5e2584edac8f4 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -60,7 +60,7 @@ void printLine(llvm::raw_ostream &OS, const UnwrappedLine &Line,
     OS << "\n";
 }
 
-LLVM_ATTRIBUTE_UNUSED static void printDebugInfo(const UnwrappedLine &Line) {
+[[maybe_unused]] static void printDebugInfo(const UnwrappedLine &Line) {
   printLine(llvm::dbgs(), Line);
 }
 
diff --git a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
index 02f34bc30f554..c905ee6bc9fc9 100644
--- a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -173,7 +173,7 @@ const PointerToMemberData *BasicValueFactory::getPointerToMemberData(
   return D;
 }
 
-LLVM_ATTRIBUTE_UNUSED static bool hasNoRepeatedElements(
+[[maybe_unused]] static bool hasNoRepeatedElements(
     llvm::ImmutableList<const CXXBaseSpecifier *> BaseSpecList) {
   llvm::SmallPtrSet<QualType, 16> BaseSpecSeen;
   for (const CXXBaseSpecifier *BaseSpec : BaseSpecList) {
diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index ab45e678bafd5..245a73047513b 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -983,7 +983,7 @@ class EquivalenceClass : public llvm::FoldingSetNode {
   }
 
   /// Check equivalence data for consistency.
-  [[nodiscard]] LLVM_ATTRIBUTE_UNUSED static bool
+  [[nodiscard]] [[maybe_unused]] static bool
   isClassDataConsistent(ProgramStateRef State);
 
   [[nodiscard]] QualType getType() const {
@@ -1041,8 +1041,7 @@ class EquivalenceClass : public llvm::FoldingSetNode {
 //                             Constraint functions
 //===----------------------------------------------------------------------===//
 
-[[nodiscard]] LLVM_ATTRIBUTE_UNUSED bool
-areFeasible(ConstraintRangeTy Constraints) {
+[[nodiscard]] [[maybe_unused]] bool areFeasible(ConstraintRangeTy Constraints) {
   return llvm::none_of(
       Constraints,
       [](const std::pair<EquivalenceClass, RangeSet> &ClassConstraint) {
@@ -1134,7 +1133,7 @@ template <class EndTy>
   return End;
 }
 
-[[nodiscard]] LLVM_ATTRIBUTE_UNUSED inline std::optional<RangeSet>
+[[nodiscard]] [[maybe_unused]] inline std::optional<RangeSet>
 intersect(RangeSet::Factory &F, const RangeSet *End) {
   // This is an extraneous conversion from a raw pointer into
   // std::optional<RangeSet>
diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp
index 860457acced85..4070bb81c6f74 100644
--- a/clang/lib/Tooling/CompilationDatabase.cpp
+++ b/clang/lib/Tooling/CompilationDatabase.cpp
@@ -403,7 +403,7 @@ namespace tooling {
 // This anchor is used to force the linker to link in the generated object file
 // and thus register the JSONCompilationDatabasePlugin.
 extern volatile int JSONAnchorSource;
-static int LLVM_ATTRIBUTE_UNUSED JSONAnchorDest = JSONAnchorSource;
+[[maybe_unused]] static int JSONAnchorDest = JSONAnchorSource;
 
 } // namespace tooling
 } // namespace clang
diff --git a/clang/lib/Tooling/Execution.cpp b/clang/lib/Tooling/Execution.cpp
index 247b260b97edc..d0499fa364cfe 100644
--- a/clang/lib/Tooling/Execution.cpp
+++ b/clang/lib/Tooling/Execution.cpp
@@ -96,9 +96,9 @@ createExecutorFromCommandLineArgs(int &argc, const char **argv,
 // and thus register the StandaloneToolExecutorPlugin etc.
 extern volatile int StandaloneToolExecutorAnchorSource;
 extern volatile int AllTUsToolExecutorAnchorSource;
-static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest =
+[[maybe_unused]] static int StandaloneToolExecutorAnchorDest =
     StandaloneToolExecutorAnchorSource;
-static int LLVM_ATTRIBUTE_UNUSED AllTUsToolExecutorAnchorDest =
+[[maybe_unused]] static int AllTUsToolExecutorAnchorDest =
     AllTUsToolExecutorAnchorSource;
 
 } // end namespace tooling
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index 90fd1f91b9ef2..9d49d72dea69b 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -77,8 +77,10 @@ static Expr *IgnoreImplicit(Expr *E) {
                          IgnoreCXXFunctionalCastExprWrappingConstructor);
 }
 
-LLVM_ATTRIBUTE_UNUSED
-static bool isImplicitExpr(Expr *E) { return IgnoreImplicit(E) != E; }
+[[maybe_unused]]
+static bool isImplicitExpr(Expr *E) {
+  return IgnoreImplicit(E) != E;
+}
 
 namespace {
 /// Get start location of the Declarator from the TypeLoc.
diff --git a/clang/unittests/StaticAnalyzer/RangeSetTest.cpp b/clang/unittests/StaticAnalyzer/RangeSetTest.cpp
index 9e36aabcf6644..a8c7626dec6f2 100644
--- a/clang/unittests/StaticAnalyzer/RangeSetTest.cpp
+++ b/clang/unittests/StaticAnalyzer/RangeSetTest.cpp
@@ -27,21 +27,21 @@ template <class RangeOrSet> static std::string toString(const RangeOrSet &Obj) {
   Obj.dump(SS);
   return ObjRepresentation;
 }
-LLVM_ATTRIBUTE_UNUSED static std::string toString(const llvm::APSInt &Point) {
+[[maybe_unused]] static std::string toString(const llvm::APSInt &Point) {
   return toString(Point, 10);
 }
 // We need it here for better fail diagnostics from gtest.
-LLVM_ATTRIBUTE_UNUSED static std::ostream &operator<<(std::ostream &OS,
-                                                      const RangeSet &Set) {
+[[maybe_unused]] static std::ostream &operator<<(std::ostream &OS,
+                                                 const RangeSet &Set) {
   return OS << toString(Set);
 }
 // We need it here for better fail diagnostics from gtest.
-LLVM_ATTRIBUTE_UNUSED static std::ostream &operator<<(std::ostream &OS,
-                                                      const Range &R) {
+[[maybe_unused]] static std::ostream &operator<<(std::ostream &OS,
+                                                 const Range &R) {
   return OS << toString(R);
 }
-LLVM_ATTRIBUTE_UNUSED static std::ostream &operator<<(std::ostream &OS,
-                                                      APSIntType Ty) {
+[[maybe_unused]] static std::ostream &operator<<(std::ostream &OS,
+                                                 APSIntType Ty) {
   return OS << (Ty.isUnsigned() ? "u" : "s") << Ty.getBitWidth();
 }
 
diff --git a/clang/unittests/StaticAnalyzer/SValTest.cpp b/clang/unittests/StaticAnalyzer/SValTest.cpp
index db4b01b79c6cf..f96456a3d620e 100644
--- a/clang/unittests/StaticAnalyzer/SValTest.cpp
+++ b/clang/unittests/StaticAnalyzer/SValTest.cpp
@@ -34,13 +34,12 @@ namespace clang {
 // getType() tests include whole bunch of type comparisons,
 // so when something is wrong, it's good to have gtest telling us
 // what are those types.
-LLVM_ATTRIBUTE_UNUSED std::ostream &operator<<(std::ostream &OS,
-                                               const QualType &T) {
+[[maybe_unused]] std::ostream &operator<<(std::ostream &OS, const QualType &T) {
   return OS << T.getAsString();
 }
 
-LLVM_ATTRIBUTE_UNUSED std::ostream &operator<<(std::ostream &OS,
-                                               const CanQualType &T) {
+[[maybe_unused]] std::ostream &operator<<(std::ostream &OS,
+                                          const CanQualType &T) {
   return OS << QualType{T};
 }
 

@cor3ntin
Copy link
Contributor

Looking around there seem to be many more uses of LLVM_ATTRIBUTE_UNUSED around - Why replace these ones but not everything?

(I think doing that replacement makes sense - all the host toolchain have support for the attribute afaik)

@tgymnich
Copy link
Member

tgymnich commented Oct 17, 2025

Looking around there seem to be many more uses of LLVM_ATTRIBUTE_UNUSED around - Why replace these ones but not everything?

(I think doing that replacement makes sense - all the host toolchain have support for the attribute afaik)

@cor3ntin I assume this is to keep PR sizes small and easy to review.

@kazutakahirata
Copy link
Contributor Author

Looking around there seem to be many more uses of LLVM_ATTRIBUTE_UNUSED around - Why replace these ones but not everything?
(I think doing that replacement makes sense - all the host toolchain have support for the attribute afaik)

@cor3ntin I assume this is to keep PR sizes small and easy to review.

Yes, that's exactly my intent. Thanks for reviews!

@kazutakahirata kazutakahirata merged commit 1dfbfbd into llvm:main Oct 17, 2025
18 checks passed
@kazutakahirata kazutakahirata deleted the cleanup_20251016_maybe_unused_clang branch October 17, 2025 14:27
@erichkeane
Copy link
Collaborator

This is causing a regression for me:

In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenDeclOpenACC.cpp:13:
In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunction.h:17:
In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.h:17:
/local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h:311:3: error: an attribute list cannot appear here
  311 |   [[maybe_unused]] unsigned destructedFlag : 1;
      |   ^~~~~~~~~~~~~~~~
/local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h:330:3: error: an attribute list cannot appear here
  330 |   [[maybe_unused]] unsigned aliasedFlag : 1;
      |   ^~~~~~~~~~~~~~~~
/local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h:338:3: error: an attribute list cannot appear here
  338 |   [[maybe_unused]] unsigned overlapFlag : 1;

ekeane@dev-epyc4:/local/home/ekeane/llvm-project/build$ /usr/bin/clang++ --version 
Ubuntu clang version 18.1.3 (1ubuntu1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

@erichkeane
Copy link
Collaborator

This is causing a regression for me:

In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenDeclOpenACC.cpp:13:
In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunction.h:17:
In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.h:17:
/local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h:311:3: error: an attribute list cannot appear here
  311 |   [[maybe_unused]] unsigned destructedFlag : 1;
      |   ^~~~~~~~~~~~~~~~
/local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h:330:3: error: an attribute list cannot appear here
  330 |   [[maybe_unused]] unsigned aliasedFlag : 1;
      |   ^~~~~~~~~~~~~~~~
/local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h:338:3: error: an attribute list cannot appear here
  338 |   [[maybe_unused]] unsigned overlapFlag : 1;
ekeane@dev-epyc4:/local/home/ekeane/llvm-project/build$ /usr/bin/clang++ --version 
Ubuntu clang version 18.1.3 (1ubuntu1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

See: https://godbolt.org/z/W6nbMbzve

Seemingly we've fixed that in Clang 21 (I vaguely remember reviewing the patch). Clang 18 however is on our support matrix.

The difference is that LLVM_ATTRIBUTE_UNUSED is defined to use the GNU spelling, so we allow those spellings in that location, however the GNU-then-CXX spellings we do not (again, as a since-fixed clang bug).

There are two potential fixes I've identified. FIRST, we could just change preferred-type to use cxx spellings in Compiler.h:

-#define LLVM_PREFERRED_TYPE(T) __attribute__((preferred_type(T)))
+#define LLVM_PREFERRED_TYPE(T) [[clang::preferred_type(T)]]

Second would be to just re-order the two in the cases this causes problems. We can put the CXX spellings FIRST (so put maybe-unused BEFORE the preferred type).

@andykaylor
Copy link
Contributor

This is causing a regression for me:

In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenDeclOpenACC.cpp:13:
In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunction.h:17:
In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.h:17:
/local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h:311:3: error: an attribute list cannot appear here
  311 |   [[maybe_unused]] unsigned destructedFlag : 1;

I ran into that problem before: #143994

I guess maybe I fixed it in the wrong way. Does moving [[maybe_unused]] before LLVM_PREFERRED_TYPE fix this for you?

@erichkeane
Copy link
Collaborator

This is causing a regression for me:

In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenDeclOpenACC.cpp:13:
In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenFunction.h:17:
In file included from /local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.h:17:
/local/home/ekeane/llvm-project/clang/lib/CIR/CodeGen/CIRGenValue.h:311:3: error: an attribute list cannot appear here
  311 |   [[maybe_unused]] unsigned destructedFlag : 1;

I ran into that problem before: #143994

I guess maybe I fixed it in the wrong way. Does moving [[maybe_unused]] before LLVM_PREFERRED_TYPE fix this for you?

Yep, re-ordering is one of the options that works for me, [[maybe_unused]] being first 'fixes' the problem.

@andykaylor
Copy link
Contributor

Yep, re-ordering is one of the options that works for me, [[maybe_unused]] being first 'fixes' the problem.

#163997

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:bytecode Issues for the clang bytecode constexpr interpreter clang:codegen IR generation bugs: mangling, exceptions, etc. clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:static analyzer clang Clang issues not falling into any other category clang-format ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants