Author: Henrik G. Olsson
Date: 2026-03-27T17:11:23-07:00
New Revision: bc12c38af9c160b65e36523a1b2e390fdb1c3625

URL: 
https://github.com/llvm/llvm-project/commit/bc12c38af9c160b65e36523a1b2e390fdb1c3625
DIFF: 
https://github.com/llvm/llvm-project/commit/bc12c38af9c160b65e36523a1b2e390fdb1c3625.diff

LOG: [Clang] remove redundant uses of dyn_cast (NFC) (#189106)

This removes dyn_cast invocations where the argument is already of the
target type (including through subtyping). This was created by adding a
static assert in dyn_cast and letting an LLM iterate until the code base
compiled. I then went through each example and cleaned it up. This does
not commit the static assert in dyn_cast, because it would prevent a lot
of uses in templated code. To prevent backsliding we should instead add
an LLVM aware version of
https://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-casting.html
(or expand the existing one).

Added: 
    

Modified: 
    clang/lib/AST/ExprCXX.cpp
    clang/lib/AST/ItaniumMangle.cpp
    clang/lib/Analysis/CFG.cpp
    clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
    clang/lib/Analysis/LiveVariables.cpp
    clang/lib/Analysis/UnsafeBufferUsage.cpp
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
    clang/lib/Interpreter/InterpreterUtils.cpp
    clang/lib/Sema/Sema.cpp
    clang/lib/Sema/SemaDeclCXX.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaFunctionEffects.cpp
    clang/lib/Sema/SemaOpenACC.cpp
    clang/tools/driver/cc1gen_reproducer_main.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index bcc481fc8399f..dd603bf548926 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1749,9 +1749,7 @@ PackIndexingExpr *PackIndexingExpr::Create(
 
 NamedDecl *PackIndexingExpr::getPackDecl() const {
   if (auto *D = dyn_cast<DeclRefExpr>(getPackIdExpression()); D) {
-    NamedDecl *ND = dyn_cast<NamedDecl>(D->getDecl());
-    assert(ND && "exected a named decl");
-    return ND;
+    return D->getDecl();
   }
   assert(false && "invalid declaration kind in pack indexing expression");
   return nullptr;

diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index eea04b14eaf09..ccf5717073fbf 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -643,8 +643,8 @@ static const CXXRecordDecl *getLambdaForInitCapture(const 
VarDecl *VD) {
     return nullptr;
 
   const auto *Method = cast<CXXMethodDecl>(VD->getDeclContext());
-  const auto *Lambda = dyn_cast<CXXRecordDecl>(Method->getParent());
-  if (!Lambda || !Lambda->isLambda())
+  const CXXRecordDecl *Lambda = Method->getParent();
+  if (!Lambda->isLambda())
     return nullptr;
 
   return Lambda;

diff  --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index a5a8cfb02b2b3..543b9d8424488 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -4179,9 +4179,7 @@ CFGBlock 
*CFGBuilder::VisitArrayInitLoopExpr(ArrayInitLoopExpr *A,
   if (CFGBlock *R = Visit(A->getSubExpr()))
     B = R;
 
-  auto *OVE = dyn_cast<OpaqueValueExpr>(A->getCommonExpr());
-  assert(OVE && "ArrayInitLoopExpr->getCommonExpr() should be wrapped in an "
-                "OpaqueValueExpr!");
+  OpaqueValueExpr *OVE = A->getCommonExpr();
   if (CFGBlock *R = Visit(OVE->getSourceExpr()))
     B = R;
 

diff  --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp 
b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
index 80a73a2bf687e..6b61d7fd64fd7 100644
--- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp
@@ -71,12 +71,10 @@ void FactsGenerator::flow(OriginList *Dst, OriginList *Src, 
bool Kill) {
 /// \param DRE The declaration reference expression that initiates the borrow.
 /// \return The new Loan on success, nullptr otherwise.
 static const Loan *createLoan(FactManager &FactMgr, const DeclRefExpr *DRE) {
-  if (const auto *VD = dyn_cast<ValueDecl>(DRE->getDecl())) {
-    AccessPath Path(VD);
-    // The loan is created at the location of the DeclRefExpr.
-    return FactMgr.getLoanMgr().createLoan(Path, DRE);
-  }
-  return nullptr;
+  const ValueDecl *VD = DRE->getDecl();
+  AccessPath Path(VD);
+  // The loan is created at the location of the DeclRefExpr.
+  return FactMgr.getLoanMgr().createLoan(Path, DRE);
 }
 
 /// Creates a loan for the storage location of a temporary object.

diff  --git a/clang/lib/Analysis/LiveVariables.cpp 
b/clang/lib/Analysis/LiveVariables.cpp
index 74b930bf26fb6..c529ca52abcb2 100644
--- a/clang/lib/Analysis/LiveVariables.cpp
+++ b/clang/lib/Analysis/LiveVariables.cpp
@@ -197,8 +197,7 @@ static const VariableArrayType *FindVA(QualType Ty) {
 
 static const Expr *LookThroughExpr(const Expr *E) {
   while (E) {
-    if (const Expr *Ex = dyn_cast<Expr>(E))
-      E = Ex->IgnoreParens();
+    E = E->IgnoreParens();
     if (const FullExpr *FE = dyn_cast<FullExpr>(E)) {
       E = FE->getSubExpr();
       continue;

diff  --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp 
b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index c44a42dc93c13..3dba15cff3b52 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -2287,7 +2287,7 @@ class UnsafeFormatAttributedFunctionCallGadget : public 
WarningGadget {
     auto *CE = dyn_cast<CallExpr>(S);
     if (!CE || !CE->getDirectCallee())
       return false;
-    const auto *FD = dyn_cast<FunctionDecl>(CE->getDirectCallee());
+    const FunctionDecl *FD = CE->getDirectCallee();
     if (!FD)
       return false;
 
@@ -2495,7 +2495,7 @@ class PointerDereferenceGadget : public FixableGadget {
       const auto *UO = dyn_cast<UnaryOperator>(S);
       if (!UO || UO->getOpcode() != UO_Deref)
         return;
-      const auto *CE = dyn_cast<Expr>(UO->getSubExpr());
+      const Expr *CE = UO->getSubExpr();
       if (!CE)
         return;
       CE = CE->IgnoreParenImpCasts();

diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 0fd17b98570fc..3b19b88b0a5f8 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -5979,15 +5979,14 @@ struct ReconstitutableType : public 
RecursiveASTVisitor<ReconstitutableType> {
   bool TraverseEnumType(EnumType *ET, bool = false) {
     // Unnamed enums can't be reconstituted due to a lack of column info we
     // produce in the DWARF, so we can't get Clang's full name back.
-    if (const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
-      if (!ED->getIdentifier()) {
-        Reconstitutable = false;
-        return false;
-      }
-      if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
-        Reconstitutable = false;
-        return false;
-      }
+    const EnumDecl *ED = ET->getDecl();
+    if (!ED->getIdentifier()) {
+      Reconstitutable = false;
+      return false;
+    }
+    if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
+      Reconstitutable = false;
+      return false;
     }
     return true;
   }

diff  --git a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp 
b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
index d7cfd23bb0a7a..1f5c3ed5375db 100644
--- a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
+++ b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp
@@ -70,9 +70,9 @@ class InterfaceStubFunctionsConsumer : public ASTConsumer {
             !Instance.getLangOpts().GNUInline)
           return true;
         if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
-          if (const auto *RC = dyn_cast<CXXRecordDecl>(MD->getParent()))
-            if (isa<ClassTemplateDecl>(RC->getParent()) || !isVisible(RC))
-              return true;
+          const CXXRecordDecl *RC = MD->getParent();
+          if (isa<ClassTemplateDecl>(RC->getParent()) || !isVisible(RC))
+            return true;
           if (MD->isDependentContext() || !MD->hasBody())
             return true;
         }
@@ -151,13 +151,13 @@ class InterfaceStubFunctionsConsumer : public ASTConsumer 
{
   void HandleTemplateSpecializations(const FunctionTemplateDecl &FTD,
                                      MangledSymbols &Symbols, int RDO) {
     for (const auto *D : FTD.specializations())
-      HandleNamedDecl(dyn_cast<NamedDecl>(D), Symbols, RDO);
+      HandleNamedDecl(D, Symbols, RDO);
   }
 
   void HandleTemplateSpecializations(const ClassTemplateDecl &CTD,
                                      MangledSymbols &Symbols, int RDO) {
     for (const auto *D : CTD.specializations())
-      HandleNamedDecl(dyn_cast<NamedDecl>(D), Symbols, RDO);
+      HandleNamedDecl(D, Symbols, RDO);
   }
 
   bool HandleNamedDecl(const NamedDecl *ND, MangledSymbols &Symbols, int RDO) {

diff  --git a/clang/lib/Interpreter/InterpreterUtils.cpp 
b/clang/lib/Interpreter/InterpreterUtils.cpp
index a1f164a3946e8..526cd491dbc6d 100644
--- a/clang/lib/Interpreter/InterpreterUtils.cpp
+++ b/clang/lib/Interpreter/InterpreterUtils.cpp
@@ -98,7 +98,7 @@ NamedDecl *LookupNamed(Sema &S, llvm::StringRef Name,
   R.resolveKind();
 
   if (R.isSingleResult())
-    return dyn_cast<NamedDecl>(R.getFoundDecl());
+    return R.getFoundDecl();
 
   return nullptr;
 }

diff  --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 98318fc597f36..0799d1f039f9f 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1420,22 +1420,18 @@ void Sema::ActOnEndOfTranslationUnit() {
   // in the module purview but has no definition before the end of the TU or
   // the start of a Private Module Fragment (if one is present).
   if (!PendingInlineFuncDecls.empty()) {
-    for (auto *D : PendingInlineFuncDecls) {
-      if (auto *FD = dyn_cast<FunctionDecl>(D)) {
-        bool DefInPMF = false;
-        if (auto *FDD = FD->getDefinition()) {
-          DefInPMF = FDD->getOwningModule()->isPrivateModule();
-          if (!DefInPMF)
-            continue;
-        }
-        Diag(FD->getLocation(), diag::err_export_inline_not_defined)
-            << DefInPMF;
-        // If we have a PMF it should be at the end of the ModuleScopes.
-        if (DefInPMF &&
-            ModuleScopes.back().Module->Kind == Module::PrivateModuleFragment) 
{
-          Diag(ModuleScopes.back().BeginLoc,
-               diag::note_private_module_fragment);
-        }
+    for (auto *FD : PendingInlineFuncDecls) {
+      bool DefInPMF = false;
+      if (auto *FDD = FD->getDefinition()) {
+        DefInPMF = FDD->getOwningModule()->isPrivateModule();
+        if (!DefInPMF)
+          continue;
+      }
+      Diag(FD->getLocation(), diag::err_export_inline_not_defined) << DefInPMF;
+      // If we have a PMF it should be at the end of the ModuleScopes.
+      if (DefInPMF &&
+          ModuleScopes.back().Module->Kind == Module::PrivateModuleFragment) {
+        Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
       }
     }
     PendingInlineFuncDecls.clear();

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 441df43d3d184..b3a02a3fd5d02 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -98,7 +98,7 @@ bool CheckDefaultArgumentVisitor::VisitExpr(const Expr *Node) 
{
 /// determine whether this declaration can be used in the default
 /// argument expression.
 bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(const DeclRefExpr *DRE) {
-  const ValueDecl *Decl = dyn_cast<ValueDecl>(DRE->getDecl());
+  const ValueDecl *Decl = DRE->getDecl();
 
   if (!isa<VarDecl, BindingDecl>(Decl))
     return false;

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 4856a51aa6a0d..102b6315b4e3b 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13963,10 +13963,10 @@ static NonConstCaptureKind 
isReferenceToNonConstCapture(Sema &S, Expr *E) {
   if (!DRE) return NCCK_None;
   if (!DRE->refersToEnclosingVariableOrCapture()) return NCCK_None;
 
-  ValueDecl *Value = dyn_cast<ValueDecl>(DRE->getDecl());
+  ValueDecl *Value = DRE->getDecl();
 
   // The declaration must be a value which is not declared 'const'.
-  if (!Value || Value->getType().isConstQualified())
+  if (Value->getType().isConstQualified())
     return NCCK_None;
 
   BindingDecl *Binding = dyn_cast<BindingDecl>(Value);

diff  --git a/clang/lib/Sema/SemaFunctionEffects.cpp 
b/clang/lib/Sema/SemaFunctionEffects.cpp
index 12cc02965e7d3..124e23cc97556 100644
--- a/clang/lib/Sema/SemaFunctionEffects.cpp
+++ b/clang/lib/Sema/SemaFunctionEffects.cpp
@@ -987,7 +987,7 @@ class Analyzer {
       // The target function may have implicit code paths beyond the
       // body: member and base destructors. Visit these first.
       if (auto *Dtor = dyn_cast<CXXDestructorDecl>(CurrentCaller.CDecl))
-        followDestructor(dyn_cast<CXXRecordDecl>(Dtor->getParent()), Dtor);
+        followDestructor(Dtor->getParent(), Dtor);
 
       if (auto *FD = dyn_cast<FunctionDecl>(CurrentCaller.CDecl)) {
         TrailingRequiresClause = 
FD->getTrailingRequiresClause().ConstraintExpr;
@@ -1095,9 +1095,8 @@ class Analyzer {
       for (const FieldDecl *Field : Rec->fields())
         followTypeDtor(Field->getType(), DtorLoc);
 
-      if (const auto *Class = dyn_cast<CXXRecordDecl>(Rec))
-        for (const CXXBaseSpecifier &Base : Class->bases())
-          followTypeDtor(Base.getType(), DtorLoc);
+      for (const CXXBaseSpecifier &Base : Rec->bases())
+        followTypeDtor(Base.getType(), DtorLoc);
     }
 
     void followTypeDtor(QualType QT, SourceLocation CallSite) {

diff  --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 1115efbb8305c..30e07d7b145af 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -1231,7 +1231,7 @@ const ValueDecl *getDeclFromExpr(const Expr *E) {
   if (!E)
     return nullptr;
   if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
-    return dyn_cast<ValueDecl>(DRE->getDecl());
+    return DRE->getDecl();
 
   if (const auto *ME = dyn_cast<MemberExpr>(E))
     if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))

diff  --git a/clang/tools/driver/cc1gen_reproducer_main.cpp 
b/clang/tools/driver/cc1gen_reproducer_main.cpp
index 851d252015c44..d8e4a0d470bc5 100644
--- a/clang/tools/driver/cc1gen_reproducer_main.cpp
+++ b/clang/tools/driver/cc1gen_reproducer_main.cpp
@@ -136,12 +136,10 @@ generateReproducerForInvocationArguments(
   std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(Argv));
   if (C && !C->containsError()) {
     for (const auto &J : C->getJobs()) {
-      if (const Command *Cmd = dyn_cast<Command>(&J)) {
-        Driver::CompilationDiagnosticReport Report;
-        TheDriver.generateCompilationDiagnostics(
-            *C, *Cmd, generateReproducerMetaInfo(Info), &Report);
-        return Report;
-      }
+      Driver::CompilationDiagnosticReport Report;
+      TheDriver.generateCompilationDiagnostics(
+          *C, J, generateReproducerMetaInfo(Info), &Report);
+      return Report;
     }
   }
 


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to