[PATCH] D59802: [clang-tidy] Add new checker: llvm-prefer-isa-or-dyn-cast-in-conditionals
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 3 05:47:52 PDT 2019
aaron.ballman added inline comments.
================
Comment at: clang-tools-extra/clang-tidy/llvm/AvoidCastInConditionalCheck.cpp:145
+
+ diag(MatchedDecl->getBeginLoc(), "use dyn_cast_or_null")
+ << FixItHint::CreateReplacement(SourceRange(MatchedDecl->getBeginLoc(),
----------------
hintonda wrote:
> aaron.ballman wrote:
> > hintonda wrote:
> > > aaron.ballman wrote:
> > > > This diagnostic doesn't tell the user what they've done wrong with the code or why this is a better choice.
> > > Yes, but I'm not yet sure what it should say. Was sorta hoping for a suggestion.
> > Do you have any evidence that this situation happens in practice? I kind of feel like this entire branch could be eliminated from this patch unless it actually catches problems that happen.
> Yes, here are a few from clang/lib -- let me know if you think it's worth it or not to keep this:
>
> - DiagnosticName: llvm-avoid-cast-in-conditional
> FileOffset: 305293
> FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/Sema/SemaTemplate.cpp
> Message: method 'getAsTemplateDecl' is called twice and could be expensive
> Replacements:
> - FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/Sema/SemaTemplate.cpp
> Length: 93
> Offset: 305293
> ReplacementText: dyn_cast_or_null<TemplateTemplateParmDecl>(Name.getAsTemplateDecl())
> - DiagnosticName: llvm-avoid-cast-in-conditional
> FileOffset: 153442
> FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/AST/ASTContext.cpp
> Message: method 'getAsTemplateDecl' is called twice and could be expensive
> Replacements:
> - FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/AST/ASTContext.cpp
> Length: 92
> Offset: 153442
> ReplacementText: dyn_cast_or_null<TypeAliasTemplateDecl>(Template.getAsTemplateDecl())
> - DiagnosticName: llvm-avoid-cast-in-conditional
> FileOffset: 97556
> FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/AST/Expr.cpp
> Message: method 'getMethodDecl' is called twice and could be expensive
> Replacements:
> - FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/AST/Expr.cpp
> Length: 68
> Offset: 97556
> ReplacementText: dyn_cast_or_null<CXXConversionDecl>(MCE->getMethodDecl())
> - DiagnosticName: llvm-avoid-cast-in-conditional
> FileOffset: 301950
> FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/Sema/SemaInit.cpp
> Message: method 'get' is called twice and could be expensive
> Replacements:
> - FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/Sema/SemaInit.cpp
> Length: 49
> Offset: 301950
> ReplacementText: dyn_cast_or_null<InitListExpr>(CurInit.get())
> - DiagnosticName: llvm-avoid-cast-in-conditional
> FileOffset: 14335
> FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp
> Message: method 'operator bool' is called twice and could be expensive
> Replacements:
> - FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp
> Length: 57
> Offset: 14335
> ReplacementText: dyn_cast_or_null<CXXTryStmt>(B->getTerminator())
> - DiagnosticName: llvm-avoid-cast-in-conditional
> FileOffset: 15997
> FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp
> Message: method 'operator bool' is called twice and could be expensive
> Replacements:
> - FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/Sema/AnalysisBasedWarnings.cpp
> Length: 55
> Offset: 15997
> ReplacementText: dyn_cast_or_null<CXXTryStmt>(B.getTerminator())
> - DiagnosticName: llvm-avoid-cast-in-conditional
> FileOffset: 9492
> FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
> Message: method 'sexpr' is called twice and could be expensive
> Replacements:
> - FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
> Length: 39
> Offset: 9492
> ReplacementText: dyn_cast_or_null<til::Undefined>(sexpr())
> - DiagnosticName: llvm-avoid-cast-in-conditional
> FileOffset: 9572
> FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
> Message: method 'sexpr' is called twice and could be expensive
> Replacements:
> - FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
> Length: 38
> Offset: 9572
> ReplacementText: dyn_cast_or_null<til::Wildcard>(sexpr())
> - DiagnosticName: llvm-avoid-cast-in-conditional
> FileOffset: 9492
> FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
> Message: method 'sexpr' is called twice and could be expensive
> Replacements:
> - FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
> Length: 39
> Offset: 9492
> ReplacementText: dyn_cast_or_null<til::Undefined>(sexpr())
> - DiagnosticName: llvm-avoid-cast-in-conditional
> FileOffset: 9572
> FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
> Message: method 'sexpr' is called twice and could be expensive
> Replacements:
> - FilePath: /Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
> Length: 38
> Offset: 9572
> ReplacementText: dyn_cast_or_null<til::Wildcard>(sexpr())
>
`/Users/dhinton/projects/llvm_project/monorepo/llvm-project/clang/lib/Sema/SemaTemplate.cpp Message: method 'getAsTemplateDecl' is called twice and could be expensive Replacements:`
This one is a false positive and the fix is incorrect. The original code is:
```
Diag(TemplateNameLoc, diag::err_not_class_template_specialization)
<< (Name.getAsTemplateDecl() &&
isa<TemplateTemplateParmDecl>(Name.getAsTemplateDecl()));
```
The rest look to be plausible true positives, but not a single case looks like there is much expense involved in the expression, and honestly, several of the replacement expressions would feel a bit "worse" to me, despite being equivalent. For instance, code like: `bool Foo = bar && isa<T>(bar);` reads more clearly to me than `bool Foo = dyn_cast_or_null<T>(bar);` because the former looks like a bool initializer while the latter looks like the user meant to write `T *Foo` instead of `bool Foo`.
I think this part of the check is contentious and I'd rather leave it out for now so that we can get the rest of the check in. I'd be especially curious to know whether the community would prefer to see us leave this situation alone, introduce `isa_or_null<T>()`, or use `dyn_cast_or_null<T>()`.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D59802/new/
https://reviews.llvm.org/D59802
More information about the cfe-commits
mailing list