Re: [PATCH] D23168: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 68321. vleschuk added a comment. More context in text. https://reviews.llvm.org/D23168 Files: lib/AST/Decl.cpp lib/CodeGen/CGDebugInfo.cpp test/Frontend/dinoreturn.c test/Frontend/dinoreturn.cpp test/Frontend/dinoreturn.m Index: test/Frontend/dinoreturn.m === --- /dev/null +++ test/Frontend/dinoreturn.m @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +__attribute__ ((noreturn)) void f() { + exit(0); +} Index: test/Frontend/dinoreturn.cpp === --- /dev/null +++ test/Frontend/dinoreturn.cpp @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -std=c++11 -x c++ -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +[[ noreturn ]] void f() { + throw 1; +} Index: test/Frontend/dinoreturn.c === --- /dev/null +++ test/Frontend/dinoreturn.c @@ -0,0 +1,6 @@ +// RUN: %clang %s -c -std=c11 -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +#include +_Noreturn void f() { + exit(0); +} Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2641,6 +2641,9 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } +// Check if it is a noreturn-marked function +if (FD->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2657,9 +2657,13 @@ } bool FunctionDecl::isNoReturn() const { - return hasAttr() || hasAttr() || - hasAttr() || - getType()->getAs()->getNoReturnAttr(); + bool HasNoReturnAttr = hasAttr() || hasAttr() + || hasAttr(); + const auto *FuncType = getType()->getAs(); + bool TypeHasNoReturnAttr = false; + if (FuncType) +TypeHasNoReturnAttr = FuncType->getNoReturnAttr(); + return HasNoReturnAttr || TypeHasNoReturnAttr; } void Index: test/Frontend/dinoreturn.m === --- /dev/null +++ test/Frontend/dinoreturn.m @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +__attribute__ ((noreturn)) void f() { + exit(0); +} Index: test/Frontend/dinoreturn.cpp === --- /dev/null +++ test/Frontend/dinoreturn.cpp @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -std=c++11 -x c++ -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +[[ noreturn ]] void f() { + throw 1; +} Index: test/Frontend/dinoreturn.c === --- /dev/null +++ test/Frontend/dinoreturn.c @@ -0,0 +1,6 @@ +// RUN: %clang %s -c -std=c11 -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +#include +_Noreturn void f() { + exit(0); +} Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2641,6 +2641,9 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } +// Check if it is a noreturn-marked function +if (FD->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2657,9 +2657,13 @@ } bool FunctionDecl::isNoReturn() const { - return hasAttr() || hasAttr() || - hasAttr() || - getType()->getAs()->getNoReturnAttr(); + bool HasNoReturnAttr = hasAttr() || hasAttr() + || hasAttr(); + const auto *FuncType = getType()->getAs(); + bool TypeHasNoReturnAttr = false; + if (FuncType) +TypeHasNoReturnAttr = FuncType->getNoReturnAttr(); + return HasNoReturnAttr || TypeHasNoReturnAttr; } void ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 68327. vleschuk marked an inline comment as done. vleschuk added a comment. Added test for noreturn flag for test/Assembler/disubprogram.ll https://reviews.llvm.org/D23167 Files: include/llvm/IR/DebugInfoFlags.def include/llvm/IR/DebugInfoMetadata.h include/llvm/Support/Dwarf.h lib/CodeGen/AsmPrinter/DwarfUnit.cpp lib/Support/Dwarf.cpp test/Assembler/disubprogram.ll test/DebugInfo/noreturn_c11.ll test/DebugInfo/noreturn_cpp11.ll test/DebugInfo/noreturn_objc.ll unittests/IR/DebugInfoTest.cpp Index: unittests/IR/DebugInfoTest.cpp === --- unittests/IR/DebugInfoTest.cpp +++ unittests/IR/DebugInfoTest.cpp @@ -73,8 +73,9 @@ CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u); unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector}; CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u); - CHECK_SPLIT(0x10u, {}, 0x10u); - CHECK_SPLIT(0x10u | DINode::FlagVector, {DINode::FlagVector}, 0x10u); + CHECK_SPLIT(0x20u, {}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagVector, {DINode::FlagVector}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagNoReturn, {DINode::FlagNoReturn}, 0x20u); #undef CHECK_SPLIT } Index: test/DebugInfo/noreturn_objc.ll === --- /dev/null +++ test/DebugInfo/noreturn_objc.ll @@ -0,0 +1,52 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c --emit-llvm -g from the following ObjC source: +; #include +; __attribute__ ((noreturn)) void f() +; { +; exit(0); +; } + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"f" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_noreturn + +; ModuleID = './test.m' +source_filename = "./test.m" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noreturn +define void @f() #0 !dbg !6 { +entry: + call void @exit(i32 0) #2, !dbg !10 + unreachable, !dbg !10 + +return: ; No predecessors! + ret void, !dbg !11 +} + +; Function Attrs: noreturn +declare void @exit(i32) #1 + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.m", directory: "/home/del/test/noreturn/objc") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)"} +!6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagNoReturn, isOptimized: false, unit: !0, variables: !2) +!7 = !DIFile(filename: "./test.m", directory: "/home/del/test/noreturn/objc") +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 4, column: 3, scope: !6) +!11 = !DILocation(line: 5, column: 1, scope: !6) Index: test/DebugInfo/noreturn_cpp11.ll === --- /dev/null +++ test/DebugInfo/noreturn_cpp11.ll @@ -0,0 +1,57 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c -std=c++11 --emit-llvm -g from the following C++11 source: +; [[ noreturn ]] void f() { +; throw 1; +; } + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"f" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_noreturn + +; ModuleID = 'test.cpp' +source_filename = "test.cpp" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@_ZTIi = external constant i8* + +; Function Attrs: noreturn +define void @_Z1fv() #0 !dbg !6 { +entry: + %exception = call i8* @__cxa_allocate_exception(i64 4) #1, !dbg !9 + %0 = bitcast i8* %exception to i32*, !dbg !9 + store i32 1, i32* %0, align 16, !dbg !9 + call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2, !dbg !10 + unreachable, !dbg !9 + +return: ; No predecessors! + ret void, !dbg !12 +} + +declare i8* @__cxa_allocate_exception(i64) + +declare void @__cxa_throw(i8*, i8*, i8*) + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 68328. vleschuk added a comment. Full context https://reviews.llvm.org/D23167 Files: include/llvm/IR/DebugInfoFlags.def include/llvm/IR/DebugInfoMetadata.h include/llvm/Support/Dwarf.h lib/CodeGen/AsmPrinter/DwarfUnit.cpp lib/Support/Dwarf.cpp test/Assembler/disubprogram.ll test/DebugInfo/noreturn_c11.ll test/DebugInfo/noreturn_cpp11.ll test/DebugInfo/noreturn_objc.ll unittests/IR/DebugInfoTest.cpp Index: unittests/IR/DebugInfoTest.cpp === --- unittests/IR/DebugInfoTest.cpp +++ unittests/IR/DebugInfoTest.cpp @@ -73,8 +73,9 @@ CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u); unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector}; CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u); - CHECK_SPLIT(0x10u, {}, 0x10u); - CHECK_SPLIT(0x10u | DINode::FlagVector, {DINode::FlagVector}, 0x10u); + CHECK_SPLIT(0x20u, {}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagVector, {DINode::FlagVector}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagNoReturn, {DINode::FlagNoReturn}, 0x20u); #undef CHECK_SPLIT } Index: test/DebugInfo/noreturn_objc.ll === --- /dev/null +++ test/DebugInfo/noreturn_objc.ll @@ -0,0 +1,52 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c --emit-llvm -g from the following ObjC source: +; #include +; __attribute__ ((noreturn)) void f() +; { +; exit(0); +; } + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"f" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_noreturn + +; ModuleID = './test.m' +source_filename = "./test.m" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noreturn +define void @f() #0 !dbg !6 { +entry: + call void @exit(i32 0) #2, !dbg !10 + unreachable, !dbg !10 + +return: ; No predecessors! + ret void, !dbg !11 +} + +; Function Attrs: noreturn +declare void @exit(i32) #1 + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.m", directory: "/home/del/test/noreturn/objc") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)"} +!6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagNoReturn, isOptimized: false, unit: !0, variables: !2) +!7 = !DIFile(filename: "./test.m", directory: "/home/del/test/noreturn/objc") +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 4, column: 3, scope: !6) +!11 = !DILocation(line: 5, column: 1, scope: !6) Index: test/DebugInfo/noreturn_cpp11.ll === --- /dev/null +++ test/DebugInfo/noreturn_cpp11.ll @@ -0,0 +1,57 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c -std=c++11 --emit-llvm -g from the following C++11 source: +; [[ noreturn ]] void f() { +; throw 1; +; } + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"f" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_noreturn + +; ModuleID = 'test.cpp' +source_filename = "test.cpp" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@_ZTIi = external constant i8* + +; Function Attrs: noreturn +define void @_Z1fv() #0 !dbg !6 { +entry: + %exception = call i8* @__cxa_allocate_exception(i64 4) #1, !dbg !9 + %0 = bitcast i8* %exception to i32*, !dbg !9 + store i32 1, i32* %0, align 16, !dbg !9 + call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2, !dbg !10 + unreachable, !dbg !9 + +return: ; No predecessors! + ret void, !dbg !12 +} + +declare i8* @__cxa_allocate_exception(i64) + +declare void @__cxa_throw(i8*, i8*, i8*) + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git
Re: [PATCH] D23168: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 68329. vleschuk marked an inline comment as done. vleschuk added a comment. Full context https://reviews.llvm.org/D23168 Files: lib/AST/Decl.cpp lib/CodeGen/CGDebugInfo.cpp test/Frontend/dinoreturn.c test/Frontend/dinoreturn.cpp test/Frontend/dinoreturn.m Index: test/Frontend/dinoreturn.m === --- /dev/null +++ test/Frontend/dinoreturn.m @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +__attribute__ ((noreturn)) void f() { + exit(0); +} Index: test/Frontend/dinoreturn.cpp === --- /dev/null +++ test/Frontend/dinoreturn.cpp @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -std=c++11 -x c++ -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +[[ noreturn ]] void f() { + throw 1; +} Index: test/Frontend/dinoreturn.c === --- /dev/null +++ test/Frontend/dinoreturn.c @@ -0,0 +1,6 @@ +// RUN: %clang %s -c -std=c11 -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +#include +_Noreturn void f() { + exit(0); +} Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2641,6 +2641,9 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } +// Check if it is a noreturn-marked function +if (FD->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2657,9 +2657,13 @@ } bool FunctionDecl::isNoReturn() const { - return hasAttr() || hasAttr() || - hasAttr() || - getType()->getAs()->getNoReturnAttr(); + bool HasNoReturnAttr = hasAttr() || hasAttr() + || hasAttr(); + const auto *FuncType = getType()->getAs(); + bool TypeHasNoReturnAttr = false; + if (FuncType) +TypeHasNoReturnAttr = FuncType->getNoReturnAttr(); + return HasNoReturnAttr || TypeHasNoReturnAttr; } void Index: test/Frontend/dinoreturn.m === --- /dev/null +++ test/Frontend/dinoreturn.m @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +__attribute__ ((noreturn)) void f() { + exit(0); +} Index: test/Frontend/dinoreturn.cpp === --- /dev/null +++ test/Frontend/dinoreturn.cpp @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -std=c++11 -x c++ -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +[[ noreturn ]] void f() { + throw 1; +} Index: test/Frontend/dinoreturn.c === --- /dev/null +++ test/Frontend/dinoreturn.c @@ -0,0 +1,6 @@ +// RUN: %clang %s -c -std=c11 -emit-llvm -S -g -o - | FileCheck %s +// CHECK: !DISubprogram({{.*}}name: "f"{{.*}}flags:{{.*DIFlagNoReturn}} +#include +_Noreturn void f() { + exit(0); +} Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2641,6 +2641,9 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } +// Check if it is a noreturn-marked function +if (FD->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2657,9 +2657,13 @@ } bool FunctionDecl::isNoReturn() const { - return hasAttr() || hasAttr() || - hasAttr() || - getType()->getAs()->getNoReturnAttr(); + bool HasNoReturnAttr = hasAttr() || hasAttr() + || hasAttr(); + const auto *FuncType = getType()->getAs(); + bool TypeHasNoReturnAttr = false; + if (FuncType) +TypeHasNoReturnAttr = FuncType->getNoReturnAttr(); + return HasNoReturnAttr || TypeHasNoReturnAttr; } void ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 68330. vleschuk added a comment. Full context https://reviews.llvm.org/D23167 Files: include/llvm/IR/DebugInfoFlags.def include/llvm/IR/DebugInfoMetadata.h include/llvm/Support/Dwarf.h lib/CodeGen/AsmPrinter/DwarfUnit.cpp lib/Support/Dwarf.cpp test/Assembler/disubprogram.ll test/DebugInfo/noreturn_c11.ll test/DebugInfo/noreturn_cpp11.ll test/DebugInfo/noreturn_objc.ll unittests/IR/DebugInfoTest.cpp Index: unittests/IR/DebugInfoTest.cpp === --- unittests/IR/DebugInfoTest.cpp +++ unittests/IR/DebugInfoTest.cpp @@ -73,8 +73,9 @@ CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u); unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector}; CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u); - CHECK_SPLIT(0x10u, {}, 0x10u); - CHECK_SPLIT(0x10u | DINode::FlagVector, {DINode::FlagVector}, 0x10u); + CHECK_SPLIT(0x20u, {}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagVector, {DINode::FlagVector}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagNoReturn, {DINode::FlagNoReturn}, 0x20u); #undef CHECK_SPLIT } Index: test/DebugInfo/noreturn_objc.ll === --- /dev/null +++ test/DebugInfo/noreturn_objc.ll @@ -0,0 +1,52 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c --emit-llvm -g from the following ObjC source: +; #include +; __attribute__ ((noreturn)) void f() +; { +; exit(0); +; } + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"f" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_noreturn + +; ModuleID = './test.m' +source_filename = "./test.m" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noreturn +define void @f() #0 !dbg !6 { +entry: + call void @exit(i32 0) #2, !dbg !10 + unreachable, !dbg !10 + +return: ; No predecessors! + ret void, !dbg !11 +} + +; Function Attrs: noreturn +declare void @exit(i32) #1 + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.m", directory: "/home/del/test/noreturn/objc") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)"} +!6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagNoReturn, isOptimized: false, unit: !0, variables: !2) +!7 = !DIFile(filename: "./test.m", directory: "/home/del/test/noreturn/objc") +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 4, column: 3, scope: !6) +!11 = !DILocation(line: 5, column: 1, scope: !6) Index: test/DebugInfo/noreturn_cpp11.ll === --- /dev/null +++ test/DebugInfo/noreturn_cpp11.ll @@ -0,0 +1,57 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c -std=c++11 --emit-llvm -g from the following C++11 source: +; [[ noreturn ]] void f() { +; throw 1; +; } + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"f" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_noreturn + +; ModuleID = 'test.cpp' +source_filename = "test.cpp" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@_ZTIi = external constant i8* + +; Function Attrs: noreturn +define void @_Z1fv() #0 !dbg !6 { +entry: + %exception = call i8* @__cxa_allocate_exception(i64 4) #1, !dbg !9 + %0 = bitcast i8* %exception to i32*, !dbg !9 + store i32 1, i32* %0, align 16, !dbg !9 + call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2, !dbg !10 + unreachable, !dbg !9 + +return: ; No predecessors! + ret void, !dbg !12 +} + +declare i8* @__cxa_allocate_exception(i64) + +declare void @__cxa_throw(i8*, i8*, i8*) + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk marked 2 inline comments as done. vleschuk added a comment. Replied on doxygen-related comment: I do not think we should use different styles within one file. https://reviews.llvm.org/D23167 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23168: emit_DW_AT_noreturn flag
vleschuk added a comment. Could somebody take a look at it and commit if no ojections? https://reviews.llvm.org/D23168 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk added a comment. Could somebody commit this, please? https://reviews.llvm.org/D23167 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D23767: DebugInfo: use llvm::di_flags_t for debug info flags
vleschuk created this revision. vleschuk added reviewers: echristo, aprantl. vleschuk added subscribers: llvm-commits, cfe-commits. Herald added a subscriber: mehdi_amini. Use llvm::di_flags_t type for debug flags instead of unsigned int to avoid problems on platforms with sizeof(int) < 4: we already have flags with values > (1 << 16). https://reviews.llvm.org/D23767 Files: include/llvm/IR/DIBuilder.h include/llvm/IR/DebugInfoMetadata.h lib/IR/DIBuilder.cpp lib/IR/DebugInfoMetadata.cpp Index: lib/IR/DebugInfoMetadata.cpp === --- lib/IR/DebugInfoMetadata.cpp +++ lib/IR/DebugInfoMetadata.cpp @@ -65,14 +65,14 @@ Storage, Context.pImpl->DILocations); } -unsigned DINode::getFlag(StringRef Flag) { - return StringSwitch(Flag) +di_flags_t DINode::getFlag(StringRef Flag) { + return StringSwitch(Flag) #define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME) #include "llvm/IR/DebugInfoFlags.def" .Default(0); } -const char *DINode::getFlagString(unsigned Flag) { +const char *DINode::getFlagString(di_flags_t Flag) { switch (Flag) { default: return ""; @@ -83,20 +83,20 @@ } } -unsigned DINode::splitFlags(unsigned Flags, -SmallVectorImpl &SplitFlags) { +di_flags_t DINode::splitFlags(di_flags_t Flags, +SmallVectorImpl &SplitFlags) { // Accessibility and member pointer flags need to be specially handled, since // they're packed together. - if (unsigned A = Flags & FlagAccessibility) { + if (di_flags_t A = Flags & FlagAccessibility) { if (A == FlagPrivate) SplitFlags.push_back(FlagPrivate); else if (A == FlagProtected) SplitFlags.push_back(FlagProtected); else SplitFlags.push_back(FlagPublic); Flags &= ~A; } - if (unsigned R = Flags & FlagPtrToMemberRep) { + if (di_flags_t R = Flags & FlagPtrToMemberRep) { if (R == FlagSingleInheritance) SplitFlags.push_back(FlagSingleInheritance); else if (R == FlagMultipleInheritance) @@ -107,7 +107,7 @@ } #define HANDLE_DI_FLAG(ID, NAME) \ - if (unsigned Bit = Flags & ID) { \ + if (di_flags_t Bit = Flags & ID) { \ SplitFlags.push_back(Bit); \ Flags &= ~Bit; \ } @@ -242,7 +242,7 @@ DIDerivedType *DIDerivedType::getImpl( LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, -uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, +uint64_t AlignInBits, uint64_t OffsetInBits, di_flags_t Flags, Metadata *ExtraData, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP(DIDerivedType, @@ -257,7 +257,7 @@ DICompositeType *DICompositeType::getImpl( LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, -uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, +uint64_t AlignInBits, uint64_t OffsetInBits, di_flags_t Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier, StorageType Storage, bool ShouldCreate) { @@ -279,7 +279,7 @@ LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, -unsigned Flags, Metadata *Elements, unsigned RuntimeLang, +di_flags_t Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) @@ -313,7 +313,7 @@ LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, -unsigned Flags, Metadata *Elements, unsigned RuntimeLang, +di_flags_t Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams) { assert(!Identifier.getString().empty() && "Expected valid identifier"); if (!Context.isODRUniquingDebugTypes()) @@ -336,7 +336,7 @@ } DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, -unsigned Flags, uint8_t CC, +di_flags_t Flags, uint8_t CC, Metadata *TypeArray,
Re: [PATCH] D23767: DebugInfo: use llvm::DIFlagsUnderlying type for debug info flags
vleschuk retitled this revision from "DebugInfo: use llvm::di_flags_t for debug info flags" to "DebugInfo: use llvm::DIFlagsUnderlying type for debug info flags". vleschuk updated the summary for this revision. vleschuk updated this revision to Diff 69332. vleschuk added a comment. Chnaged typedef name according to naming convention. https://reviews.llvm.org/D23767 Files: lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h Index: lib/CodeGen/CGDebugInfo.h === --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -517,7 +517,7 @@ StringRef &Name, StringRef &LinkageName, llvm::DIScope *&FDContext, llvm::DINodeArray &TParamsArray, -unsigned &Flags); +llvm::DIFlagsUnderlying &Flags); /// Collect various properties of a VarDecl. void collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit, Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -787,7 +787,7 @@ Elements = DBuilder.getOrCreateArray(EltTys); EltTys.clear(); - unsigned Flags = llvm::DINode::FlagAppleBlock; + llvm::DIFlagsUnderlying Flags = llvm::DINode::FlagAppleBlock; unsigned LineNo = 0; auto *EltTy = @@ -924,7 +924,7 @@ /// Convert an AccessSpecifier into the corresponding DINode flag. /// As an optimization, return 0 if the access specifier equals the /// default for the containing type. -static unsigned getAccessFlag(AccessSpecifier Access, const RecordDecl *RD) { +static llvm::DIFlagsUnderlying getAccessFlag(AccessSpecifier Access, const RecordDecl *RD) { AccessSpecifier Default = clang::AS_none; if (RD && RD->isClass()) Default = clang::AS_private; @@ -968,7 +968,7 @@ uint64_t StorageOffsetInBits = CGM.getContext().toBits(BitFieldInfo.StorageOffset); uint64_t OffsetInBits = StorageOffsetInBits + BitFieldInfo.Offset; - unsigned Flags = getAccessFlag(BitFieldDecl->getAccess(), RD); + llvm::DIFlagsUnderlying Flags = getAccessFlag(BitFieldDecl->getAccess(), RD); return DBuilder.createBitFieldMemberType( RecordTy, Name, File, Line, SizeInBits, AlignInBits, OffsetInBits, StorageOffsetInBits, Flags, DebugType); @@ -993,7 +993,7 @@ AlignInBits = TI.Align; } - unsigned flags = getAccessFlag(AS, RD); + llvm::DIFlagsUnderlying flags = getAccessFlag(AS, RD); return DBuilder.createMemberType(scope, name, file, line, SizeInBits, AlignInBits, offsetInBits, flags, debugType); } @@ -1060,7 +1060,7 @@ } } - unsigned Flags = getAccessFlag(Var->getAccess(), RD); + llvm::DIFlagsUnderlying Flags = getAccessFlag(Var->getAccess(), RD); llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( RecordTy, VName, VUnit, LineNumber, VTy, Flags, C); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); @@ -1203,7 +1203,7 @@ llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts); - unsigned Flags = 0; + llvm::DIFlagsUnderlying Flags = 0; if (Func->getExtProtoInfo().RefQualifier == RQ_LValue) Flags |= llvm::DINode::FlagLValueReference; if (Func->getExtProtoInfo().RefQualifier == RQ_RValue) @@ -1254,7 +1254,7 @@ llvm::DIType *ContainingType = nullptr; unsigned Virtuality = 0; unsigned VIndex = 0; - unsigned Flags = 0; + llvm::DIFlagsUnderlying Flags = 0; int ThisAdjustment = 0; if (Method->isVirtual()) { @@ -1367,7 +1367,7 @@ llvm::DIType *RecordTy) { const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); for (const auto &BI : RD->bases()) { -unsigned BFlags = 0; +llvm::DIFlagsUnderlying BFlags = 0; uint64_t BaseOffset; const auto *Base = @@ -1918,7 +1918,7 @@ uint64_t Size = CGM.getContext().getTypeSize(Ty); uint64_t Align = CGM.getContext().getTypeAlign(Ty); - unsigned Flags = 0; + llvm::DIFlagsUnderlying Flags = 0; if (ID->getImplementation()) Flags |= llvm::DINode::FlagObjcClassComplete; @@ -2026,7 +2026,7 @@ FieldOffset = RL.getFieldOffset(FieldNo); } -unsigned Flags = 0; +llvm::DIFlagsUnderlying Flags = 0; if (Field->getAccessControl() == ObjCIvarDecl::Protected) Flags = llvm::DINode::FlagProtected; else if (Field->getAccessControl() == ObjCIvarDecl::Private) @@ -2157,7 +2157,7 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty, llvm::DIFile *U) { - unsigned Flags = 0; + llvm::DIFlagsUnderlying Flags = 0; uint64_t Size = 0; if (!Ty->isIncompleteType()) { @@ -2633,7 +2633,7 @@ StringRef &LinkageName, llvm::DIScope *&
Re: [PATCH] D23767: DebugInfo: use llvm::DINode::DIFlags type for debug info flags
vleschuk retitled this revision from "DebugInfo: use llvm::DIFlagsUnderlying type for debug info flags" to "DebugInfo: use llvm::DINode::DIFlags type for debug info flags". vleschuk updated the summary for this revision. vleschuk updated this revision to Diff 69755. vleschuk added a comment. Switched to include/llvm/ADT/BitmaskEnum for debug info flags. https://reviews.llvm.org/D23767 Files: lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h Index: lib/CodeGen/CGDebugInfo.h === --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -517,7 +517,7 @@ StringRef &Name, StringRef &LinkageName, llvm::DIScope *&FDContext, llvm::DINodeArray &TParamsArray, -unsigned &Flags); +llvm::DINode::DIFlags &Flags); /// Collect various properties of a VarDecl. void collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit, Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -497,12 +497,12 @@ ObjTy = DBuilder.createStructType(TheCU, "objc_object", getOrCreateMainFile(), - 0, 0, 0, 0, nullptr, llvm::DINodeArray()); + 0, 0, 0, llvm::DINode::FlagZero, nullptr, llvm::DINodeArray()); DBuilder.replaceArrays( ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType( -ObjTy, "isa", getOrCreateMainFile(), 0, Size, 0, 0, 0, ISATy))); +ObjTy, "isa", getOrCreateMainFile(), 0, Size, 0, 0, llvm::DINode::FlagZero, ISATy))); return ObjTy; } case BuiltinType::ObjCSel: { @@ -787,7 +787,7 @@ Elements = DBuilder.getOrCreateArray(EltTys); EltTys.clear(); - unsigned Flags = llvm::DINode::FlagAppleBlock; + llvm::DINode::DIFlags Flags = llvm::DINode::FlagAppleBlock; unsigned LineNo = 0; auto *EltTy = @@ -813,7 +813,7 @@ FieldAlign = CGM.getContext().getTypeAlign(Ty); EltTys.push_back(DBuilder.createMemberType(Unit, "__descriptor", nullptr, LineNo, FieldSize, FieldAlign, FieldOffset, - 0, DescTy)); + llvm::DINode::FlagZero, DescTy)); FieldOffset += FieldSize; Elements = DBuilder.getOrCreateArray(EltTys); @@ -917,22 +917,22 @@ } llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(EltTys); - return DBuilder.createSubroutineType(EltTypeArray, 0, + return DBuilder.createSubroutineType(EltTypeArray, llvm::DINode::FlagZero, getDwarfCC(Ty->getCallConv())); } /// Convert an AccessSpecifier into the corresponding DINode flag. /// As an optimization, return 0 if the access specifier equals the /// default for the containing type. -static unsigned getAccessFlag(AccessSpecifier Access, const RecordDecl *RD) { +static llvm::DINode::DIFlags getAccessFlag(AccessSpecifier Access, const RecordDecl *RD) { AccessSpecifier Default = clang::AS_none; if (RD && RD->isClass()) Default = clang::AS_private; else if (RD && (RD->isStruct() || RD->isUnion())) Default = clang::AS_public; if (Access == Default) -return 0; +return llvm::DINode::FlagZero; switch (Access) { case clang::AS_private: @@ -942,7 +942,7 @@ case clang::AS_public: return llvm::DINode::FlagPublic; case clang::AS_none: -return 0; +return llvm::DINode::FlagZero; } llvm_unreachable("unexpected access enumerator"); } @@ -968,7 +968,7 @@ uint64_t StorageOffsetInBits = CGM.getContext().toBits(BitFieldInfo.StorageOffset); uint64_t OffsetInBits = StorageOffsetInBits + BitFieldInfo.Offset; - unsigned Flags = getAccessFlag(BitFieldDecl->getAccess(), RD); + llvm::DINode::DIFlags Flags = getAccessFlag(BitFieldDecl->getAccess(), RD); return DBuilder.createBitFieldMemberType( RecordTy, Name, File, Line, SizeInBits, AlignInBits, OffsetInBits, StorageOffsetInBits, Flags, DebugType); @@ -993,7 +993,7 @@ AlignInBits = TI.Align; } - unsigned flags = getAccessFlag(AS, RD); + llvm::DINode::DIFlags flags = getAccessFlag(AS, RD); return DBuilder.createMemberType(scope, name, file, line, SizeInBits, AlignInBits, offsetInBits, flags, debugType); } @@ -1060,7 +1060,7 @@ } } - unsigned Flags = getAccessFlag(Var->getAccess(), RD); + llvm::DINode::DIFlags Flags = getAccessFlag(Var->getAccess(), RD); llvm::DIDerivedType *GV = DBuilder.createStaticMemberType( RecordTy, VName, VUnit, LineNumber, VTy, Flags, C); StaticDataMemberCache[Var->getCanonicalDecl()].reset(GV); @@ -1203,7 +1203,7 @@ llvm::DITypeRefArray EltTypeAr
[PATCH] D23168: emit_DW_AT_noreturn flag
vleschuk created this revision. vleschuk added a reviewer: asl. vleschuk added a subscriber: cfe-commits. Emit DWARF DW_AT_noreturn for C++ [[ noreturn ]] and C _Noreturn specifiers. Corresponding LLVM patch: https://reviews.llvm.org/D23167 https://reviews.llvm.org/D23168 Files: lib/AST/Decl.cpp lib/CodeGen/CGDebugInfo.cpp Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2641,6 +2641,9 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } +// Check if it is a noreturn-marked function +if (FD->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2653,9 +2653,12 @@ } bool FunctionDecl::isNoReturn() const { - return hasAttr() || hasAttr() || - hasAttr() || - getType()->getAs()->getNoReturnAttr(); + bool HasNoReturnAttr = hasAttr() || hasAttr() || hasAttr(); + const auto *FuncType = getType()->getAs(); + bool TypeHasNoReturnAttr = false; + if (FuncType) +TypeHasNoReturnAttr = FuncType->getNoReturnAttr(); + return HasNoReturnAttr || TypeHasNoReturnAttr; } void Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2641,6 +2641,9 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } +// Check if it is a noreturn-marked function +if (FD->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2653,9 +2653,12 @@ } bool FunctionDecl::isNoReturn() const { - return hasAttr() || hasAttr() || - hasAttr() || - getType()->getAs()->getNoReturnAttr(); + bool HasNoReturnAttr = hasAttr() || hasAttr() || hasAttr(); + const auto *FuncType = getType()->getAs(); + bool TypeHasNoReturnAttr = false; + if (FuncType) +TypeHasNoReturnAttr = FuncType->getNoReturnAttr(); + return HasNoReturnAttr || TypeHasNoReturnAttr; } void ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk added reviewers: dexonsmith, echristo, aprantl. vleschuk added a subscriber: cfe-commits. vleschuk updated this revision to Diff 66822. vleschuk added a comment. Herald added a subscriber: mehdi_amini. Expanded context, added more reviewers who took part in this parts of code. https://reviews.llvm.org/D23167 Files: include/llvm/IR/DebugInfoFlags.def include/llvm/IR/DebugInfoMetadata.h include/llvm/Support/Dwarf.h lib/CodeGen/AsmPrinter/DwarfUnit.cpp lib/Support/Dwarf.cpp unittests/IR/DebugInfoTest.cpp Index: unittests/IR/DebugInfoTest.cpp === --- unittests/IR/DebugInfoTest.cpp +++ unittests/IR/DebugInfoTest.cpp @@ -73,8 +73,9 @@ CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u); unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector}; CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u); - CHECK_SPLIT(0x10u, {}, 0x10u); - CHECK_SPLIT(0x10u | DINode::FlagVector, {DINode::FlagVector}, 0x10u); + CHECK_SPLIT(0x20u, {}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagVector, {DINode::FlagVector}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagNoReturn, {DINode::FlagNoReturn}, 0x20u); #undef CHECK_SPLIT } Index: lib/Support/Dwarf.cpp === --- lib/Support/Dwarf.cpp +++ lib/Support/Dwarf.cpp @@ -147,6 +147,7 @@ case DW_AT_dwo_name: return "DW_AT_dwo_name"; case DW_AT_reference: return "DW_AT_reference"; case DW_AT_rvalue_reference: return "DW_AT_rvalue_reference"; + case DW_AT_noreturn: return "DW_AT_noreturn"; case DW_AT_MIPS_loop_begin:return "DW_AT_MIPS_loop_begin"; case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin"; case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin"; Index: lib/CodeGen/AsmPrinter/DwarfUnit.cpp === --- lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1248,6 +1248,9 @@ if (SP->isRValueReference()) addFlag(SPDie, dwarf::DW_AT_rvalue_reference); + if (SP->isNoReturn()) +addFlag(SPDie, dwarf::DW_AT_noreturn); + if (SP->isProtected()) addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1, dwarf::DW_ACCESS_protected); Index: include/llvm/Support/Dwarf.h === --- include/llvm/Support/Dwarf.h +++ include/llvm/Support/Dwarf.h @@ -197,6 +197,7 @@ DW_AT_reference = 0x77, DW_AT_rvalue_reference = 0x78, DW_AT_macros = 0x79, + DW_AT_noreturn = 0x87, DW_AT_lo_user = 0x2000, DW_AT_hi_user = 0x3fff, Index: include/llvm/IR/DebugInfoMetadata.h === --- include/llvm/IR/DebugInfoMetadata.h +++ include/llvm/IR/DebugInfoMetadata.h @@ -1419,6 +1419,13 @@ return getFlags() & FlagRValueReference; } + /// \brief Check if this is marked as noreturn + /// + /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn + unsigned isNoReturn() const { +return getFlags() & FlagNoReturn; + } + DIScopeRef getScope() const { return DIScopeRef(getRawScope()); } StringRef getName() const { return getStringOperand(2); } Index: include/llvm/IR/DebugInfoFlags.def === --- include/llvm/IR/DebugInfoFlags.def +++ include/llvm/IR/DebugInfoFlags.def @@ -38,5 +38,6 @@ HANDLE_DI_FLAG((3 << 16), VirtualInheritance) HANDLE_DI_FLAG((1 << 18), IntroducedVirtual) HANDLE_DI_FLAG((1 << 19), BitField) +HANDLE_DI_FLAG((1 << 20), NoReturn) #undef HANDLE_DI_FLAG Index: unittests/IR/DebugInfoTest.cpp === --- unittests/IR/DebugInfoTest.cpp +++ unittests/IR/DebugInfoTest.cpp @@ -73,8 +73,9 @@ CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u); unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector}; CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u); - CHECK_SPLIT(0x10u, {}, 0x10u); - CHECK_SPLIT(0x10u | DINode::FlagVector, {DINode::FlagVector}, 0x10u); + CHECK_SPLIT(0x20u, {}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagVector, {DINode::FlagVector}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagNoReturn, {DINode::FlagNoReturn}, 0x20u); #undef CHECK_SPLIT } Index: lib/Support/Dwarf.cpp === --- lib/Support/Dwarf.cpp +++ lib/Support/Dwarf.cpp @@ -147,6 +147,7 @@ case DW_AT_dwo_name: return "DW_AT_dwo_name"; case DW_AT_reference: return "DW_AT_reference"; case DW_AT_rvalue_reference: return "DW_AT_rvalue_reference"; + case
Re: [PATCH] D23168: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 66825. vleschuk added a comment. More context. Slight formatting changes. https://reviews.llvm.org/D23168 Files: lib/AST/Decl.cpp lib/CodeGen/CGDebugInfo.cpp Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2641,6 +2641,9 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } +// Check if it is a noreturn-marked function +if (FD->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2653,9 +2653,13 @@ } bool FunctionDecl::isNoReturn() const { - return hasAttr() || hasAttr() || - hasAttr() || - getType()->getAs()->getNoReturnAttr(); + bool HasNoReturnAttr = hasAttr() || hasAttr() + || hasAttr(); + const auto *FuncType = getType()->getAs(); + bool TypeHasNoReturnAttr = false; + if (FuncType) +TypeHasNoReturnAttr = FuncType->getNoReturnAttr(); + return HasNoReturnAttr || TypeHasNoReturnAttr; } void Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2641,6 +2641,9 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } +// Check if it is a noreturn-marked function +if (FD->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2653,9 +2653,13 @@ } bool FunctionDecl::isNoReturn() const { - return hasAttr() || hasAttr() || - hasAttr() || - getType()->getAs()->getNoReturnAttr(); + bool HasNoReturnAttr = hasAttr() || hasAttr() + || hasAttr(); + const auto *FuncType = getType()->getAs(); + bool TypeHasNoReturnAttr = false; + if (FuncType) +TypeHasNoReturnAttr = FuncType->getNoReturnAttr(); + return HasNoReturnAttr || TypeHasNoReturnAttr; } void ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 67212. vleschuk added a comment. Added C++11, C11 and ObjC textual llvm-dwarfdump tests. https://reviews.llvm.org/D23167 Files: include/llvm/IR/DebugInfoFlags.def include/llvm/IR/DebugInfoMetadata.h include/llvm/Support/Dwarf.h lib/CodeGen/AsmPrinter/DwarfUnit.cpp lib/Support/Dwarf.cpp test/DebugInfo/noreturn_c11.ll test/DebugInfo/noreturn_cpp11.ll test/DebugInfo/noreturn_objc.ll unittests/IR/DebugInfoTest.cpp Index: unittests/IR/DebugInfoTest.cpp === --- unittests/IR/DebugInfoTest.cpp +++ unittests/IR/DebugInfoTest.cpp @@ -73,8 +73,9 @@ CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u); unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector}; CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u); - CHECK_SPLIT(0x10u, {}, 0x10u); - CHECK_SPLIT(0x10u | DINode::FlagVector, {DINode::FlagVector}, 0x10u); + CHECK_SPLIT(0x20u, {}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagVector, {DINode::FlagVector}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagNoReturn, {DINode::FlagNoReturn}, 0x20u); #undef CHECK_SPLIT } Index: test/DebugInfo/noreturn_objc.ll === --- /dev/null +++ test/DebugInfo/noreturn_objc.ll @@ -0,0 +1,50 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c --emit-llvm -g from the following ObjC source: +; #include +; __attribute__ ((noreturn)) void f() +; { +; exit(0); +; } + +; CHECK: DW_AT_noreturn + +; ModuleID = './test.m' +source_filename = "./test.m" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noreturn nounwind uwtable +define void @f() #0 !dbg !6 { +entry: + call void @exit(i32 0) #2, !dbg !10 + unreachable, !dbg !10 + +return: ; No predecessors! + ret void, !dbg !11 +} + +; Function Attrs: noreturn nounwind +declare void @exit(i32) #1 + +attributes #0 = { noreturn nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { noreturn nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { noreturn nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.m", directory: "/home/del/test/noreturn/objc") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)"} +!6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagNoReturn, isOptimized: false, unit: !0, variables: !2) +!7 = !DIFile(filename: "./test.m", directory: "/home/del/test/noreturn/objc") +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 4, column: 3, scope: !6) +!11 = !DILocation(line: 5, column: 1, scope: !6) Index: test/DebugInfo/noreturn_cpp11.ll === --- /dev/null +++ test/DebugInfo/noreturn_cpp11.ll @@ -0,0 +1,56 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c -std=c++11 --emit-llvm -g from the following C++11 source: +; [[ noreturn ]] void f() { +; throw 1; +; } + +; CHECK: DW_AT_noreturn + + +; ModuleID = 'test.cpp' +source_filename = "test.cpp" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@_ZTIi = external constant i8* + +; Function Attrs: noreturn uwtable +define void @_Z1fv() #0 !d
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 67398. vleschuk marked 6 inline comments as done. vleschuk added a comment. Stripped unnecessary attributes, added more context to CHECK https://reviews.llvm.org/D23167 Files: include/llvm/IR/DebugInfoFlags.def include/llvm/IR/DebugInfoMetadata.h include/llvm/Support/Dwarf.h lib/CodeGen/AsmPrinter/DwarfUnit.cpp lib/Support/Dwarf.cpp test/DebugInfo/noreturn_c11.ll test/DebugInfo/noreturn_cpp11.ll test/DebugInfo/noreturn_objc.ll unittests/IR/DebugInfoTest.cpp Index: unittests/IR/DebugInfoTest.cpp === --- unittests/IR/DebugInfoTest.cpp +++ unittests/IR/DebugInfoTest.cpp @@ -73,8 +73,9 @@ CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u); unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector}; CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u); - CHECK_SPLIT(0x10u, {}, 0x10u); - CHECK_SPLIT(0x10u | DINode::FlagVector, {DINode::FlagVector}, 0x10u); + CHECK_SPLIT(0x20u, {}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagVector, {DINode::FlagVector}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagNoReturn, {DINode::FlagNoReturn}, 0x20u); #undef CHECK_SPLIT } Index: test/DebugInfo/noreturn_objc.ll === --- /dev/null +++ test/DebugInfo/noreturn_objc.ll @@ -0,0 +1,49 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c --emit-llvm -g from the following ObjC source: +; #include +; __attribute__ ((noreturn)) void f() +; { +; exit(0); +; } + +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_noreturn + +; ModuleID = './test.m' +source_filename = "./test.m" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noreturn +define void @f() #0 !dbg !6 { +entry: + call void @exit(i32 0) #2, !dbg !10 + unreachable, !dbg !10 + +return: ; No predecessors! + ret void, !dbg !11 +} + +; Function Attrs: noreturn +declare void @exit(i32) #1 + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.m", directory: "/home/del/test/noreturn/objc") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)"} +!6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagNoReturn, isOptimized: false, unit: !0, variables: !2) +!7 = !DIFile(filename: "./test.m", directory: "/home/del/test/noreturn/objc") +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 4, column: 3, scope: !6) +!11 = !DILocation(line: 5, column: 1, scope: !6) Index: test/DebugInfo/noreturn_cpp11.ll === --- /dev/null +++ test/DebugInfo/noreturn_cpp11.ll @@ -0,0 +1,55 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c -std=c++11 --emit-llvm -g from the following C++11 source: +; [[ noreturn ]] void f() { +; throw 1; +; } + +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_noreturn + + +; ModuleID = 'test.cpp' +source_filename = "test.cpp" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@_ZTIi = external constant i8* + +; Function Attrs: noreturn +define void @_Z1fv() #0 !dbg !6 { +entry: + %exception = call i8* @__cxa_allocate_exception(i64 4) #1, !dbg !9 + %0 = bitcast i8* %exception to i32*, !dbg !9 + store i32 1, i32* %0, align 16, !dbg !9 + call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2, !dbg !10 + unreachable, !dbg !9 + +return: ; No predecessors! + ret void, !dbg !12 +} + +declare i8* @__cxa_allocate_exception(i64) + +declare void @__cxa_throw(i8*, i8*, i8*) + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeec
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 67410. vleschuk added a comment. Added more tests https://reviews.llvm.org/D23167 Files: include/llvm/IR/DebugInfoFlags.def include/llvm/IR/DebugInfoMetadata.h include/llvm/Support/Dwarf.h lib/CodeGen/AsmPrinter/DwarfUnit.cpp lib/Support/Dwarf.cpp test/DebugInfo/noreturn_c11.ll test/DebugInfo/noreturn_cpp11.ll test/DebugInfo/noreturn_objc.ll unittests/IR/DebugInfoTest.cpp Index: unittests/IR/DebugInfoTest.cpp === --- unittests/IR/DebugInfoTest.cpp +++ unittests/IR/DebugInfoTest.cpp @@ -73,8 +73,9 @@ CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u); unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector}; CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u); - CHECK_SPLIT(0x10u, {}, 0x10u); - CHECK_SPLIT(0x10u | DINode::FlagVector, {DINode::FlagVector}, 0x10u); + CHECK_SPLIT(0x20u, {}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagVector, {DINode::FlagVector}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagNoReturn, {DINode::FlagNoReturn}, 0x20u); #undef CHECK_SPLIT } Index: test/DebugInfo/noreturn_objc.ll === --- /dev/null +++ test/DebugInfo/noreturn_objc.ll @@ -0,0 +1,52 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c --emit-llvm -g from the following ObjC source: +; #include +; __attribute__ ((noreturn)) void f() +; { +; exit(0); +; } + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"f" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_noreturn + +; ModuleID = './test.m' +source_filename = "./test.m" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noreturn +define void @f() #0 !dbg !6 { +entry: + call void @exit(i32 0) #2, !dbg !10 + unreachable, !dbg !10 + +return: ; No predecessors! + ret void, !dbg !11 +} + +; Function Attrs: noreturn +declare void @exit(i32) #1 + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.m", directory: "/home/del/test/noreturn/objc") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)"} +!6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagNoReturn, isOptimized: false, unit: !0, variables: !2) +!7 = !DIFile(filename: "./test.m", directory: "/home/del/test/noreturn/objc") +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 4, column: 3, scope: !6) +!11 = !DILocation(line: 5, column: 1, scope: !6) Index: test/DebugInfo/noreturn_cpp11.ll === --- /dev/null +++ test/DebugInfo/noreturn_cpp11.ll @@ -0,0 +1,57 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c -std=c++11 --emit-llvm -g from the following C++11 source: +; [[ noreturn ]] void f() { +; throw 1; +; } + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"f" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_noreturn + +; ModuleID = 'test.cpp' +source_filename = "test.cpp" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@_ZTIi = external constant i8* + +; Function Attrs: noreturn +define void @_Z1fv() #0 !dbg !6 { +entry: + %exception = call i8* @__cxa_allocate_exception(i64 4) #1, !dbg !9 + %0 = bitcast i8* %exception to i32*, !dbg !9 + store i32 1, i32* %0, align 16, !dbg !9 + call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2, !dbg !10 + unreachable, !dbg !9 + +return: ; No predecessors! + ret void, !dbg !12 +} + +declare i8* @__cxa_allocate_exception(i64) + +declare void @__cxa_throw(i8*, i8*, i8*) + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09f
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk added a comment. In https://reviews.llvm.org/D23167#510379, @aprantl wrote: > Found one more. Done Comment at: include/llvm/IR/DebugInfoMetadata.h:1424 @@ +1423,3 @@ + /// + /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn + unsigned isNoReturn() const { Just following the pattern in file. Added dot. https://reviews.llvm.org/D23167 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk added a comment. Could somebody commit this, please? I do not have the commit permissions yet. https://reviews.llvm.org/D23167 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 67462. vleschuk added a comment. Stripped more unnecessary code. And cosmetics: trailing spaces. https://reviews.llvm.org/D23167 Files: include/llvm/IR/DebugInfoFlags.def include/llvm/IR/DebugInfoMetadata.h include/llvm/Support/Dwarf.h lib/CodeGen/AsmPrinter/DwarfUnit.cpp lib/Support/Dwarf.cpp test/DebugInfo/noreturn_c11.ll test/DebugInfo/noreturn_cpp11.ll test/DebugInfo/noreturn_objc.ll unittests/IR/DebugInfoTest.cpp Index: unittests/IR/DebugInfoTest.cpp === --- unittests/IR/DebugInfoTest.cpp +++ unittests/IR/DebugInfoTest.cpp @@ -73,8 +73,9 @@ CHECK_SPLIT(DINode::FlagRValueReference, {DINode::FlagRValueReference}, 0u); unsigned Flags[] = {DINode::FlagFwdDecl, DINode::FlagVector}; CHECK_SPLIT(DINode::FlagFwdDecl | DINode::FlagVector, Flags, 0u); - CHECK_SPLIT(0x10u, {}, 0x10u); - CHECK_SPLIT(0x10u | DINode::FlagVector, {DINode::FlagVector}, 0x10u); + CHECK_SPLIT(0x20u, {}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagVector, {DINode::FlagVector}, 0x20u); + CHECK_SPLIT(0x20u | DINode::FlagNoReturn, {DINode::FlagNoReturn}, 0x20u); #undef CHECK_SPLIT } Index: test/DebugInfo/noreturn_objc.ll === --- /dev/null +++ test/DebugInfo/noreturn_objc.ll @@ -0,0 +1,52 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c --emit-llvm -g from the following ObjC source: +; #include +; __attribute__ ((noreturn)) void f() +; { +; exit(0); +; } + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"f" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_noreturn + +; ModuleID = './test.m' +source_filename = "./test.m" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noreturn +define void @f() #0 !dbg !6 { +entry: + call void @exit(i32 0) #2, !dbg !10 + unreachable, !dbg !10 + +return: ; No predecessors! + ret void, !dbg !11 +} + +; Function Attrs: noreturn +declare void @exit(i32) #1 + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, file: !1, producer: "clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)", isOptimized: false, runtimeVersion: 1, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.m", directory: "/home/del/test/noreturn/objc") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{!"clang version 4.0.0 (http://llvm.org/git/clang.git 08946d46f2add8cb241fdc09fc3731dd9dc5ecb5) (http://llvm.org/git/llvm.git d048aeecd34b8c336d1fd44e36c15b0b11c2ea4d)"} +!6 = distinct !DISubprogram(name: "f", scope: !7, file: !7, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagNoReturn, isOptimized: false, unit: !0, variables: !2) +!7 = !DIFile(filename: "./test.m", directory: "/home/del/test/noreturn/objc") +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 4, column: 3, scope: !6) +!11 = !DILocation(line: 5, column: 1, scope: !6) Index: test/DebugInfo/noreturn_cpp11.ll === --- /dev/null +++ test/DebugInfo/noreturn_cpp11.ll @@ -0,0 +1,57 @@ +; RUN: %llc_dwarf -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s +; REQUIRES: object-emission + +; Generated by clang++ -S -c -std=c++11 --emit-llvm -g from the following C++11 source: +; [[ noreturn ]] void f() { +; throw 1; +; } + +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}"f" +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_noreturn + +; ModuleID = 'test.cpp' +source_filename = "test.cpp" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@_ZTIi = external constant i8* + +; Function Attrs: noreturn +define void @_Z1fv() #0 !dbg !6 { +entry: + %exception = call i8* @__cxa_allocate_exception(i64 4) #1, !dbg !9 + %0 = bitcast i8* %exception to i32*, !dbg !9 + store i32 1, i32* %0, align 16, !dbg !9 + call void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #2, !dbg !10 + unreachable, !dbg !9 + +return: ; No predecessors! + ret void, !dbg !12 +} + +declare i8* @__cxa_allocate_exception(i64) + +declare void @__cxa_throw(i8*, i8*, i8*) + +attributes #0 = { noreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} +!llvm.ident = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 4.0.0 (http://ll
Re: [PATCH] D23167: emit_DW_AT_noreturn flag
vleschuk added a comment. In https://reviews.llvm.org/D23167#510485, @aprantl wrote: > Did you forget to add the IR test before uploading the patch? Could you please clarify, what do you mean? All the IR tests are here now. https://reviews.llvm.org/D23167 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D23168: emit_DW_AT_noreturn flag
vleschuk updated this revision to Diff 67694. vleschuk added a comment. Add IR tests https://reviews.llvm.org/D23168 Files: lib/AST/Decl.cpp lib/CodeGen/CGDebugInfo.cpp test/Frontend/dinoreturn.c test/Frontend/dinoreturn.cpp test/Frontend/dinoreturn.m Index: test/Frontend/dinoreturn.m === --- /dev/null +++ test/Frontend/dinoreturn.m @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -emit-llvm -S -g -o - | FileCheck %s +// CHECK: DIFlagNoReturn +__attribute__ ((noreturn)) void f() { + exit(0); +} Index: test/Frontend/dinoreturn.cpp === --- /dev/null +++ test/Frontend/dinoreturn.cpp @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -std=c++11 -x c++ -emit-llvm -S -g -o - | FileCheck %s +// CHECK: DIFlagNoReturn +[[ noreturn ]] void f() { + throw 1; +} Index: test/Frontend/dinoreturn.c === --- /dev/null +++ test/Frontend/dinoreturn.c @@ -0,0 +1,6 @@ +// RUN: %clang %s -c -std=c11 -emit-llvm -S -g -o - | FileCheck %s +// CHECK: DIFlagNoReturn +#include +_Noreturn void f() { + exit(0); +} Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2641,6 +2641,9 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } +// Check if it is a noreturn-marked function +if (FD->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2653,9 +2653,13 @@ } bool FunctionDecl::isNoReturn() const { - return hasAttr() || hasAttr() || - hasAttr() || - getType()->getAs()->getNoReturnAttr(); + bool HasNoReturnAttr = hasAttr() || hasAttr() + || hasAttr(); + const auto *FuncType = getType()->getAs(); + bool TypeHasNoReturnAttr = false; + if (FuncType) +TypeHasNoReturnAttr = FuncType->getNoReturnAttr(); + return HasNoReturnAttr || TypeHasNoReturnAttr; } void Index: test/Frontend/dinoreturn.m === --- /dev/null +++ test/Frontend/dinoreturn.m @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -emit-llvm -S -g -o - | FileCheck %s +// CHECK: DIFlagNoReturn +__attribute__ ((noreturn)) void f() { + exit(0); +} Index: test/Frontend/dinoreturn.cpp === --- /dev/null +++ test/Frontend/dinoreturn.cpp @@ -0,0 +1,5 @@ +// RUN: %clang %s -c -std=c++11 -x c++ -emit-llvm -S -g -o - | FileCheck %s +// CHECK: DIFlagNoReturn +[[ noreturn ]] void f() { + throw 1; +} Index: test/Frontend/dinoreturn.c === --- /dev/null +++ test/Frontend/dinoreturn.c @@ -0,0 +1,6 @@ +// RUN: %clang %s -c -std=c11 -emit-llvm -S -g -o - | FileCheck %s +// CHECK: DIFlagNoReturn +#include +_Noreturn void f() { + exit(0); +} Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2641,6 +2641,9 @@ llvm::DIScope *Mod = getParentModuleOrNull(RDecl); FDContext = getContextDescriptor(RDecl, Mod ? Mod : TheCU); } +// Check if it is a noreturn-marked function +if (FD->isNoReturn()) + Flags |= llvm::DINode::FlagNoReturn; // Collect template parameters. TParamsArray = CollectFunctionTemplateParams(FD, Unit); } Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2653,9 +2653,13 @@ } bool FunctionDecl::isNoReturn() const { - return hasAttr() || hasAttr() || - hasAttr() || - getType()->getAs()->getNoReturnAttr(); + bool HasNoReturnAttr = hasAttr() || hasAttr() + || hasAttr(); + const auto *FuncType = getType()->getAs(); + bool TypeHasNoReturnAttr = false; + if (FuncType) +TypeHasNoReturnAttr = FuncType->getNoReturnAttr(); + return HasNoReturnAttr || TypeHasNoReturnAttr; } void ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-reset-call check (PR #121291)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/121291 >From 37dce6a7ed0cca2e9819c24f4d176c43e3c9f2ac Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 29 Dec 2024 15:32:22 +0300 Subject: [PATCH 1/3] [clang-tidy] Add bugprone-reset-call check --- .../bugprone/BugproneTidyModule.cpp | 2 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../clang-tidy/bugprone/ResetCallCheck.cpp| 133 +++ .../clang-tidy/bugprone/ResetCallCheck.h | 34 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../clang-tidy/checks/bugprone/reset-call.rst | 33 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/reset-call.cpp | 215 ++ 8 files changed, 425 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/reset-call.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/reset-call.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 33ac65e715ce81..645958e47e22a5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -57,6 +57,7 @@ #include "PosixReturnCheck.h" #include "RedundantBranchConditionCheck.h" #include "ReservedIdentifierCheck.h" +#include "ResetCallCheck.h" #include "ReturnConstRefFromParameterCheck.h" #include "SharedPtrArrayMismatchCheck.h" #include "SignalHandlerCheck.h" @@ -144,6 +145,7 @@ class BugproneModule : public ClangTidyModule { "bugprone-inaccurate-erase"); CheckFactories.registerCheck( "bugprone-incorrect-enable-if"); +CheckFactories.registerCheck("bugprone-reset-call"); CheckFactories.registerCheck( "bugprone-return-const-ref-from-parameter"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 13adad7c3dadbd..17ab5b27ec5550 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -52,6 +52,7 @@ add_clang_library(clangTidyBugproneModule STATIC PosixReturnCheck.cpp RedundantBranchConditionCheck.cpp ReservedIdentifierCheck.cpp + ResetCallCheck.cpp ReturnConstRefFromParameterCheck.cpp SharedPtrArrayMismatchCheck.cpp SignalHandlerCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp new file mode 100644 index 00..305ac8d51adf3e --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp @@ -0,0 +1,133 @@ +//===--- ResetCallCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ResetCallCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { + +AST_MATCHER_P(CallExpr, everyArgumentMatches, + ast_matchers::internal::Matcher, InnerMatcher) { + if (Node.getNumArgs() == 0) +return true; + + for (const auto *Arg : Node.arguments()) { +if (!InnerMatcher.matches(*Arg, Finder, Builder)) + return false; + } + return true; +} + +AST_MATCHER(CXXMethodDecl, hasOnlyDefaultArgs) { + if (Node.param_empty()) +return true; + + for (const auto *Param : Node.parameters()) { +if (!Param->hasDefaultArg()) + return false; + } + return true; +} + +} // namespace + +void ResetCallCheck::registerMatchers(MatchFinder *Finder) { + const auto IsSmartptr = hasAnyName("::std::unique_ptr", "::std::shared_ptr"); + + const auto ResetMethod = + cxxMethodDecl(hasName("reset"), hasOnlyDefaultArgs()); + + const auto TypeWithReset = + anyOf(cxxRecordDecl(hasMethod(ResetMethod)), +classTemplateSpecializationDecl( +hasSpecializedTemplate(classTemplateDecl(has(ResetMethod); + + const auto SmartptrWithBugproneReset = classTemplateSpecializationDecl( + IsSmartptr, + hasTemplateArgument( + 0, templateArgument(refersToType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(TypeWithReset))); + + // Find a.reset() calls + Finder->addMatcher( + cxxMemberCallExpr(callee(memberExpr(member(hasName("reset", +
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
@@ -0,0 +1,33 @@ +.. title:: clang-tidy - bugprone-reset-call + +bugprone-reset-call +=== + +Finds calls to ``reset()`` method on smart pointers where the pointee type vbvictor wrote: Done, also removed parentheses in ``reset`` to follow general style https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
vbvictor wrote: > 1. Consider TK_IgnoreUnlessSpelledInSource, may simplify matchers > 2. Name is too generic, consider: > > * bugprone-smartptr-reset-pointee-reset > * bugprone-smartptr-reset-call > * bugprone-smartptr-pointee-reset > * bugprone-smartptr-reset-ambiguous-call (my prefered) > > Or any simillar. 1. Could not find a way to use TK_IgnoreUnlessSpelledInSource because code in function `template void TemplatePositiveTest() {}` is implicitly instantiated for different template types, so it is being ignored by matchers with TK_IgnoreUnlessSpelledInSource. 2. Renamed check to bugprone-smartptr-reset-ambiguous-call. https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-reset-call check (PR #121291)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-reset-call check (PR #121291)
https://github.com/vbvictor created https://github.com/llvm/llvm-project/pull/121291 Add new clang-tidy check that finds potentially erroneous calls to ``reset()`` method on smart pointers when the pointee type also has a ``reset()`` method. It's easy to make typo and delete object because the difference between ``.`` and ``->`` is really small. Sometimes IDE's autocomplete will change ``->`` to ``.`` automatically. For example, developer wrote ``ptr->res`` but after _Tab_ it became ``ptr.reset()``. Small example: ```cpp struct Resettable { void reset() { /* Own reset logic */ } }; auto ptr = std::make_unique(); ptr->reset(); // Calls underlying reset method ptr.reset(); // Makes the pointer null // After Fix-its (*ptr).reset(); // Clearly calls underlying reset method ptr = nullptr; // Clearly makes the pointer null ``` >From 37dce6a7ed0cca2e9819c24f4d176c43e3c9f2ac Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 29 Dec 2024 15:32:22 +0300 Subject: [PATCH] [clang-tidy] Add bugprone-reset-call check --- .../bugprone/BugproneTidyModule.cpp | 2 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../clang-tidy/bugprone/ResetCallCheck.cpp| 133 +++ .../clang-tidy/bugprone/ResetCallCheck.h | 34 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../clang-tidy/checks/bugprone/reset-call.rst | 33 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/reset-call.cpp | 215 ++ 8 files changed, 425 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/reset-call.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/reset-call.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 33ac65e715ce81..645958e47e22a5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -57,6 +57,7 @@ #include "PosixReturnCheck.h" #include "RedundantBranchConditionCheck.h" #include "ReservedIdentifierCheck.h" +#include "ResetCallCheck.h" #include "ReturnConstRefFromParameterCheck.h" #include "SharedPtrArrayMismatchCheck.h" #include "SignalHandlerCheck.h" @@ -144,6 +145,7 @@ class BugproneModule : public ClangTidyModule { "bugprone-inaccurate-erase"); CheckFactories.registerCheck( "bugprone-incorrect-enable-if"); +CheckFactories.registerCheck("bugprone-reset-call"); CheckFactories.registerCheck( "bugprone-return-const-ref-from-parameter"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 13adad7c3dadbd..17ab5b27ec5550 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -52,6 +52,7 @@ add_clang_library(clangTidyBugproneModule STATIC PosixReturnCheck.cpp RedundantBranchConditionCheck.cpp ReservedIdentifierCheck.cpp + ResetCallCheck.cpp ReturnConstRefFromParameterCheck.cpp SharedPtrArrayMismatchCheck.cpp SignalHandlerCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp new file mode 100644 index 00..305ac8d51adf3e --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp @@ -0,0 +1,133 @@ +//===--- ResetCallCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ResetCallCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { + +AST_MATCHER_P(CallExpr, everyArgumentMatches, + ast_matchers::internal::Matcher, InnerMatcher) { + if (Node.getNumArgs() == 0) +return true; + + for (const auto *Arg : Node.arguments()) { +if (!InnerMatcher.matches(*Arg, Finder, Builder)) + return false; + } + return true; +} + +AST_MATCHER(CXXMethodDecl, hasOnlyDefaultArgs) { + if (Node.param_empty()) +return true; + + for (const auto *Param : Node.parameters()) { +if (!Param->hasDefaultArg()) + return false; + } + return true; +} + +} // namespace + +void ResetCallCheck::registerMatchers(MatchFinder *Finder) { + const auto IsSmartptr
[clang-tools-extra] [clang-tidy] Add bugprone-reset-call check (PR #121291)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor closed https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
vbvictor wrote: > I think that this check is one that we don't want to emit fixes for, at least > not in the main diagnostic, but maybe as a fixit attached to a note > What do others think? https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor reopened https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
@@ -0,0 +1,34 @@ +//===--- SmartptrResetAmbiguousCallCheck.h - clang-tidy -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SMARTPTRRESETAMBIGUOUSCALLCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SMARTPTRRESETAMBIGUOUSCALLCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::bugprone { + +/// Finds potentially erroneous calls to 'reset' method on smart pointers when +/// the pointee type also has a 'reset' method +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.html +class SmartptrResetAmbiguousCallCheck : public ClangTidyCheck { +public: + SmartptrResetAmbiguousCallCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { +return LangOpts.CPlusPlus; vbvictor wrote: As for now, this check only matches `::std::unique_ptr` and `::std::shared_ptr`, so this comment is valid. In the future, I think a list of smartptr-like classes should be an option for check. https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
vbvictor wrote: Ping https://github.com/llvm/llvm-project/pull/123413 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/122951 >From 618f4a1707c1b62693c0e878040997154e7e35d6 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 14 Jan 2025 22:05:43 +0300 Subject: [PATCH 1/7] [clang-tidy] add AllowedTypes to misc-const-correctness --- .../clang-tidy/misc/ConstCorrectnessCheck.cpp | 18 +- .../clang-tidy/misc/ConstCorrectnessCheck.h | 2 + clang-tools-extra/docs/ReleaseNotes.rst | 5 + .../checks/misc/const-correctness.rst | 10 + .../misc/const-correctness-allowed-types.cpp | 180 ++ 5 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-allowed-types.cpp diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index 71a4cee4bdc6ef6..aee4a3b789863c0 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -8,6 +8,8 @@ #include "ConstCorrectnessCheck.h" #include "../utils/FixItHintUtils.h" +#include "../utils/Matchers.h" +#include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -41,7 +43,9 @@ ConstCorrectnessCheck::ConstCorrectnessCheck(StringRef Name, TransformValues(Options.get("TransformValues", true)), TransformReferences(Options.get("TransformReferences", true)), TransformPointersAsValues( - Options.get("TransformPointersAsValues", false)) { + Options.get("TransformPointersAsValues", false)), + AllowedTypes( + utils::options::parseStringList(Options.get("AllowedTypes", ""))) { if (AnalyzeValues == false && AnalyzeReferences == false) this->configurationDiag( "The check 'misc-const-correctness' will not " @@ -57,6 +61,9 @@ void ConstCorrectnessCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "TransformValues", TransformValues); Options.store(Opts, "TransformReferences", TransformReferences); Options.store(Opts, "TransformPointersAsValues", TransformPointersAsValues); + + Options.store(Opts, "AllowedTypes", +utils::options::serializeStringList(AllowedTypes)); } void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { @@ -73,6 +80,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType(), hasType(referenceType(pointee(substTemplateTypeParmType(); + const auto AllowedType = hasType(qualType(anyOf( + hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + pointerType(pointee(hasDeclaration( + namedDecl(matchers::matchesAnyListedName(AllowedTypes; + const auto AutoTemplateType = varDecl( anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType(, hasType(pointerType(pointee(autoType()); @@ -87,7 +100,8 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { unless(anyOf(ConstType, ConstReference, TemplateType, hasInitializer(isInstantiationDependent()), AutoTemplateType, RValueReference, FunctionPointerRef, - hasType(cxxRecordDecl(isLambda())), isImplicit(; + hasType(cxxRecordDecl(isLambda())), isImplicit(), + AllowedType))); // Match the function scope for which the analysis of all local variables // shall be run. diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h index bba060e555d001f..3b7aba7c4be384e 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h @@ -45,6 +45,8 @@ class ConstCorrectnessCheck : public ClangTidyCheck { const bool TransformValues; const bool TransformReferences; const bool TransformPointersAsValues; + + const std::vector AllowedTypes; }; } // namespace clang::tidy::misc diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 3bddeeda06e06b9..f57e951afc1ce05 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -101,6 +101,11 @@ Changes in existing checks ` check to allow specifying additional C++ member functions to match. +- Improved :doc:`misc-const-correctness + ` check by adding + the option ``AllowedTypes``, that excludes specified types + from const-correctness checking. + Removed checks ^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst b/clang-tools-extra/docs/
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/123413 >From 26c73cba1157bc538eb69c4ce11bba79c21ec3c6 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sat, 18 Jan 2025 00:49:29 +0300 Subject: [PATCH 1/4] [clang-tidy] Added support for 3-argument string ctor --- .../bugprone/StringConstructorCheck.cpp | 50 +-- clang-tools-extra/docs/ReleaseNotes.rst | 5 ++ .../checkers/bugprone/string-constructor.cpp | 30 +++ 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 8ae4351ac2830a9..d1902b658061b11 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -82,7 +82,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxConstructExpr( hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(0, hasType(qualType(isInteger(, + argumentCountIs(2), hasArgument(0, hasType(qualType(isInteger(, hasArgument(1, hasType(qualType(isInteger(, anyOf( // Detect the expression: string('x', 40); @@ -102,7 +102,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { cxxConstructExpr( hasDeclaration(cxxConstructorDecl(ofClass( cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), - hasArgument(0, hasType(CharPtrType)), + argumentCountIs(2), hasArgument(0, hasType(CharPtrType)), hasArgument(1, hasType(isInteger())), anyOf( // Detect the expression: string("...", 0); @@ -114,7 +114,34 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { // Detect the expression: string("lit", 5) allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), hasArgument(1, ignoringParenImpCasts( - integerLiteral().bind("int")) + integerLiteral().bind("length")) + .bind("constructor"), + this); + + // Check the literal string constructor with char pointer, start position and + // length parameters. [i.e. string (const char* s, size_t pos, size_t count);] + Finder->addMatcher( + cxxConstructExpr( + hasDeclaration(cxxConstructorDecl(ofClass( + cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), + argumentCountIs(3), hasArgument(0, hasType(CharPtrType)), + hasArgument(1, hasType(qualType(isInteger(, + hasArgument(2, hasType(qualType(isInteger(, + anyOf( + // Detect the expression: string("...", 1, 0); + hasArgument(2, ZeroExpr.bind("empty-string")), + // Detect the expression: string("...", -4, 1); + hasArgument(1, NegativeExpr.bind("negative-pos")), + // Detect the expression: string("...", 0, -4); + hasArgument(2, NegativeExpr.bind("negative-length")), + // Detect the expression: string("lit", 0, 0x1234567); + hasArgument(2, LargeLengthExpr.bind("large-length")), + // Detect the expression: string("lit", 1, 5) + allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), +hasArgument( +1, ignoringParenImpCasts(integerLiteral().bind("pos"))), +hasArgument(2, ignoringParenImpCasts( + integerLiteral().bind("length")) .bind("constructor"), this); @@ -155,14 +182,27 @@ void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { diag(Loc, "constructor creating an empty string"); } else if (Result.Nodes.getNodeAs("negative-length")) { diag(Loc, "negative value used as length parameter"); + } else if (Result.Nodes.getNodeAs("negative-pos")) { +diag(Loc, "negative value used as position of the " + "first character parameter"); } else if (Result.Nodes.getNodeAs("large-length")) { if (WarnOnLargeLength) diag(Loc, "suspicious large length parameter"); } else if (Result.Nodes.getNodeAs("literal-with-length")) { const auto *Str = Result.Nodes.getNodeAs("str"); -const auto *Lit = Result.Nodes.getNodeAs("int"); -if (Lit->getValue().ugt(Str->getLength())) { +const auto *Length = Result.Nodes.getNodeAs("length"); +if (Length->getValue().ugt(Str->getLength())) { diag(Loc, "length is bigger than string literal size"); + return; +} +if (const auto *Pos = Result.Nodes.getNodeAs("pos")) { + if (Pos->getValue().uge(Str->getLength())) { +diag(Loc, "position of the first chara
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/121291 >From 42e03bb9cc9bd815476b0a3f06ac5f58826e3708 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Fri, 31 Jan 2025 19:29:05 +0300 Subject: [PATCH] [clang-tidy] add new check bugprone-reset-ambiguous-call --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../SmartptrResetAmbiguousCallCheck.cpp | 146 +++ .../SmartptrResetAmbiguousCallCheck.h | 37 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../smartptr-reset-ambiguous-call.rst | 47 .../docs/clang-tidy/checks/list.rst | 1 + ...r-reset-ambiguous-call-custom-pointers.cpp | 72 ++ .../smartptr-reset-ambiguous-call.cpp | 239 ++ 9 files changed, 552 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index c5f0b5b28418f8..a01d0e384ab737 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -64,6 +64,7 @@ #include "SignedCharMisuseCheck.h" #include "SizeofContainerCheck.h" #include "SizeofExpressionCheck.h" +#include "SmartptrResetAmbiguousCallCheck.h" #include "SpuriouslyWakeUpFunctionsCheck.h" #include "StandaloneEmptyCheck.h" #include "StringConstructorCheck.h" @@ -207,6 +208,8 @@ class BugproneModule : public ClangTidyModule { "bugprone-sizeof-container"); CheckFactories.registerCheck( "bugprone-sizeof-expression"); +CheckFactories.registerCheck( +"bugprone-smartptr-reset-ambiguous-call"); CheckFactories.registerCheck( "bugprone-spuriously-wake-up-functions"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index e8309c68b7fcaa..7fd6f4994f5375 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -65,6 +65,7 @@ add_clang_library(clangTidyBugproneModule STATIC SizeofContainerCheck.cpp SizeofExpressionCheck.cpp SmartPtrArrayMismatchCheck.cpp + SmartptrResetAmbiguousCallCheck.cpp SpuriouslyWakeUpFunctionsCheck.cpp StandaloneEmptyCheck.cpp StringConstructorCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp new file mode 100644 index 00..326a5665179d79 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp @@ -0,0 +1,146 @@ +//===--- SmartptrResetAmbiguousCallCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "SmartptrResetAmbiguousCallCheck.h" +#include "../utils/OptionsUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { + +AST_MATCHER_P(CallExpr, everyArgumentMatches, + ast_matchers::internal::Matcher, InnerMatcher) { + for (const auto *Arg : Node.arguments()) { +if (!InnerMatcher.matches(*Arg, Finder, Builder)) + return false; + } + + return true; +} + +AST_MATCHER(CXXMethodDecl, hasOnlyDefaultParameters) { + for (const auto *Param : Node.parameters()) { +if (!Param->hasDefaultArg()) + return false; + } + + return true; +} + +const auto DefaultSmartPointers = "::std::shared_ptr;::std::unique_ptr"; +} // namespace + +SmartptrResetAmbiguousCallCheck::SmartptrResetAmbiguousCallCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + SmartPointers(utils::options::parseStringList( + Options.get("SmartPointers", DefaultSmartPointers))) {} + +void SmartptrResetAmbiguousCallCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "SmartPointers", +utils::options::seria
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/121291 >From 42e03bb9cc9bd815476b0a3f06ac5f58826e3708 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Fri, 31 Jan 2025 19:29:05 +0300 Subject: [PATCH 1/2] [clang-tidy] add new check bugprone-reset-ambiguous-call --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../SmartptrResetAmbiguousCallCheck.cpp | 146 +++ .../SmartptrResetAmbiguousCallCheck.h | 37 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../smartptr-reset-ambiguous-call.rst | 47 .../docs/clang-tidy/checks/list.rst | 1 + ...r-reset-ambiguous-call-custom-pointers.cpp | 72 ++ .../smartptr-reset-ambiguous-call.cpp | 239 ++ 9 files changed, 552 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index c5f0b5b28418f8..a01d0e384ab737 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -64,6 +64,7 @@ #include "SignedCharMisuseCheck.h" #include "SizeofContainerCheck.h" #include "SizeofExpressionCheck.h" +#include "SmartptrResetAmbiguousCallCheck.h" #include "SpuriouslyWakeUpFunctionsCheck.h" #include "StandaloneEmptyCheck.h" #include "StringConstructorCheck.h" @@ -207,6 +208,8 @@ class BugproneModule : public ClangTidyModule { "bugprone-sizeof-container"); CheckFactories.registerCheck( "bugprone-sizeof-expression"); +CheckFactories.registerCheck( +"bugprone-smartptr-reset-ambiguous-call"); CheckFactories.registerCheck( "bugprone-spuriously-wake-up-functions"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index e8309c68b7fcaa..7fd6f4994f5375 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -65,6 +65,7 @@ add_clang_library(clangTidyBugproneModule STATIC SizeofContainerCheck.cpp SizeofExpressionCheck.cpp SmartPtrArrayMismatchCheck.cpp + SmartptrResetAmbiguousCallCheck.cpp SpuriouslyWakeUpFunctionsCheck.cpp StandaloneEmptyCheck.cpp StringConstructorCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp new file mode 100644 index 00..326a5665179d79 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp @@ -0,0 +1,146 @@ +//===--- SmartptrResetAmbiguousCallCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "SmartptrResetAmbiguousCallCheck.h" +#include "../utils/OptionsUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { + +AST_MATCHER_P(CallExpr, everyArgumentMatches, + ast_matchers::internal::Matcher, InnerMatcher) { + for (const auto *Arg : Node.arguments()) { +if (!InnerMatcher.matches(*Arg, Finder, Builder)) + return false; + } + + return true; +} + +AST_MATCHER(CXXMethodDecl, hasOnlyDefaultParameters) { + for (const auto *Param : Node.parameters()) { +if (!Param->hasDefaultArg()) + return false; + } + + return true; +} + +const auto DefaultSmartPointers = "::std::shared_ptr;::std::unique_ptr"; +} // namespace + +SmartptrResetAmbiguousCallCheck::SmartptrResetAmbiguousCallCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + SmartPointers(utils::options::parseStringList( + Options.get("SmartPointers", DefaultSmartPointers))) {} + +void SmartptrResetAmbiguousCallCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "SmartPointers", +utils::options::s
[clang-tools-extra] [clang-tidy] add new modernize-use-scoped-lock check (PR #126434)
https://github.com/vbvictor created https://github.com/llvm/llvm-project/pull/126434 Add new clang-tidy that finds uses of `std::lock_guard` and suggests replacing them with C++17's more flexible and safer alternative `std::scoped_lock`. Here is a small description of how it works for better understanding of the code: Two separate AST matchers are registered: - The first one matches declarations of `std::lock_guard` that are single in their scope (only one `std::lock_guard` in `CompoundStmt`). It's an easy case, we can emit warning right away. - The second one matches `CompoundStmt`'s that have multiple `std::lock_guard` declarations, which means that we may have consecutive declarations of `std::lock_guard` that can be replaced by a single `std::scoped_lock`. In order to ensure that declarations are consecutive, we need to loop over `Stmt`'s in `CompoundStmt`. Here is a small example: ```cpp { std::mutex m1, m2; std::lock(m1, m2); std::lock_guard l1(m, std::adopt_lock); // first declaration of 'std::lock_guard' std::lock_guard l2(m, std::adopt_lock); // second declaration of 'std::lock_guard' that can be merged with first using 'scoped_lock' } ``` If there is an easier way to find consecutive declarations of `std::lock_guard` in AST matchers, I'm happy to learn and adjust my code. This PR closes https://github.com/llvm/llvm-project/issues/107839. >From 92588a7eb3f87e74887e94f88d3402ec25c6ee53 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 9 Feb 2025 22:34:26 +0300 Subject: [PATCH] [clang-tidy] add modernize-use-scoped-lock check --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseScopedLockCheck.cpp | 234 ++ .../clang-tidy/modernize/UseScopedLockCheck.h | 50 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../checks/modernize/use-scoped-lock.rst | 81 + .../use-scoped-lock-only-warn-on-multiple.cpp | 122 .../checkers/modernize/use-scoped-lock.cpp| 290 ++ 9 files changed, 788 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-scoped-lock.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock-only-warn-on-multiple.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index bab1167fb15ff20..619a27b2f9bb6b2 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -42,6 +42,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseNullptrCheck.cpp UseOverrideCheck.cpp UseRangesCheck.cpp + UseScopedLockCheck.cpp UseStartsEndsWithCheck.cpp UseStdFormatCheck.cpp UseStdNumbersCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index fc46c72982fdce8..b2d4ddd6675022a 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -43,6 +43,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseScopedLockCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -80,6 +81,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-integer-sign-comparison"); CheckFactories.registerCheck("modernize-use-ranges"); +CheckFactories.registerCheck( +"modernize-use-scoped-lock"); CheckFactories.registerCheck( "modernize-use-starts-ends-with"); CheckFactories.registerCheck("modernize-use-std-format"); diff --git a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp new file mode 100644 index 000..af2fea5ad310e6d --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp @@ -0,0 +1,234 @@ +//===--- UseScopedLockCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseScopedLockCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/
[clang-tools-extra] [clang-tidy] add new check: modernize-use-scoped-lock (PR #126434)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/126434 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add new check: modernize-use-scoped-lock (PR #126434)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/126434 >From 92588a7eb3f87e74887e94f88d3402ec25c6ee53 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 9 Feb 2025 22:34:26 +0300 Subject: [PATCH 1/2] [clang-tidy] add modernize-use-scoped-lock check --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseScopedLockCheck.cpp | 234 ++ .../clang-tidy/modernize/UseScopedLockCheck.h | 50 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../checks/modernize/use-scoped-lock.rst | 81 + .../use-scoped-lock-only-warn-on-multiple.cpp | 122 .../checkers/modernize/use-scoped-lock.cpp| 290 ++ 9 files changed, 788 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-scoped-lock.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock-only-warn-on-multiple.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index bab1167fb15ff20..619a27b2f9bb6b2 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -42,6 +42,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseNullptrCheck.cpp UseOverrideCheck.cpp UseRangesCheck.cpp + UseScopedLockCheck.cpp UseStartsEndsWithCheck.cpp UseStdFormatCheck.cpp UseStdNumbersCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index fc46c72982fdce8..b2d4ddd6675022a 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -43,6 +43,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseScopedLockCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -80,6 +81,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-integer-sign-comparison"); CheckFactories.registerCheck("modernize-use-ranges"); +CheckFactories.registerCheck( +"modernize-use-scoped-lock"); CheckFactories.registerCheck( "modernize-use-starts-ends-with"); CheckFactories.registerCheck("modernize-use-std-format"); diff --git a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp new file mode 100644 index 000..af2fea5ad310e6d --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp @@ -0,0 +1,234 @@ +//===--- UseScopedLockCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseScopedLockCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/Type.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Lex/Lexer.h" +#include "llvm/ADT/Twine.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +bool isLockGuard(const QualType &Type) { + if (const auto *RecordTy = Type->getAs()) { +if (const auto *RecordDecl = RecordTy->getDecl()) { + return RecordDecl->getQualifiedNameAsString() == "std::lock_guard"; +} + } + + if (const auto *TemplateSpecType = + Type->getAs()) { +if (const auto *TemplateDecl = +TemplateSpecType->getTemplateName().getAsTemplateDecl()) { + return TemplateDecl->getQualifiedNameAsString() == "std::lock_guard"; +} + } + + return false; +} + +std::vector getLockGuardsFromDecl(const DeclStmt *DS) { + std::vector LockGuards; + + for (const auto *Decl : DS->decls()) { +if (const auto *VD = dyn_cast(Decl)) { + const QualType Type = VD->getType().getCanonicalType(); + if (isLockGuard(Type)) { +LockGuards.push_back(VD); + } +} + } + + return LockGuards; +} + +// Scans through the statements in a block and groups consecutive +// 'std::lock_guard' variable declarations toget
[clang-tools-extra] [clang-tidy] add new check: modernize-use-scoped-lock (PR #126434)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/126434 >From 92588a7eb3f87e74887e94f88d3402ec25c6ee53 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 9 Feb 2025 22:34:26 +0300 Subject: [PATCH 1/3] [clang-tidy] add modernize-use-scoped-lock check --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseScopedLockCheck.cpp | 234 ++ .../clang-tidy/modernize/UseScopedLockCheck.h | 50 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 1 + .../checks/modernize/use-scoped-lock.rst | 81 + .../use-scoped-lock-only-warn-on-multiple.cpp | 122 .../checkers/modernize/use-scoped-lock.cpp| 290 ++ 9 files changed, 788 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-scoped-lock.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock-only-warn-on-multiple.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index bab1167fb15ff20..619a27b2f9bb6b2 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -42,6 +42,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseNullptrCheck.cpp UseOverrideCheck.cpp UseRangesCheck.cpp + UseScopedLockCheck.cpp UseStartsEndsWithCheck.cpp UseStdFormatCheck.cpp UseStdNumbersCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index fc46c72982fdce8..b2d4ddd6675022a 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -43,6 +43,7 @@ #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" #include "UseRangesCheck.h" +#include "UseScopedLockCheck.h" #include "UseStartsEndsWithCheck.h" #include "UseStdFormatCheck.h" #include "UseStdNumbersCheck.h" @@ -80,6 +81,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck( "modernize-use-integer-sign-comparison"); CheckFactories.registerCheck("modernize-use-ranges"); +CheckFactories.registerCheck( +"modernize-use-scoped-lock"); CheckFactories.registerCheck( "modernize-use-starts-ends-with"); CheckFactories.registerCheck("modernize-use-std-format"); diff --git a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp new file mode 100644 index 000..af2fea5ad310e6d --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp @@ -0,0 +1,234 @@ +//===--- UseScopedLockCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseScopedLockCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/Type.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Lex/Lexer.h" +#include "llvm/ADT/Twine.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +namespace { + +bool isLockGuard(const QualType &Type) { + if (const auto *RecordTy = Type->getAs()) { +if (const auto *RecordDecl = RecordTy->getDecl()) { + return RecordDecl->getQualifiedNameAsString() == "std::lock_guard"; +} + } + + if (const auto *TemplateSpecType = + Type->getAs()) { +if (const auto *TemplateDecl = +TemplateSpecType->getTemplateName().getAsTemplateDecl()) { + return TemplateDecl->getQualifiedNameAsString() == "std::lock_guard"; +} + } + + return false; +} + +std::vector getLockGuardsFromDecl(const DeclStmt *DS) { + std::vector LockGuards; + + for (const auto *Decl : DS->decls()) { +if (const auto *VD = dyn_cast(Decl)) { + const QualType Type = VD->getType().getCanonicalType(); + if (isLockGuard(Type)) { +LockGuards.push_back(VD); + } +} + } + + return LockGuards; +} + +// Scans through the statements in a block and groups consecutive +// 'std::lock_guard' variable declarations toget
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
vbvictor wrote: Ping https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
vbvictor wrote: Ping https://github.com/llvm/llvm-project/pull/122951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
vbvictor wrote: There are some general improvements can be made: - Create a separate test file `use-cpp-style-comments-doxygen.cpp` and leave `use-cpp-style-comments.cpp` as it was before. With this, we can make sure that check runs good both with and without option. - Add documentation about option `ExcludeDoxygenStyleComments` in clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst. You can use others docs with described options as reference. https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
vbvictor wrote: Ping, @HerrCai0907, Could you please address https://github.com/llvm/llvm-project/pull/123413#issuecomment-2622200842. Thank you in advance. https://github.com/llvm/llvm-project/pull/123413 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
vbvictor wrote: Ping https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/122951 >From 618f4a1707c1b62693c0e878040997154e7e35d6 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 14 Jan 2025 22:05:43 +0300 Subject: [PATCH 1/9] [clang-tidy] add AllowedTypes to misc-const-correctness --- .../clang-tidy/misc/ConstCorrectnessCheck.cpp | 18 +- .../clang-tidy/misc/ConstCorrectnessCheck.h | 2 + clang-tools-extra/docs/ReleaseNotes.rst | 5 + .../checks/misc/const-correctness.rst | 10 + .../misc/const-correctness-allowed-types.cpp | 180 ++ 5 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-allowed-types.cpp diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index 71a4cee4bdc6ef..aee4a3b789863c 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -8,6 +8,8 @@ #include "ConstCorrectnessCheck.h" #include "../utils/FixItHintUtils.h" +#include "../utils/Matchers.h" +#include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -41,7 +43,9 @@ ConstCorrectnessCheck::ConstCorrectnessCheck(StringRef Name, TransformValues(Options.get("TransformValues", true)), TransformReferences(Options.get("TransformReferences", true)), TransformPointersAsValues( - Options.get("TransformPointersAsValues", false)) { + Options.get("TransformPointersAsValues", false)), + AllowedTypes( + utils::options::parseStringList(Options.get("AllowedTypes", ""))) { if (AnalyzeValues == false && AnalyzeReferences == false) this->configurationDiag( "The check 'misc-const-correctness' will not " @@ -57,6 +61,9 @@ void ConstCorrectnessCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "TransformValues", TransformValues); Options.store(Opts, "TransformReferences", TransformReferences); Options.store(Opts, "TransformPointersAsValues", TransformPointersAsValues); + + Options.store(Opts, "AllowedTypes", +utils::options::serializeStringList(AllowedTypes)); } void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { @@ -73,6 +80,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType(), hasType(referenceType(pointee(substTemplateTypeParmType(); + const auto AllowedType = hasType(qualType(anyOf( + hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + pointerType(pointee(hasDeclaration( + namedDecl(matchers::matchesAnyListedName(AllowedTypes; + const auto AutoTemplateType = varDecl( anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType(, hasType(pointerType(pointee(autoType()); @@ -87,7 +100,8 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { unless(anyOf(ConstType, ConstReference, TemplateType, hasInitializer(isInstantiationDependent()), AutoTemplateType, RValueReference, FunctionPointerRef, - hasType(cxxRecordDecl(isLambda())), isImplicit(; + hasType(cxxRecordDecl(isLambda())), isImplicit(), + AllowedType))); // Match the function scope for which the analysis of all local variables // shall be run. diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h index bba060e555d001..3b7aba7c4be384 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h @@ -45,6 +45,8 @@ class ConstCorrectnessCheck : public ClangTidyCheck { const bool TransformValues; const bool TransformReferences; const bool TransformPointersAsValues; + + const std::vector AllowedTypes; }; } // namespace clang::tidy::misc diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 3bddeeda06e06b..f57e951afc1ce0 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -101,6 +101,11 @@ Changes in existing checks ` check to allow specifying additional C++ member functions to match. +- Improved :doc:`misc-const-correctness + ` check by adding + the option ``AllowedTypes``, that excludes specified types + from const-correctness checking. + Removed checks ^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst b/clang-tools-extra/docs/clang-
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
@@ -196,3 +199,13 @@ Options // The following pointer may not become a 'int *const'. int *changing_pointee = &value; changing_pointee = &result; + +.. option:: AllowedTypes + + A semicolon-separated list of names of types that will be excluded from + const-correctness checking. Regular expressions are accepted, e.g. + `[Rr]ef(erence)?$` matches every type with suffix `Ref`, `ref`, `Reference` + and `reference`. If a name in the list contains the sequence `::`, it is + matched against the qualified type name (i.e. ``namespace::Type``), + otherwise it is matched against only the type name (i.e. ``Type``). + Default is empty. vbvictor wrote: Done. https://github.com/llvm/llvm-project/pull/122951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/122951 >From 618f4a1707c1b62693c0e878040997154e7e35d6 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 14 Jan 2025 22:05:43 +0300 Subject: [PATCH 1/8] [clang-tidy] add AllowedTypes to misc-const-correctness --- .../clang-tidy/misc/ConstCorrectnessCheck.cpp | 18 +- .../clang-tidy/misc/ConstCorrectnessCheck.h | 2 + clang-tools-extra/docs/ReleaseNotes.rst | 5 + .../checks/misc/const-correctness.rst | 10 + .../misc/const-correctness-allowed-types.cpp | 180 ++ 5 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-allowed-types.cpp diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index 71a4cee4bdc6ef..aee4a3b789863c 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -8,6 +8,8 @@ #include "ConstCorrectnessCheck.h" #include "../utils/FixItHintUtils.h" +#include "../utils/Matchers.h" +#include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -41,7 +43,9 @@ ConstCorrectnessCheck::ConstCorrectnessCheck(StringRef Name, TransformValues(Options.get("TransformValues", true)), TransformReferences(Options.get("TransformReferences", true)), TransformPointersAsValues( - Options.get("TransformPointersAsValues", false)) { + Options.get("TransformPointersAsValues", false)), + AllowedTypes( + utils::options::parseStringList(Options.get("AllowedTypes", ""))) { if (AnalyzeValues == false && AnalyzeReferences == false) this->configurationDiag( "The check 'misc-const-correctness' will not " @@ -57,6 +61,9 @@ void ConstCorrectnessCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "TransformValues", TransformValues); Options.store(Opts, "TransformReferences", TransformReferences); Options.store(Opts, "TransformPointersAsValues", TransformPointersAsValues); + + Options.store(Opts, "AllowedTypes", +utils::options::serializeStringList(AllowedTypes)); } void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { @@ -73,6 +80,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType(), hasType(referenceType(pointee(substTemplateTypeParmType(); + const auto AllowedType = hasType(qualType(anyOf( + hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + pointerType(pointee(hasDeclaration( + namedDecl(matchers::matchesAnyListedName(AllowedTypes; + const auto AutoTemplateType = varDecl( anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType(, hasType(pointerType(pointee(autoType()); @@ -87,7 +100,8 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { unless(anyOf(ConstType, ConstReference, TemplateType, hasInitializer(isInstantiationDependent()), AutoTemplateType, RValueReference, FunctionPointerRef, - hasType(cxxRecordDecl(isLambda())), isImplicit(; + hasType(cxxRecordDecl(isLambda())), isImplicit(), + AllowedType))); // Match the function scope for which the analysis of all local variables // shall be run. diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h index bba060e555d001..3b7aba7c4be384 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h @@ -45,6 +45,8 @@ class ConstCorrectnessCheck : public ClangTidyCheck { const bool TransformValues; const bool TransformReferences; const bool TransformPointersAsValues; + + const std::vector AllowedTypes; }; } // namespace clang::tidy::misc diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 3bddeeda06e06b..f57e951afc1ce0 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -101,6 +101,11 @@ Changes in existing checks ` check to allow specifying additional C++ member functions to match. +- Improved :doc:`misc-const-correctness + ` check by adding + the option ``AllowedTypes``, that excludes specified types + from const-correctness checking. + Removed checks ^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst b/clang-tools-extra/docs/clang-
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/123413 >From f5f0ba142a2eb71ce781faf4e15fcd225bec9ca8 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sat, 18 Jan 2025 00:49:29 +0300 Subject: [PATCH 1/2] [clang-tidy] Added support for 3-argument string ctor --- .../bugprone/StringConstructorCheck.cpp | 50 +-- clang-tools-extra/docs/ReleaseNotes.rst | 5 ++ .../checkers/bugprone/string-constructor.cpp | 30 +++ 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 8ae4351ac2830a..d1902b658061b1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -82,7 +82,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxConstructExpr( hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(0, hasType(qualType(isInteger(, + argumentCountIs(2), hasArgument(0, hasType(qualType(isInteger(, hasArgument(1, hasType(qualType(isInteger(, anyOf( // Detect the expression: string('x', 40); @@ -102,7 +102,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { cxxConstructExpr( hasDeclaration(cxxConstructorDecl(ofClass( cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), - hasArgument(0, hasType(CharPtrType)), + argumentCountIs(2), hasArgument(0, hasType(CharPtrType)), hasArgument(1, hasType(isInteger())), anyOf( // Detect the expression: string("...", 0); @@ -114,7 +114,34 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { // Detect the expression: string("lit", 5) allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), hasArgument(1, ignoringParenImpCasts( - integerLiteral().bind("int")) + integerLiteral().bind("length")) + .bind("constructor"), + this); + + // Check the literal string constructor with char pointer, start position and + // length parameters. [i.e. string (const char* s, size_t pos, size_t count);] + Finder->addMatcher( + cxxConstructExpr( + hasDeclaration(cxxConstructorDecl(ofClass( + cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), + argumentCountIs(3), hasArgument(0, hasType(CharPtrType)), + hasArgument(1, hasType(qualType(isInteger(, + hasArgument(2, hasType(qualType(isInteger(, + anyOf( + // Detect the expression: string("...", 1, 0); + hasArgument(2, ZeroExpr.bind("empty-string")), + // Detect the expression: string("...", -4, 1); + hasArgument(1, NegativeExpr.bind("negative-pos")), + // Detect the expression: string("...", 0, -4); + hasArgument(2, NegativeExpr.bind("negative-length")), + // Detect the expression: string("lit", 0, 0x1234567); + hasArgument(2, LargeLengthExpr.bind("large-length")), + // Detect the expression: string("lit", 1, 5) + allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), +hasArgument( +1, ignoringParenImpCasts(integerLiteral().bind("pos"))), +hasArgument(2, ignoringParenImpCasts( + integerLiteral().bind("length")) .bind("constructor"), this); @@ -155,14 +182,27 @@ void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { diag(Loc, "constructor creating an empty string"); } else if (Result.Nodes.getNodeAs("negative-length")) { diag(Loc, "negative value used as length parameter"); + } else if (Result.Nodes.getNodeAs("negative-pos")) { +diag(Loc, "negative value used as position of the " + "first character parameter"); } else if (Result.Nodes.getNodeAs("large-length")) { if (WarnOnLargeLength) diag(Loc, "suspicious large length parameter"); } else if (Result.Nodes.getNodeAs("literal-with-length")) { const auto *Str = Result.Nodes.getNodeAs("str"); -const auto *Lit = Result.Nodes.getNodeAs("int"); -if (Lit->getValue().ugt(Str->getLength())) { +const auto *Length = Result.Nodes.getNodeAs("length"); +if (Length->getValue().ugt(Str->getLength())) { diag(Loc, "length is bigger than string literal size"); + return; +} +if (const auto *Pos = Result.Nodes.getNodeAs("pos")) { + if (Pos->getValue().uge(Str->getLength())) { +diag(Loc, "position of the first charact
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
vbvictor wrote: > please update documents in > clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.rst also Added new error description for "invalid character position argument" and provided more examples to existing cases. https://github.com/llvm/llvm-project/pull/123413 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
@@ -0,0 +1,127 @@ +//===--- UseCppStyleCommentsCheck.cpp - clang-tidy-===// + +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseCppStyleCommentsCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" +#include +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { +class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler { +public: + CStyleCommentHandler(UseCppStyleCommentsCheck &Check) + : Check(Check), +CStyleCommentMatch( +"^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$") { + } + + std::string convertToCppStyleComment(const SourceManager &SM, + const SourceRange &Range) { +StringRef CommentText = Lexer::getSourceText( +CharSourceRange::getTokenRange(Range), SM, LangOptions()); + +std::string InnerText = CommentText.str(); +InnerText.erase(0, 2); +InnerText.erase(InnerText.size() - 2, 2); + +std::string Result; +std::istringstream Stream(InnerText); +std::string Line; + +if (std::getline(Stream, Line)) { + size_t startPos = Line.find_first_not_of(" \t"); + if (startPos != std::string::npos) { +Line = Line.substr(startPos); + } else { +Line.clear(); + } + Result += "// " + Line; +} + +while (std::getline(Stream, Line)) { + size_t startPos = Line.find_first_not_of(" \t"); vbvictor wrote: ```suggestion size_t StartPos = Line.find_first_not_of(" \t"); ``` https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
vbvictor wrote: Ping @PiotrZSL @5chmidti https://github.com/llvm/llvm-project/pull/123413 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] added option `google-readability-namespace-comments.AllowNoNamespaceComments` (PR #124265)
@@ -39,3 +39,10 @@ Options An unsigned integer specifying the number of spaces before the comment closing a namespace definition. Default is `1U`. + + +.. option:: AllowNoNamespaceComments + + When true, the check will allow that no namespace comment is present. + If a namespace comment is added but it is not matching, the check will fail. Default is `false`. vbvictor wrote: Please, wrap line to 80 characters. https://github.com/llvm/llvm-project/pull/124265 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] added option `google-readability-namespace-comments.AllowNoNamespaceComments` (PR #124265)
@@ -39,3 +39,10 @@ Options An unsigned integer specifying the number of spaces before the comment closing a namespace definition. Default is `1U`. + + +.. option:: AllowNoNamespaceComments + + When true, the check will allow that no namespace comment is present. + If a namespace comment is added but it is not matching, the check will fail. Default is `false`. vbvictor wrote: Please, wrap line to 80 characters https://github.com/llvm/llvm-project/pull/124265 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] added option `google-readability-namespace-comments.AllowNoNamespaceComments` (PR #124265)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/124265 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
@@ -0,0 +1,40 @@ +//===--- UseCppStyleCommentsCheck.h - clang-tidy---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_CPP_STYLE_COMMENTS_CHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_CPP_STYLE_COMMENTS_CHECK_H + +#include "../ClangTidyCheck.h" +#include vbvictor wrote: Please, remove unused include. https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
@@ -0,0 +1,127 @@ +//===--- UseCppStyleCommentsCheck.cpp - clang-tidy-===// + +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseCppStyleCommentsCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" +#include vbvictor wrote: Please, remove unused include. https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
@@ -0,0 +1,127 @@ +//===--- UseCppStyleCommentsCheck.cpp - clang-tidy-===// + +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UseCppStyleCommentsCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" +#include +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { +class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler { +public: + CStyleCommentHandler(UseCppStyleCommentsCheck &Check) + : Check(Check), +CStyleCommentMatch( +"^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$") { + } + + std::string convertToCppStyleComment(const SourceManager &SM, + const SourceRange &Range) { +StringRef CommentText = Lexer::getSourceText( +CharSourceRange::getTokenRange(Range), SM, LangOptions()); + +std::string InnerText = CommentText.str(); +InnerText.erase(0, 2); +InnerText.erase(InnerText.size() - 2, 2); + +std::string Result; +std::istringstream Stream(InnerText); +std::string Line; + +if (std::getline(Stream, Line)) { + size_t startPos = Line.find_first_not_of(" \t"); vbvictor wrote: Please, use CamelCase ```suggestion size_t StartPos = Line.find_first_not_of(" \t"); ``` https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
vbvictor wrote: Thank you for working on this check! Please, read comments on previous pull request https://github.com/llvm/llvm-project/pull/99713. I think there could be some improvements done based on comments in that PR. For moving this check to `readability` section script `clang-tools-extra/clang-tidy/rename_check.py` can be useful. https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] added option `google-readability-namespace-comments.AllowNoNamespaceComments` (PR #124265)
@@ -39,3 +39,10 @@ Options An unsigned integer specifying the number of spaces before the comment closing a namespace definition. Default is `1U`. + + +.. option:: AllowNoNamespaceComments + + When true, the check will allow that no namespace comment is present. + If a namespace comment is added but it is not matching, the check will fail. Default is `false`. vbvictor wrote: Nit: I am not a native speaker but I suggest there could be an easier to understand wording: ```suggestion If a namespace comment is present but does not match namespace definition, the check will fail. Default is `false`. ``` https://github.com/llvm/llvm-project/pull/124265 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/121291 >From 37dce6a7ed0cca2e9819c24f4d176c43e3c9f2ac Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 29 Dec 2024 15:32:22 +0300 Subject: [PATCH 1/7] [clang-tidy] Add bugprone-reset-call check --- .../bugprone/BugproneTidyModule.cpp | 2 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../clang-tidy/bugprone/ResetCallCheck.cpp| 133 +++ .../clang-tidy/bugprone/ResetCallCheck.h | 34 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../clang-tidy/checks/bugprone/reset-call.rst | 33 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/reset-call.cpp | 215 ++ 8 files changed, 425 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/reset-call.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/reset-call.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 33ac65e715ce81..645958e47e22a5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -57,6 +57,7 @@ #include "PosixReturnCheck.h" #include "RedundantBranchConditionCheck.h" #include "ReservedIdentifierCheck.h" +#include "ResetCallCheck.h" #include "ReturnConstRefFromParameterCheck.h" #include "SharedPtrArrayMismatchCheck.h" #include "SignalHandlerCheck.h" @@ -144,6 +145,7 @@ class BugproneModule : public ClangTidyModule { "bugprone-inaccurate-erase"); CheckFactories.registerCheck( "bugprone-incorrect-enable-if"); +CheckFactories.registerCheck("bugprone-reset-call"); CheckFactories.registerCheck( "bugprone-return-const-ref-from-parameter"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 13adad7c3dadbd..17ab5b27ec5550 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -52,6 +52,7 @@ add_clang_library(clangTidyBugproneModule STATIC PosixReturnCheck.cpp RedundantBranchConditionCheck.cpp ReservedIdentifierCheck.cpp + ResetCallCheck.cpp ReturnConstRefFromParameterCheck.cpp SharedPtrArrayMismatchCheck.cpp SignalHandlerCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp new file mode 100644 index 00..305ac8d51adf3e --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp @@ -0,0 +1,133 @@ +//===--- ResetCallCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ResetCallCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { + +AST_MATCHER_P(CallExpr, everyArgumentMatches, + ast_matchers::internal::Matcher, InnerMatcher) { + if (Node.getNumArgs() == 0) +return true; + + for (const auto *Arg : Node.arguments()) { +if (!InnerMatcher.matches(*Arg, Finder, Builder)) + return false; + } + return true; +} + +AST_MATCHER(CXXMethodDecl, hasOnlyDefaultArgs) { + if (Node.param_empty()) +return true; + + for (const auto *Param : Node.parameters()) { +if (!Param->hasDefaultArg()) + return false; + } + return true; +} + +} // namespace + +void ResetCallCheck::registerMatchers(MatchFinder *Finder) { + const auto IsSmartptr = hasAnyName("::std::unique_ptr", "::std::shared_ptr"); + + const auto ResetMethod = + cxxMethodDecl(hasName("reset"), hasOnlyDefaultArgs()); + + const auto TypeWithReset = + anyOf(cxxRecordDecl(hasMethod(ResetMethod)), +classTemplateSpecializationDecl( +hasSpecializedTemplate(classTemplateDecl(has(ResetMethod); + + const auto SmartptrWithBugproneReset = classTemplateSpecializationDecl( + IsSmartptr, + hasTemplateArgument( + 0, templateArgument(refersToType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(TypeWithReset))); + + // Find a.reset() calls + Finder->addMatcher( + cxxMemberCallExpr(callee(memberExpr(member(hasName("reset", +
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
@@ -0,0 +1,150 @@ +//===--- SmartptrResetAmbiguousCallCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "SmartptrResetAmbiguousCallCheck.h" +#include "../utils/OptionsUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { + +AST_MATCHER_P(CallExpr, everyArgumentMatches, + ast_matchers::internal::Matcher, InnerMatcher) { + if (Node.getNumArgs() == 0) +return true; + vbvictor wrote: Yes, removed useless condition. https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
@@ -0,0 +1,150 @@ +//===--- SmartptrResetAmbiguousCallCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "SmartptrResetAmbiguousCallCheck.h" +#include "../utils/OptionsUtils.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { + +AST_MATCHER_P(CallExpr, everyArgumentMatches, + ast_matchers::internal::Matcher, InnerMatcher) { + if (Node.getNumArgs() == 0) +return true; + + for (const auto *Arg : Node.arguments()) { +if (!InnerMatcher.matches(*Arg, Finder, Builder)) + return false; + } + return true; +} + +AST_MATCHER(CXXMethodDecl, hasOnlyDefaultParameters) { + if (Node.param_empty()) vbvictor wrote: Yes, removed useless condition. https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] added option `google-readability-namespace-comments.AllowNoNamespaceComments` (PR #124265)
https://github.com/vbvictor deleted https://github.com/llvm/llvm-project/pull/124265 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] added option `google-readability-namespace-comments.AllowNoNamespaceComments` (PR #124265)
vbvictor wrote: Please, update Release Notes in clang-tools-extra/docs/ReleaseNotes.rst https://github.com/llvm/llvm-project/pull/124265 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] added option `google-readability-namespace-comments.AllowNoNamespaceComments` (PR #124265)
vbvictor wrote: > What do you think about the option's name? Is `AllowNoNamespaceComments` > fine for you or shall I rename to `AllowOmittingNamespaceComments` (or any > other suggestion)? As for now I can not think of a better name, maybe others will suggest. https://github.com/llvm/llvm-project/pull/124265 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] added option `google-readability-namespace-comments.AllowNoNamespaceComments` (PR #124265)
@@ -39,3 +39,11 @@ Options An unsigned integer specifying the number of spaces before the comment closing a namespace definition. Default is `1U`. + + +.. option:: AllowNoNamespaceComments + + When true, the check will allow that namespace comments are ommitted + entirely. The check only fails if a namespace comment is present but does + not match. Default is `false`. vbvictor wrote: Nit: I think it will make easier to understand what it tries to match. The same should be corrected in clang-tools-extra/docs/ReleaseNotes.rst if you wish to apply this fix. ```suggestion not match namespace definition. Default is `false`. ``` https://github.com/llvm/llvm-project/pull/124265 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/121291 >From 37dce6a7ed0cca2e9819c24f4d176c43e3c9f2ac Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 29 Dec 2024 15:32:22 +0300 Subject: [PATCH 1/5] [clang-tidy] Add bugprone-reset-call check --- .../bugprone/BugproneTidyModule.cpp | 2 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../clang-tidy/bugprone/ResetCallCheck.cpp| 133 +++ .../clang-tidy/bugprone/ResetCallCheck.h | 34 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../clang-tidy/checks/bugprone/reset-call.rst | 33 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/reset-call.cpp | 215 ++ 8 files changed, 425 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/reset-call.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/reset-call.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 33ac65e715ce81..645958e47e22a5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -57,6 +57,7 @@ #include "PosixReturnCheck.h" #include "RedundantBranchConditionCheck.h" #include "ReservedIdentifierCheck.h" +#include "ResetCallCheck.h" #include "ReturnConstRefFromParameterCheck.h" #include "SharedPtrArrayMismatchCheck.h" #include "SignalHandlerCheck.h" @@ -144,6 +145,7 @@ class BugproneModule : public ClangTidyModule { "bugprone-inaccurate-erase"); CheckFactories.registerCheck( "bugprone-incorrect-enable-if"); +CheckFactories.registerCheck("bugprone-reset-call"); CheckFactories.registerCheck( "bugprone-return-const-ref-from-parameter"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 13adad7c3dadbd..17ab5b27ec5550 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -52,6 +52,7 @@ add_clang_library(clangTidyBugproneModule STATIC PosixReturnCheck.cpp RedundantBranchConditionCheck.cpp ReservedIdentifierCheck.cpp + ResetCallCheck.cpp ReturnConstRefFromParameterCheck.cpp SharedPtrArrayMismatchCheck.cpp SignalHandlerCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp new file mode 100644 index 00..305ac8d51adf3e --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp @@ -0,0 +1,133 @@ +//===--- ResetCallCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ResetCallCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { + +AST_MATCHER_P(CallExpr, everyArgumentMatches, + ast_matchers::internal::Matcher, InnerMatcher) { + if (Node.getNumArgs() == 0) +return true; + + for (const auto *Arg : Node.arguments()) { +if (!InnerMatcher.matches(*Arg, Finder, Builder)) + return false; + } + return true; +} + +AST_MATCHER(CXXMethodDecl, hasOnlyDefaultArgs) { + if (Node.param_empty()) +return true; + + for (const auto *Param : Node.parameters()) { +if (!Param->hasDefaultArg()) + return false; + } + return true; +} + +} // namespace + +void ResetCallCheck::registerMatchers(MatchFinder *Finder) { + const auto IsSmartptr = hasAnyName("::std::unique_ptr", "::std::shared_ptr"); + + const auto ResetMethod = + cxxMethodDecl(hasName("reset"), hasOnlyDefaultArgs()); + + const auto TypeWithReset = + anyOf(cxxRecordDecl(hasMethod(ResetMethod)), +classTemplateSpecializationDecl( +hasSpecializedTemplate(classTemplateDecl(has(ResetMethod); + + const auto SmartptrWithBugproneReset = classTemplateSpecializationDecl( + IsSmartptr, + hasTemplateArgument( + 0, templateArgument(refersToType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(TypeWithReset))); + + // Find a.reset() calls + Finder->addMatcher( + cxxMemberCallExpr(callee(memberExpr(member(hasName("reset", +
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/121291 >From 37dce6a7ed0cca2e9819c24f4d176c43e3c9f2ac Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 29 Dec 2024 15:32:22 +0300 Subject: [PATCH 1/6] [clang-tidy] Add bugprone-reset-call check --- .../bugprone/BugproneTidyModule.cpp | 2 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../clang-tidy/bugprone/ResetCallCheck.cpp| 133 +++ .../clang-tidy/bugprone/ResetCallCheck.h | 34 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../clang-tidy/checks/bugprone/reset-call.rst | 33 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/reset-call.cpp | 215 ++ 8 files changed, 425 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/reset-call.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/reset-call.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 33ac65e715ce81..645958e47e22a5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -57,6 +57,7 @@ #include "PosixReturnCheck.h" #include "RedundantBranchConditionCheck.h" #include "ReservedIdentifierCheck.h" +#include "ResetCallCheck.h" #include "ReturnConstRefFromParameterCheck.h" #include "SharedPtrArrayMismatchCheck.h" #include "SignalHandlerCheck.h" @@ -144,6 +145,7 @@ class BugproneModule : public ClangTidyModule { "bugprone-inaccurate-erase"); CheckFactories.registerCheck( "bugprone-incorrect-enable-if"); +CheckFactories.registerCheck("bugprone-reset-call"); CheckFactories.registerCheck( "bugprone-return-const-ref-from-parameter"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 13adad7c3dadbd..17ab5b27ec5550 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -52,6 +52,7 @@ add_clang_library(clangTidyBugproneModule STATIC PosixReturnCheck.cpp RedundantBranchConditionCheck.cpp ReservedIdentifierCheck.cpp + ResetCallCheck.cpp ReturnConstRefFromParameterCheck.cpp SharedPtrArrayMismatchCheck.cpp SignalHandlerCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp new file mode 100644 index 00..305ac8d51adf3e --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp @@ -0,0 +1,133 @@ +//===--- ResetCallCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ResetCallCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { + +AST_MATCHER_P(CallExpr, everyArgumentMatches, + ast_matchers::internal::Matcher, InnerMatcher) { + if (Node.getNumArgs() == 0) +return true; + + for (const auto *Arg : Node.arguments()) { +if (!InnerMatcher.matches(*Arg, Finder, Builder)) + return false; + } + return true; +} + +AST_MATCHER(CXXMethodDecl, hasOnlyDefaultArgs) { + if (Node.param_empty()) +return true; + + for (const auto *Param : Node.parameters()) { +if (!Param->hasDefaultArg()) + return false; + } + return true; +} + +} // namespace + +void ResetCallCheck::registerMatchers(MatchFinder *Finder) { + const auto IsSmartptr = hasAnyName("::std::unique_ptr", "::std::shared_ptr"); + + const auto ResetMethod = + cxxMethodDecl(hasName("reset"), hasOnlyDefaultArgs()); + + const auto TypeWithReset = + anyOf(cxxRecordDecl(hasMethod(ResetMethod)), +classTemplateSpecializationDecl( +hasSpecializedTemplate(classTemplateDecl(has(ResetMethod); + + const auto SmartptrWithBugproneReset = classTemplateSpecializationDecl( + IsSmartptr, + hasTemplateArgument( + 0, templateArgument(refersToType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(TypeWithReset))); + + // Find a.reset() calls + Finder->addMatcher( + cxxMemberCallExpr(callee(memberExpr(member(hasName("reset", +
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
@@ -0,0 +1,47 @@ +.. title:: clang-tidy - bugprone-smartptr-reset-ambiguous-call + +bugprone-smartptr-reset-ambiguous-call +== + +Finds potentially erroneous calls to ``reset`` method on +smart pointers when the pointee type also has a ``reset`` method. +Having a ``reset`` method in both classes makes it easy to accidentally +make the pointer null when intending to reset the underlying object. + +.. code-block:: c++ + + struct Resettable { +void reset() { /* Own reset logic */ } + }; + + auto ptr = std::make_unique(); + + ptr->reset(); // Calls underlying reset method + ptr.reset(); // Makes the pointer null + +Both calls are valid C++ code, but the second one might not be +what the developer intended, as it destroys the pointed-to object +rather than resetting its state. +It's easy to make such a typo because the difference +between ``.`` and ``->`` is really small. + +The recommended approach is to make the intent explicit by +using either member access or direct assignment: + +.. code-block:: c++ + + std::unique_ptr ptr = std::make_unique(); + + (*ptr).reset(); // Clearly calls underlying reset method + ptr = nullptr; // Clearly makes the pointer null + +The default smart pointers that are considered are ``std::unique_ptr``, +``std::shared_ptr``. To specify other smart pointers or +other classes use the :option:`SmartPointers` option. + +Options +--- + +.. option:: SmartPointers + +Semicolon-separated list of class names of custom smart pointers. vbvictor wrote: Done https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
vbvictor wrote: Thank you everyone for the feedback! @PiotrZSL I tried using TK_IgnoreUnlessSpelledInSource with `cxxDependentScopeMemberExpr` ast-matcher but failed to write a working matcher case with nested template parameters: ```cpp template void TemplatePositiveTest() { std::unique_ptr u_ptr; u_ptr.reset(); u_ptr->reset(); } void instantiate() { TemplatePositiveTest>(); } ``` As for now, I'm thinking about leaving it as is and make an NFC change in the future when I get more familiar with matchers. Apart from TK_IgnoreUnlessSpelledInSource I fixed your comments. @5chmidti I fixed all your comments and added better _warning_ and _note_ messages: ```cpp s.reset(); // warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method // note: assign the pointer to 'nullptr' s->reset(); // warning: be explicit when calling 'reset()' on a pointee of a smart pointer // note: use dereference to call 'reset' method of the pointee ``` @EugeneZelenko Fixed all pr comments. https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
https://github.com/vbvictor created https://github.com/llvm/llvm-project/pull/123413 This PR add diagnostics for 3-parameter `std::basic_string(const char* t, size_type pos, size_type count)` constructor in bugprone-string-constructor check: ```cpp std::string r1("test", 1, 0); // constructor creating an empty string std::string r2("test", 0, -4); // negative value used as length parameter // more examples in test file ``` Fixes false-positives reported in https://github.com/llvm/llvm-project/issues/123198. >From f5f0ba142a2eb71ce781faf4e15fcd225bec9ca8 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sat, 18 Jan 2025 00:49:29 +0300 Subject: [PATCH] [clang-tidy] Added support for 3-argument string ctor --- .../bugprone/StringConstructorCheck.cpp | 50 +-- clang-tools-extra/docs/ReleaseNotes.rst | 5 ++ .../checkers/bugprone/string-constructor.cpp | 30 +++ 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 8ae4351ac2830a..d1902b658061b1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -82,7 +82,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxConstructExpr( hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(0, hasType(qualType(isInteger(, + argumentCountIs(2), hasArgument(0, hasType(qualType(isInteger(, hasArgument(1, hasType(qualType(isInteger(, anyOf( // Detect the expression: string('x', 40); @@ -102,7 +102,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { cxxConstructExpr( hasDeclaration(cxxConstructorDecl(ofClass( cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), - hasArgument(0, hasType(CharPtrType)), + argumentCountIs(2), hasArgument(0, hasType(CharPtrType)), hasArgument(1, hasType(isInteger())), anyOf( // Detect the expression: string("...", 0); @@ -114,7 +114,34 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { // Detect the expression: string("lit", 5) allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), hasArgument(1, ignoringParenImpCasts( - integerLiteral().bind("int")) + integerLiteral().bind("length")) + .bind("constructor"), + this); + + // Check the literal string constructor with char pointer, start position and + // length parameters. [i.e. string (const char* s, size_t pos, size_t count);] + Finder->addMatcher( + cxxConstructExpr( + hasDeclaration(cxxConstructorDecl(ofClass( + cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), + argumentCountIs(3), hasArgument(0, hasType(CharPtrType)), + hasArgument(1, hasType(qualType(isInteger(, + hasArgument(2, hasType(qualType(isInteger(, + anyOf( + // Detect the expression: string("...", 1, 0); + hasArgument(2, ZeroExpr.bind("empty-string")), + // Detect the expression: string("...", -4, 1); + hasArgument(1, NegativeExpr.bind("negative-pos")), + // Detect the expression: string("...", 0, -4); + hasArgument(2, NegativeExpr.bind("negative-length")), + // Detect the expression: string("lit", 0, 0x1234567); + hasArgument(2, LargeLengthExpr.bind("large-length")), + // Detect the expression: string("lit", 1, 5) + allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), +hasArgument( +1, ignoringParenImpCasts(integerLiteral().bind("pos"))), +hasArgument(2, ignoringParenImpCasts( + integerLiteral().bind("length")) .bind("constructor"), this); @@ -155,14 +182,27 @@ void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { diag(Loc, "constructor creating an empty string"); } else if (Result.Nodes.getNodeAs("negative-length")) { diag(Loc, "negative value used as length parameter"); + } else if (Result.Nodes.getNodeAs("negative-pos")) { +diag(Loc, "negative value used as position of the " + "first character parameter"); } else if (Result.Nodes.getNodeAs("large-length")) { if (WarnOnLargeLength) diag(Loc, "suspicious large length parameter"); } else if (Result.Nodes.getNodeAs("literal-with-length")) { const auto *Str = Result.Nodes.getNodeAs("str"); -const auto *Lit =
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
vbvictor wrote: Ping https://github.com/llvm/llvm-project/pull/122951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Refactor: removed typos in 'AllowedTypes' option in various checks (PR #122957)
vbvictor wrote: @EugeneZelenko Ping I would also need assistance in merging this PR since I don't have write permissions. https://github.com/llvm/llvm-project/pull/122957 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/122951 >From 841cfec5a0ab4ce5ce64e71facfb7becaf4340e8 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 14 Jan 2025 22:05:43 +0300 Subject: [PATCH 1/5] [clang-tidy] add AllowedTypes to misc-const-correctness --- .../clang-tidy/misc/ConstCorrectnessCheck.cpp | 18 +- .../clang-tidy/misc/ConstCorrectnessCheck.h | 2 + clang-tools-extra/docs/ReleaseNotes.rst | 5 + .../checks/misc/const-correctness.rst | 10 + .../misc/const-correctness-allowed-types.cpp | 180 ++ 5 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-allowed-types.cpp diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index 71a4cee4bdc6ef..aee4a3b789863c 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -8,6 +8,8 @@ #include "ConstCorrectnessCheck.h" #include "../utils/FixItHintUtils.h" +#include "../utils/Matchers.h" +#include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -41,7 +43,9 @@ ConstCorrectnessCheck::ConstCorrectnessCheck(StringRef Name, TransformValues(Options.get("TransformValues", true)), TransformReferences(Options.get("TransformReferences", true)), TransformPointersAsValues( - Options.get("TransformPointersAsValues", false)) { + Options.get("TransformPointersAsValues", false)), + AllowedTypes( + utils::options::parseStringList(Options.get("AllowedTypes", ""))) { if (AnalyzeValues == false && AnalyzeReferences == false) this->configurationDiag( "The check 'misc-const-correctness' will not " @@ -57,6 +61,9 @@ void ConstCorrectnessCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "TransformValues", TransformValues); Options.store(Opts, "TransformReferences", TransformReferences); Options.store(Opts, "TransformPointersAsValues", TransformPointersAsValues); + + Options.store(Opts, "AllowedTypes", +utils::options::serializeStringList(AllowedTypes)); } void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { @@ -73,6 +80,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType(), hasType(referenceType(pointee(substTemplateTypeParmType(); + const auto AllowedType = hasType(qualType(anyOf( + hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + pointerType(pointee(hasDeclaration( + namedDecl(matchers::matchesAnyListedName(AllowedTypes; + const auto AutoTemplateType = varDecl( anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType(, hasType(pointerType(pointee(autoType()); @@ -87,7 +100,8 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { unless(anyOf(ConstType, ConstReference, TemplateType, hasInitializer(isInstantiationDependent()), AutoTemplateType, RValueReference, FunctionPointerRef, - hasType(cxxRecordDecl(isLambda())), isImplicit(; + hasType(cxxRecordDecl(isLambda())), isImplicit(), + AllowedType))); // Match the function scope for which the analysis of all local variables // shall be run. diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h index bba060e555d001..3b7aba7c4be384 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h @@ -45,6 +45,8 @@ class ConstCorrectnessCheck : public ClangTidyCheck { const bool TransformValues; const bool TransformReferences; const bool TransformPointersAsValues; + + const std::vector AllowedTypes; }; } // namespace clang::tidy::misc diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index fa3a8e577a33ad..16be70ca944e95 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -260,6 +260,11 @@ Changes in existing checks ` check to report a location even when the member location is not valid. +- Improved :doc:`misc-const-correctness + ` check by adding + the option ``AllowedTypes``, that excludes specified types + from const-correctness checking. + - Improved :doc:`misc-definitions-in-headers ` check by rewording the diagnostic note that suggests adding ``inline``. diff --git a/clang
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/121291 >From 37dce6a7ed0cca2e9819c24f4d176c43e3c9f2ac Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sun, 29 Dec 2024 15:32:22 +0300 Subject: [PATCH 1/8] [clang-tidy] Add bugprone-reset-call check --- .../bugprone/BugproneTidyModule.cpp | 2 + .../clang-tidy/bugprone/CMakeLists.txt| 1 + .../clang-tidy/bugprone/ResetCallCheck.cpp| 133 +++ .../clang-tidy/bugprone/ResetCallCheck.h | 34 +++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../clang-tidy/checks/bugprone/reset-call.rst | 33 +++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/reset-call.cpp | 215 ++ 8 files changed, 425 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/reset-call.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/reset-call.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 33ac65e715ce81..645958e47e22a5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -57,6 +57,7 @@ #include "PosixReturnCheck.h" #include "RedundantBranchConditionCheck.h" #include "ReservedIdentifierCheck.h" +#include "ResetCallCheck.h" #include "ReturnConstRefFromParameterCheck.h" #include "SharedPtrArrayMismatchCheck.h" #include "SignalHandlerCheck.h" @@ -144,6 +145,7 @@ class BugproneModule : public ClangTidyModule { "bugprone-inaccurate-erase"); CheckFactories.registerCheck( "bugprone-incorrect-enable-if"); +CheckFactories.registerCheck("bugprone-reset-call"); CheckFactories.registerCheck( "bugprone-return-const-ref-from-parameter"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 13adad7c3dadbd..17ab5b27ec5550 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -52,6 +52,7 @@ add_clang_library(clangTidyBugproneModule STATIC PosixReturnCheck.cpp RedundantBranchConditionCheck.cpp ReservedIdentifierCheck.cpp + ResetCallCheck.cpp ReturnConstRefFromParameterCheck.cpp SharedPtrArrayMismatchCheck.cpp SignalHandlerCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp new file mode 100644 index 00..305ac8d51adf3e --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ResetCallCheck.cpp @@ -0,0 +1,133 @@ +//===--- ResetCallCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ResetCallCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { + +AST_MATCHER_P(CallExpr, everyArgumentMatches, + ast_matchers::internal::Matcher, InnerMatcher) { + if (Node.getNumArgs() == 0) +return true; + + for (const auto *Arg : Node.arguments()) { +if (!InnerMatcher.matches(*Arg, Finder, Builder)) + return false; + } + return true; +} + +AST_MATCHER(CXXMethodDecl, hasOnlyDefaultArgs) { + if (Node.param_empty()) +return true; + + for (const auto *Param : Node.parameters()) { +if (!Param->hasDefaultArg()) + return false; + } + return true; +} + +} // namespace + +void ResetCallCheck::registerMatchers(MatchFinder *Finder) { + const auto IsSmartptr = hasAnyName("::std::unique_ptr", "::std::shared_ptr"); + + const auto ResetMethod = + cxxMethodDecl(hasName("reset"), hasOnlyDefaultArgs()); + + const auto TypeWithReset = + anyOf(cxxRecordDecl(hasMethod(ResetMethod)), +classTemplateSpecializationDecl( +hasSpecializedTemplate(classTemplateDecl(has(ResetMethod); + + const auto SmartptrWithBugproneReset = classTemplateSpecializationDecl( + IsSmartptr, + hasTemplateArgument( + 0, templateArgument(refersToType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(TypeWithReset))); + + // Find a.reset() calls + Finder->addMatcher( + cxxMemberCallExpr(callee(memberExpr(member(hasName("reset", +
[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)
@@ -0,0 +1,48 @@ +.. title:: clang-tidy - bugprone-smartptr-reset-ambiguous-call + +bugprone-smartptr-reset-ambiguous-call +== + +Finds potentially erroneous calls to ``reset`` method on vbvictor wrote: Done https://github.com/llvm/llvm-project/pull/121291 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/122951 >From 841cfec5a0ab4ce5ce64e71facfb7becaf4340e8 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 14 Jan 2025 22:05:43 +0300 Subject: [PATCH 1/6] [clang-tidy] add AllowedTypes to misc-const-correctness --- .../clang-tidy/misc/ConstCorrectnessCheck.cpp | 18 +- .../clang-tidy/misc/ConstCorrectnessCheck.h | 2 + clang-tools-extra/docs/ReleaseNotes.rst | 5 + .../checks/misc/const-correctness.rst | 10 + .../misc/const-correctness-allowed-types.cpp | 180 ++ 5 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-allowed-types.cpp diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index 71a4cee4bdc6ef..aee4a3b789863c 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -8,6 +8,8 @@ #include "ConstCorrectnessCheck.h" #include "../utils/FixItHintUtils.h" +#include "../utils/Matchers.h" +#include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -41,7 +43,9 @@ ConstCorrectnessCheck::ConstCorrectnessCheck(StringRef Name, TransformValues(Options.get("TransformValues", true)), TransformReferences(Options.get("TransformReferences", true)), TransformPointersAsValues( - Options.get("TransformPointersAsValues", false)) { + Options.get("TransformPointersAsValues", false)), + AllowedTypes( + utils::options::parseStringList(Options.get("AllowedTypes", ""))) { if (AnalyzeValues == false && AnalyzeReferences == false) this->configurationDiag( "The check 'misc-const-correctness' will not " @@ -57,6 +61,9 @@ void ConstCorrectnessCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "TransformValues", TransformValues); Options.store(Opts, "TransformReferences", TransformReferences); Options.store(Opts, "TransformPointersAsValues", TransformPointersAsValues); + + Options.store(Opts, "AllowedTypes", +utils::options::serializeStringList(AllowedTypes)); } void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { @@ -73,6 +80,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType(), hasType(referenceType(pointee(substTemplateTypeParmType(); + const auto AllowedType = hasType(qualType(anyOf( + hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + pointerType(pointee(hasDeclaration( + namedDecl(matchers::matchesAnyListedName(AllowedTypes; + const auto AutoTemplateType = varDecl( anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType(, hasType(pointerType(pointee(autoType()); @@ -87,7 +100,8 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { unless(anyOf(ConstType, ConstReference, TemplateType, hasInitializer(isInstantiationDependent()), AutoTemplateType, RValueReference, FunctionPointerRef, - hasType(cxxRecordDecl(isLambda())), isImplicit(; + hasType(cxxRecordDecl(isLambda())), isImplicit(), + AllowedType))); // Match the function scope for which the analysis of all local variables // shall be run. diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h index bba060e555d001..3b7aba7c4be384 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h @@ -45,6 +45,8 @@ class ConstCorrectnessCheck : public ClangTidyCheck { const bool TransformValues; const bool TransformReferences; const bool TransformPointersAsValues; + + const std::vector AllowedTypes; }; } // namespace clang::tidy::misc diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index fa3a8e577a33ad..16be70ca944e95 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -260,6 +260,11 @@ Changes in existing checks ` check to report a location even when the member location is not valid. +- Improved :doc:`misc-const-correctness + ` check by adding + the option ``AllowedTypes``, that excludes specified types + from const-correctness checking. + - Improved :doc:`misc-definitions-in-headers ` check by rewording the diagnostic note that suggests adding ``inline``. diff --git a/clang
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
@@ -196,3 +196,12 @@ Options // The following pointer may not become a 'int *const'. int *changing_pointee = &value; changing_pointee = &result; + +.. option:: AllowedTypes (default = '') vbvictor wrote: Placed default in last sentence. https://github.com/llvm/llvm-project/pull/122951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
vbvictor wrote: > Please also fix preceding option defaults. Fixed preceding option defaults https://github.com/llvm/llvm-project/pull/122951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
vbvictor wrote: > Can anyone please help me? Why is Test Documentation build is failing? I am > in no clue. Restore clang-tools-extra/clang-tidy/modernize/CMakeLists.txt and clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp as they were before (with no changes to them). https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
@@ -0,0 +1,40 @@ +//===--- UseCppStyleCommentsCheck.h - clang-tidy---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_CPP_STYLE_COMMENTS_CHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_CPP_STYLE_COMMENTS_CHECK_H + +#include "../ClangTidyCheck.h" +#include vbvictor wrote: Thank you for pointing out, I didn't see usage in header file https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
@@ -196,3 +196,12 @@ Options // The following pointer may not become a 'int *const'. int *changing_pointee = &value; changing_pointee = &result; + +.. option:: AllowedTypes (default = '') vbvictor wrote: In this file all the options has default in its names. I assumed that I should stick to the style of the file. Maybe It's better to leave this as is and create a new PR with fixes for all options, what do you think? https://github.com/llvm/llvm-project/pull/122951 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] add AllowedTypes option to misc-const-correctness (PR #122951)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/122951 >From 841cfec5a0ab4ce5ce64e71facfb7becaf4340e8 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 14 Jan 2025 22:05:43 +0300 Subject: [PATCH 1/7] [clang-tidy] add AllowedTypes to misc-const-correctness --- .../clang-tidy/misc/ConstCorrectnessCheck.cpp | 18 +- .../clang-tidy/misc/ConstCorrectnessCheck.h | 2 + clang-tools-extra/docs/ReleaseNotes.rst | 5 + .../checks/misc/const-correctness.rst | 10 + .../misc/const-correctness-allowed-types.cpp | 180 ++ 5 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-allowed-types.cpp diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index 71a4cee4bdc6ef..aee4a3b789863c 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -8,6 +8,8 @@ #include "ConstCorrectnessCheck.h" #include "../utils/FixItHintUtils.h" +#include "../utils/Matchers.h" +#include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -41,7 +43,9 @@ ConstCorrectnessCheck::ConstCorrectnessCheck(StringRef Name, TransformValues(Options.get("TransformValues", true)), TransformReferences(Options.get("TransformReferences", true)), TransformPointersAsValues( - Options.get("TransformPointersAsValues", false)) { + Options.get("TransformPointersAsValues", false)), + AllowedTypes( + utils::options::parseStringList(Options.get("AllowedTypes", ""))) { if (AnalyzeValues == false && AnalyzeReferences == false) this->configurationDiag( "The check 'misc-const-correctness' will not " @@ -57,6 +61,9 @@ void ConstCorrectnessCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "TransformValues", TransformValues); Options.store(Opts, "TransformReferences", TransformReferences); Options.store(Opts, "TransformPointersAsValues", TransformPointersAsValues); + + Options.store(Opts, "AllowedTypes", +utils::options::serializeStringList(AllowedTypes)); } void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { @@ -73,6 +80,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType(), hasType(referenceType(pointee(substTemplateTypeParmType(); + const auto AllowedType = hasType(qualType(anyOf( + hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))), + pointerType(pointee(hasDeclaration( + namedDecl(matchers::matchesAnyListedName(AllowedTypes; + const auto AutoTemplateType = varDecl( anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType(, hasType(pointerType(pointee(autoType()); @@ -87,7 +100,8 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { unless(anyOf(ConstType, ConstReference, TemplateType, hasInitializer(isInstantiationDependent()), AutoTemplateType, RValueReference, FunctionPointerRef, - hasType(cxxRecordDecl(isLambda())), isImplicit(; + hasType(cxxRecordDecl(isLambda())), isImplicit(), + AllowedType))); // Match the function scope for which the analysis of all local variables // shall be run. diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h index bba060e555d001..3b7aba7c4be384 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.h @@ -45,6 +45,8 @@ class ConstCorrectnessCheck : public ClangTidyCheck { const bool TransformValues; const bool TransformReferences; const bool TransformPointersAsValues; + + const std::vector AllowedTypes; }; } // namespace clang::tidy::misc diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index fa3a8e577a33ad..16be70ca944e95 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -260,6 +260,11 @@ Changes in existing checks ` check to report a location even when the member location is not valid. +- Improved :doc:`misc-const-correctness + ` check by adding + the option ``AllowedTypes``, that excludes specified types + from const-correctness checking. + - Improved :doc:`misc-definitions-in-headers ` check by rewording the diagnostic note that suggests adding ``inline``. diff --git a/clang
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
vbvictor wrote: As @PiotrZSL mentioned in the issue, adding an option called `ExcludeDoxygenStyleComments` would be very helpful (or even necessary) before releasing this check. Otherwise, it could create a lot of trouble for projects that use doxygen for their documentation (including LLVM itself). Doxygen comments typically look like this: ```cpp /** * ... text ... */ void foo() ``` With this option enabled, I think we should exclude the following cases: ```cpp /** * ... text ... */ /*! * ... text ... */ /*** * ... text ***/ ``` Basically, they are comments that start with `/*` followed by more than one `*` or `/*!` More detailed documentation can be found in https://www.doxygen.nl/manual/docblocks.html. This option can also be tested on LLVM codebase for false positives. https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Refactor: removed typos in 'AllowedTypes' option in various checks (PR #122957)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/122957 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Refactor: removed typos in 'AllowedTypes' option in various checks (PR #122957)
@@ -31,6 +31,6 @@ Options A semicolon-separated list of names of types allowed to be copied in each iteration. Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches every type with suffix `Ref`, `ref`, `Reference` and `reference`. The default vbvictor wrote: @nicovank, yes, I can make this change. As far as I understand only _Ref_, _ref_, _Reference_ and _reference_ should be changed but not _[Rr]ef(erence)?$_. It got a little tricky for me since _Ref_ only refers to a suffix of potential c++ type, so it doesn't fall in double back-ticks category. https://github.com/llvm/llvm-project/pull/122957 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Refactor: removed typos in 'AllowedTypes' option in various checks (PR #122957)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/122957 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
@@ -146,6 +147,8 @@ class ReadabilityModule : public ClangTidyModule { "readability-static-definition-in-anonymous-namespace"); CheckFactories.registerCheck( "readability-string-compare"); +CheckFactories.registerCheck( vbvictor wrote: Please sort alphabetically https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
https://github.com/vbvictor edited https://github.com/llvm/llvm-project/pull/124319 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Refactor: removed typos in 'AllowedTypes' option in various checks (PR #122957)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/122957 >From 9c49e1e558c43d13872afe0a10345e3510afebdf Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Tue, 14 Jan 2025 22:30:03 +0300 Subject: [PATCH 1/3] [clang-tidy] Fix: typos in 'AllowedTypes' option in various checks --- .../docs/clang-tidy/checks/performance/for-range-copy.rst | 2 +- .../checks/performance/unnecessary-copy-initialization.rst | 2 +- .../clang-tidy/checks/performance/unnecessary-value-param.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst index 01fde9580e2a08..9460802bf4eab4 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst @@ -32,5 +32,5 @@ Options iteration. Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches every type with suffix `Ref`, `ref`, `Reference` and `reference`. The default is empty. If a name in the list contains the sequence `::` it is matched - against the qualified typename (i.e. `namespace::Type`, otherwise it is + against the qualified typename (i.e. `namespace::Type`), otherwise it is matched against only the type name (i.e. `Type`). diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-copy-initialization.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-copy-initialization.rst index 837283811ddcce..4ad9dac3e38f66 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-copy-initialization.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-copy-initialization.rst @@ -45,7 +45,7 @@ Options copying. Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches every type with suffix `Ref`, `ref`, `Reference` and `reference`. The default is empty. If a name in the list contains the sequence `::` it is matched - against the qualified typename (i.e. `namespace::Type`, otherwise it is + against the qualified typename (i.e. `namespace::Type`), otherwise it is matched against only the type name (i.e. `Type`). .. option:: ExcludedContainerTypes diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst index cc5e1ae73508c5..330ef960e9a3bb 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst @@ -68,5 +68,5 @@ Options Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches every type with suffix `Ref`, `ref`, `Reference` and `reference`. The default is empty. If a name in the list contains the sequence `::` it is matched against - the qualified typename (i.e. `namespace::Type`, otherwise it is matched + the qualified typename (i.e. `namespace::Type`), otherwise it is matched against only the type name (i.e. `Type`). >From be68e91708bd122e74b03d559796f22a94628155 Mon Sep 17 00:00:00 2001 From: Baranov Victor Date: Wed, 15 Jan 2025 20:31:44 +0300 Subject: [PATCH 2/3] [clang-tidy] more fixes to docs --- .../docs/clang-tidy/checks/performance/for-range-copy.rst | 6 +++--- .../checks/performance/unnecessary-copy-initialization.rst | 6 +++--- .../checks/performance/unnecessary-value-param.rst | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst index 9460802bf4eab4..cd1b8daacee107 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst @@ -31,6 +31,6 @@ Options A semicolon-separated list of names of types allowed to be copied in each iteration. Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches every type with suffix `Ref`, `ref`, `Reference` and `reference`. The default - is empty. If a name in the list contains the sequence `::` it is matched - against the qualified typename (i.e. `namespace::Type`), otherwise it is - matched against only the type name (i.e. `Type`). + is empty. If a name in the list contains the sequence `::`, it is matched + against the qualified type name (i.e. ``namespace::Type``), otherwise it is + matched against only the type name (i.e. ``Type``). diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-copy-initialization.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-copy-initialization.rst index 4ad9dac3e38f66..45c91cd56218df 100644 --- a/clang-tools-extra/docs
[clang-tools-extra] [clang-tidy] Refactor: removed typos in 'AllowedTypes' option in various checks (PR #122957)
@@ -31,6 +31,6 @@ Options A semicolon-separated list of names of types allowed to be copied in each iteration. Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches every type with suffix `Ref`, `ref`, `Reference` and `reference`. The default vbvictor wrote: Corrected to double-ticks plus found one more file with same errors: `clang-tools-extra/docs/clang-tidy/checks/bugprone/assert-side-effect.rst` https://github.com/llvm/llvm-project/pull/122957 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/123413 >From f5f0ba142a2eb71ce781faf4e15fcd225bec9ca8 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sat, 18 Jan 2025 00:49:29 +0300 Subject: [PATCH 1/3] [clang-tidy] Added support for 3-argument string ctor --- .../bugprone/StringConstructorCheck.cpp | 50 +-- clang-tools-extra/docs/ReleaseNotes.rst | 5 ++ .../checkers/bugprone/string-constructor.cpp | 30 +++ 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 8ae4351ac2830a..d1902b658061b1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -82,7 +82,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxConstructExpr( hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(0, hasType(qualType(isInteger(, + argumentCountIs(2), hasArgument(0, hasType(qualType(isInteger(, hasArgument(1, hasType(qualType(isInteger(, anyOf( // Detect the expression: string('x', 40); @@ -102,7 +102,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { cxxConstructExpr( hasDeclaration(cxxConstructorDecl(ofClass( cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), - hasArgument(0, hasType(CharPtrType)), + argumentCountIs(2), hasArgument(0, hasType(CharPtrType)), hasArgument(1, hasType(isInteger())), anyOf( // Detect the expression: string("...", 0); @@ -114,7 +114,34 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { // Detect the expression: string("lit", 5) allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), hasArgument(1, ignoringParenImpCasts( - integerLiteral().bind("int")) + integerLiteral().bind("length")) + .bind("constructor"), + this); + + // Check the literal string constructor with char pointer, start position and + // length parameters. [i.e. string (const char* s, size_t pos, size_t count);] + Finder->addMatcher( + cxxConstructExpr( + hasDeclaration(cxxConstructorDecl(ofClass( + cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), + argumentCountIs(3), hasArgument(0, hasType(CharPtrType)), + hasArgument(1, hasType(qualType(isInteger(, + hasArgument(2, hasType(qualType(isInteger(, + anyOf( + // Detect the expression: string("...", 1, 0); + hasArgument(2, ZeroExpr.bind("empty-string")), + // Detect the expression: string("...", -4, 1); + hasArgument(1, NegativeExpr.bind("negative-pos")), + // Detect the expression: string("...", 0, -4); + hasArgument(2, NegativeExpr.bind("negative-length")), + // Detect the expression: string("lit", 0, 0x1234567); + hasArgument(2, LargeLengthExpr.bind("large-length")), + // Detect the expression: string("lit", 1, 5) + allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), +hasArgument( +1, ignoringParenImpCasts(integerLiteral().bind("pos"))), +hasArgument(2, ignoringParenImpCasts( + integerLiteral().bind("length")) .bind("constructor"), this); @@ -155,14 +182,27 @@ void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { diag(Loc, "constructor creating an empty string"); } else if (Result.Nodes.getNodeAs("negative-length")) { diag(Loc, "negative value used as length parameter"); + } else if (Result.Nodes.getNodeAs("negative-pos")) { +diag(Loc, "negative value used as position of the " + "first character parameter"); } else if (Result.Nodes.getNodeAs("large-length")) { if (WarnOnLargeLength) diag(Loc, "suspicious large length parameter"); } else if (Result.Nodes.getNodeAs("literal-with-length")) { const auto *Str = Result.Nodes.getNodeAs("str"); -const auto *Lit = Result.Nodes.getNodeAs("int"); -if (Lit->getValue().ugt(Str->getLength())) { +const auto *Length = Result.Nodes.getNodeAs("length"); +if (Length->getValue().ugt(Str->getLength())) { diag(Loc, "length is bigger than string literal size"); + return; +} +if (const auto *Pos = Result.Nodes.getNodeAs("pos")) { + if (Pos->getValue().uge(Str->getLength())) { +diag(Loc, "position of the first charact
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/123413 >From bc85c10a7d316630843266779cb1465b02d3dbf6 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sat, 18 Jan 2025 00:49:29 +0300 Subject: [PATCH 1/4] [clang-tidy] Added support for 3-argument string ctor --- .../bugprone/StringConstructorCheck.cpp | 50 - clang-tools-extra/docs/ReleaseNotes.rst | 182 ++ .../checkers/bugprone/string-constructor.cpp | 30 +++ 3 files changed, 257 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 8ae4351ac2830a..d1902b658061b1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -82,7 +82,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxConstructExpr( hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(0, hasType(qualType(isInteger(, + argumentCountIs(2), hasArgument(0, hasType(qualType(isInteger(, hasArgument(1, hasType(qualType(isInteger(, anyOf( // Detect the expression: string('x', 40); @@ -102,7 +102,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { cxxConstructExpr( hasDeclaration(cxxConstructorDecl(ofClass( cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), - hasArgument(0, hasType(CharPtrType)), + argumentCountIs(2), hasArgument(0, hasType(CharPtrType)), hasArgument(1, hasType(isInteger())), anyOf( // Detect the expression: string("...", 0); @@ -114,7 +114,34 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { // Detect the expression: string("lit", 5) allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), hasArgument(1, ignoringParenImpCasts( - integerLiteral().bind("int")) + integerLiteral().bind("length")) + .bind("constructor"), + this); + + // Check the literal string constructor with char pointer, start position and + // length parameters. [i.e. string (const char* s, size_t pos, size_t count);] + Finder->addMatcher( + cxxConstructExpr( + hasDeclaration(cxxConstructorDecl(ofClass( + cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), + argumentCountIs(3), hasArgument(0, hasType(CharPtrType)), + hasArgument(1, hasType(qualType(isInteger(, + hasArgument(2, hasType(qualType(isInteger(, + anyOf( + // Detect the expression: string("...", 1, 0); + hasArgument(2, ZeroExpr.bind("empty-string")), + // Detect the expression: string("...", -4, 1); + hasArgument(1, NegativeExpr.bind("negative-pos")), + // Detect the expression: string("...", 0, -4); + hasArgument(2, NegativeExpr.bind("negative-length")), + // Detect the expression: string("lit", 0, 0x1234567); + hasArgument(2, LargeLengthExpr.bind("large-length")), + // Detect the expression: string("lit", 1, 5) + allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), +hasArgument( +1, ignoringParenImpCasts(integerLiteral().bind("pos"))), +hasArgument(2, ignoringParenImpCasts( + integerLiteral().bind("length")) .bind("constructor"), this); @@ -155,14 +182,27 @@ void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { diag(Loc, "constructor creating an empty string"); } else if (Result.Nodes.getNodeAs("negative-length")) { diag(Loc, "negative value used as length parameter"); + } else if (Result.Nodes.getNodeAs("negative-pos")) { +diag(Loc, "negative value used as position of the " + "first character parameter"); } else if (Result.Nodes.getNodeAs("large-length")) { if (WarnOnLargeLength) diag(Loc, "suspicious large length parameter"); } else if (Result.Nodes.getNodeAs("literal-with-length")) { const auto *Str = Result.Nodes.getNodeAs("str"); -const auto *Lit = Result.Nodes.getNodeAs("int"); -if (Lit->getValue().ugt(Str->getLength())) { +const auto *Length = Result.Nodes.getNodeAs("length"); +if (Length->getValue().ugt(Str->getLength())) { diag(Loc, "length is bigger than string literal size"); + return; +} +if (const auto *Pos = Result.Nodes.getNodeAs("pos")) { + if (Pos->getValue().uge(Str->getLength())) { +diag(Loc, "position of the first character
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
vbvictor wrote: @HerrCai0907, sorry to bother you, but can you help merge this pr if it is okay to have only one review (from you). I can keep pinging others but don't understand how many people need to watch it. Some other pull requests were merged with some reviewers still being in "awaiting" status. https://github.com/llvm/llvm-project/pull/123413 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added support for 3-argument std::string ctor in bugprone-string-constructor check (PR #123413)
https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/123413 >From bc85c10a7d316630843266779cb1465b02d3dbf6 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Sat, 18 Jan 2025 00:49:29 +0300 Subject: [PATCH 1/5] [clang-tidy] Added support for 3-argument string ctor --- .../bugprone/StringConstructorCheck.cpp | 50 - clang-tools-extra/docs/ReleaseNotes.rst | 182 ++ .../checkers/bugprone/string-constructor.cpp | 30 +++ 3 files changed, 257 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 8ae4351ac2830a..d1902b658061b1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -82,7 +82,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxConstructExpr( hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(0, hasType(qualType(isInteger(, + argumentCountIs(2), hasArgument(0, hasType(qualType(isInteger(, hasArgument(1, hasType(qualType(isInteger(, anyOf( // Detect the expression: string('x', 40); @@ -102,7 +102,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { cxxConstructExpr( hasDeclaration(cxxConstructorDecl(ofClass( cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), - hasArgument(0, hasType(CharPtrType)), + argumentCountIs(2), hasArgument(0, hasType(CharPtrType)), hasArgument(1, hasType(isInteger())), anyOf( // Detect the expression: string("...", 0); @@ -114,7 +114,34 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { // Detect the expression: string("lit", 5) allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), hasArgument(1, ignoringParenImpCasts( - integerLiteral().bind("int")) + integerLiteral().bind("length")) + .bind("constructor"), + this); + + // Check the literal string constructor with char pointer, start position and + // length parameters. [i.e. string (const char* s, size_t pos, size_t count);] + Finder->addMatcher( + cxxConstructExpr( + hasDeclaration(cxxConstructorDecl(ofClass( + cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)), + argumentCountIs(3), hasArgument(0, hasType(CharPtrType)), + hasArgument(1, hasType(qualType(isInteger(, + hasArgument(2, hasType(qualType(isInteger(, + anyOf( + // Detect the expression: string("...", 1, 0); + hasArgument(2, ZeroExpr.bind("empty-string")), + // Detect the expression: string("...", -4, 1); + hasArgument(1, NegativeExpr.bind("negative-pos")), + // Detect the expression: string("...", 0, -4); + hasArgument(2, NegativeExpr.bind("negative-length")), + // Detect the expression: string("lit", 0, 0x1234567); + hasArgument(2, LargeLengthExpr.bind("large-length")), + // Detect the expression: string("lit", 1, 5) + allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), +hasArgument( +1, ignoringParenImpCasts(integerLiteral().bind("pos"))), +hasArgument(2, ignoringParenImpCasts( + integerLiteral().bind("length")) .bind("constructor"), this); @@ -155,14 +182,27 @@ void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { diag(Loc, "constructor creating an empty string"); } else if (Result.Nodes.getNodeAs("negative-length")) { diag(Loc, "negative value used as length parameter"); + } else if (Result.Nodes.getNodeAs("negative-pos")) { +diag(Loc, "negative value used as position of the " + "first character parameter"); } else if (Result.Nodes.getNodeAs("large-length")) { if (WarnOnLargeLength) diag(Loc, "suspicious large length parameter"); } else if (Result.Nodes.getNodeAs("literal-with-length")) { const auto *Str = Result.Nodes.getNodeAs("str"); -const auto *Lit = Result.Nodes.getNodeAs("int"); -if (Lit->getValue().ugt(Str->getLength())) { +const auto *Length = Result.Nodes.getNodeAs("length"); +if (Length->getValue().ugt(Str->getLength())) { diag(Loc, "length is bigger than string literal size"); + return; +} +if (const auto *Pos = Result.Nodes.getNodeAs("pos")) { + if (Pos->getValue().uge(Str->getLength())) { +diag(Loc, "position of the first character