[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)
@@ -14277,6 +14325,113 @@ StmtResult Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, : IdentLoc); } +static ImplicitConversionKind GetConversionKind(QualType FromType, Fznamznon wrote: @AaronBallman , I think I could reuse `IsStandardConversion` to build `StandardConversionSequence` object and call it from `InitializationSequence::Perform`, so `InitializationSequence` will take care of the recursion. https://github.com/llvm/llvm-project/pull/73099 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)
https://github.com/Fznamznon edited https://github.com/llvm/llvm-project/pull/73099 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)
https://github.com/Fznamznon edited https://github.com/llvm/llvm-project/pull/73099 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add new check `modernize-use-designated-initializers` (PR #80541)
SimplyDanny wrote: I don't get why the Windows tests are failing. 🤔 Can you give me a hint maybe, @PiotrZSL? https://github.com/llvm/llvm-project/pull/80541 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 22734e1 - [Clang][AArch64] Fix 'svzero_za' intrinsic to take no arguments. (#82648)
Author: Sander de Smalen Date: 2024-02-23T11:31:24Z New Revision: 22734e15d8f2c437e8543f19632299d2e09b31f3 URL: https://github.com/llvm/llvm-project/commit/22734e15d8f2c437e8543f19632299d2e09b31f3 DIFF: https://github.com/llvm/llvm-project/commit/22734e15d8f2c437e8543f19632299d2e09b31f3.diff LOG: [Clang][AArch64] Fix 'svzero_za' intrinsic to take no arguments. (#82648) We previously defined svzero_za as: void svzero_za(); rather than: void svzero_za(void); Which meant that Clang accepted arguments. Compiling for example `svzero_za()` ended up with incorrect IR and a compiler crash because it couldn't select an instruction for it. Added: clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c Modified: clang/include/clang/Basic/arm_sme.td Removed: diff --git a/clang/include/clang/Basic/arm_sme.td b/clang/include/clang/Basic/arm_sme.td index 2da0e8d2aba9a4..1ac6d5170ea283 100644 --- a/clang/include/clang/Basic/arm_sme.td +++ b/clang/include/clang/Basic/arm_sme.td @@ -142,7 +142,7 @@ let TargetGuard = "sme" in { def SVZERO_MASK_ZA : SInst<"svzero_mask_za", "vi", "", MergeNone, "aarch64_sme_zero", [IsOverloadNone, IsStreamingCompatible, IsInOutZA], [ImmCheck<0, ImmCheck0_255>]>; - def SVZERO_ZA : SInst<"svzero_za", "v", "", MergeNone, "aarch64_sme_zero", + def SVZERO_ZA : SInst<"svzero_za", "vv", "", MergeNone, "aarch64_sme_zero", [IsOverloadNone, IsStreamingCompatible, IsOutZA]>; } diff --git a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c new file mode 100644 index 00..e0b6c391d98902 --- /dev/null +++ b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -fsyntax-only -verify %s + +void test_svzero_args(uint64_t m) { + svzero_za(0); // expected-error {{too many arguments to function call, expected 0, have 1}} + svzero_za(m); // expected-error {{too many arguments to function call, expected 0, have 1}} + svzero_mask_za(m); // expected-error {{argument to 'svzero_mask_za' must be a constant integer}} +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][AArch64] Fix 'svzero_za' intrinsic to take no arguments. (PR #82648)
https://github.com/sdesmalen-arm closed https://github.com/llvm/llvm-project/pull/82648 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3c90fce - [Clang][AArch64] Add missing prototypes for streaming-compatible routines (#82649)
Author: Sander de Smalen Date: 2024-02-23T11:31:53Z New Revision: 3c90fce4504e22953ec5586599afaecfb2923a9e URL: https://github.com/llvm/llvm-project/commit/3c90fce4504e22953ec5586599afaecfb2923a9e DIFF: https://github.com/llvm/llvm-project/commit/3c90fce4504e22953ec5586599afaecfb2923a9e.diff LOG: [Clang][AArch64] Add missing prototypes for streaming-compatible routines (#82649) Added: Modified: clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_state_funs.c clang/utils/TableGen/SveEmitter.cpp Removed: diff --git a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_state_funs.c b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_state_funs.c index dc07efbb816038..e80a965394e7f0 100644 --- a/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_state_funs.c +++ b/clang/test/CodeGen/aarch64-sme-intrinsics/acle_sme_state_funs.c @@ -28,12 +28,12 @@ bool test_in_streaming_mode(void) __arm_streaming_compatible { // CHECK-LABEL: @test_za_disable( // CHECK-NEXT: entry: -// CHECK-NEXT:tail call void @__arm_za_disable() #[[ATTR4:[0-9]+]] +// CHECK-NEXT:tail call void @__arm_za_disable() #[[ATTR3]] // CHECK-NEXT:ret void // // CPP-CHECK-LABEL: @_Z15test_za_disablev( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT:tail call void @__arm_za_disable() #[[ATTR4:[0-9]+]] +// CPP-CHECK-NEXT:tail call void @__arm_za_disable() #[[ATTR3]] // CPP-CHECK-NEXT:ret void // void test_za_disable(void) __arm_streaming_compatible { @@ -70,3 +70,58 @@ void test_svundef_za(void) __arm_streaming_compatible __arm_out("za") { svundef_za(); } +// CHECK-LABEL: @test_sc_memcpy( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[CALL:%.*]] = tail call ptr @__arm_sc_memcpy(ptr noundef [[DEST:%.*]], ptr noundef [[SRC:%.*]], i64 noundef [[N:%.*]]) #[[ATTR3]] +// CHECK-NEXT:ret ptr [[CALL]] +// +// CPP-CHECK-LABEL: @_Z14test_sc_memcpyPvPKvm( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT:[[CALL:%.*]] = tail call ptr @__arm_sc_memcpy(ptr noundef [[DEST:%.*]], ptr noundef [[SRC:%.*]], i64 noundef [[N:%.*]]) #[[ATTR3]] +// CPP-CHECK-NEXT:ret ptr [[CALL]] +// +void *test_sc_memcpy(void *dest, const void *src, size_t n) __arm_streaming_compatible { + return __arm_sc_memcpy(dest, src, n); +} + +// CHECK-LABEL: @test_sc_memmove( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[CALL:%.*]] = tail call ptr @__arm_sc_memmove(ptr noundef [[DEST:%.*]], ptr noundef [[SRC:%.*]], i64 noundef [[N:%.*]]) #[[ATTR3]] +// CHECK-NEXT:ret ptr [[CALL]] +// +// CPP-CHECK-LABEL: @_Z15test_sc_memmovePvPKvm( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT:[[CALL:%.*]] = tail call ptr @__arm_sc_memmove(ptr noundef [[DEST:%.*]], ptr noundef [[SRC:%.*]], i64 noundef [[N:%.*]]) #[[ATTR3]] +// CPP-CHECK-NEXT:ret ptr [[CALL]] +// +void *test_sc_memmove(void *dest, const void *src, size_t n) __arm_streaming_compatible { + return __arm_sc_memmove(dest, src, n); +} + +// CHECK-LABEL: @test_sc_memset( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[CALL:%.*]] = tail call ptr @__arm_sc_memset(ptr noundef [[S:%.*]], i32 noundef [[C:%.*]], i64 noundef [[N:%.*]]) #[[ATTR3]] +// CHECK-NEXT:ret ptr [[CALL]] +// +// CPP-CHECK-LABEL: @_Z14test_sc_memsetPvim( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT:[[CALL:%.*]] = tail call ptr @__arm_sc_memset(ptr noundef [[S:%.*]], i32 noundef [[C:%.*]], i64 noundef [[N:%.*]]) #[[ATTR3]] +// CPP-CHECK-NEXT:ret ptr [[CALL]] +// +void *test_sc_memset(void *s, int c, size_t n) __arm_streaming_compatible { + return __arm_sc_memset(s, c, n); +} + +// CHECK-LABEL: @test_sc_memchr( +// CHECK-NEXT: entry: +// CHECK-NEXT:[[CALL:%.*]] = tail call ptr @__arm_sc_memchr(ptr noundef [[S:%.*]], i32 noundef [[C:%.*]], i64 noundef [[N:%.*]]) #[[ATTR3]] +// CHECK-NEXT:ret ptr [[CALL]] +// +// CPP-CHECK-LABEL: @_Z14test_sc_memchrPvim( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT:[[CALL:%.*]] = tail call ptr @__arm_sc_memchr(ptr noundef [[S:%.*]], i32 noundef [[C:%.*]], i64 noundef [[N:%.*]]) #[[ATTR3]] +// CPP-CHECK-NEXT:ret ptr [[CALL]] +// +void *test_sc_memchr(void *s, int c, size_t n) __arm_streaming_compatible { + return __arm_sc_memchr(s, c, n); +} diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp index 174304f09007bf..131397e3825b02 100644 --- a/clang/utils/TableGen/SveEmitter.cpp +++ b/clang/utils/TableGen/SveEmitter.cpp @@ -1579,6 +1579,7 @@ void SVEEmitter::createSMEHeader(raw_ostream &OS) { OS << "#endif\n"; OS << "#include \n\n"; + OS << "#include \n\n"; OS << "/* Function attributes */\n"; OS << "#define __ai static __inline__ __attribute__((__always_inline__, " @@ -1605,6 +1606,11 @@ void SVEEmitter::createSMEHeader(raw_ostream &OS) { OS << " return x0 & 1;\n"; OS << "}\n\n"; + OS << "void *__arm_sc_memcpy(void *dest, const void *src, size_t n) __arm_streaming_compatible;\n"; + OS << "
[clang] [Clang][AArch64] Add missing prototypes for streaming-compatible routines (PR #82649)
https://github.com/sdesmalen-arm closed https://github.com/llvm/llvm-project/pull/82649 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)
5chmidti wrote: I'd like to see the diagnostics say `forwarded` instead of `moved` (for all 4 possible diagnostics). `after it was potentially moved by forwarding` could work as well. Otherwise, the changes themselves look good https://github.com/llvm/llvm-project/pull/82673 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] cdf19d1 - [Clang] Fix acle_sme_zero.c (missing aarch64-registered-target)
Author: Sander de Smalen Date: 2024-02-23T11:43:55Z New Revision: cdf19d13bf39f0679c3636eada87a5645f9a4c84 URL: https://github.com/llvm/llvm-project/commit/cdf19d13bf39f0679c3636eada87a5645f9a4c84 DIFF: https://github.com/llvm/llvm-project/commit/cdf19d13bf39f0679c3636eada87a5645f9a4c84.diff LOG: [Clang] Fix acle_sme_zero.c (missing aarch64-registered-target) This test was added in #82648 Added: Modified: clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c Removed: diff --git a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c index e0b6c391d98902..8ea80bc6568fec 100644 --- a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c +++ b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c @@ -1,3 +1,4 @@ +// REQUIRES: aarch64-registered-target // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -fsyntax-only -verify %s void test_svzero_args(uint64_t m) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Disable generation of asynchronous unwind tables for RISCV baremetal (PR #81727)
quic-garvgupt wrote: ping! for merging this PR https://github.com/llvm/llvm-project/pull/81727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f1e0392 - [RISCV] Disable generation of asynchronous unwind tables for RISCV baremetal (#81727)
Author: Garvit Gupta Date: 2024-02-23T20:01:58+08:00 New Revision: f1e0392b822e06f39c49df3ba594f4c98f608ba0 URL: https://github.com/llvm/llvm-project/commit/f1e0392b822e06f39c49df3ba594f4c98f608ba0 DIFF: https://github.com/llvm/llvm-project/commit/f1e0392b822e06f39c49df3ba594f4c98f608ba0.diff LOG: [RISCV] Disable generation of asynchronous unwind tables for RISCV baremetal (#81727) The below culprit patch enabled the generation of asynchronous unwind tables (-funwind-tables=2) by default for RISCV for both linux and RISCVToolChain baremetal object. However, since there are 2 baremetal toolchain objects for RISCV, this created a discrepancy between their behavior. Moreover, enabling the generation of asynchronous unwind tables based on whether `-gcc-toolchain` option is present or not doesn't seem to be the best criteria to decide on the same. This patch make the behavior consistent by disabling the unwind tables in RISCVToolChain Baremetal object. Culprit Patch - https://reviews.llvm.org/D145164 Added: Modified: clang/lib/Driver/ToolChains/RISCVToolchain.cpp clang/lib/Driver/ToolChains/RISCVToolchain.h clang/test/Driver/riscv-features.c Removed: diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp index 85beb945cbf6fc..624099d21ae124 100644 --- a/clang/lib/Driver/ToolChains/RISCVToolchain.cpp +++ b/clang/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -86,6 +86,11 @@ RISCVToolChain::GetUnwindLibType(const llvm::opt::ArgList &Args) const { return ToolChain::UNW_None; } +ToolChain::UnwindTableLevel RISCVToolChain::getDefaultUnwindTableLevel( +const llvm::opt::ArgList &Args) const { + return UnwindTableLevel::None; +} + void RISCVToolChain::addClangTargetOptions( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, diff --git a/clang/lib/Driver/ToolChains/RISCVToolchain.h b/clang/lib/Driver/ToolChains/RISCVToolchain.h index cec817ef7190be..fa0aa265d842bb 100644 --- a/clang/lib/Driver/ToolChains/RISCVToolchain.h +++ b/clang/lib/Driver/ToolChains/RISCVToolchain.h @@ -28,6 +28,8 @@ class LLVM_LIBRARY_VISIBILITY RISCVToolChain : public Generic_ELF { RuntimeLibType GetDefaultRuntimeLibType() const override; UnwindLibType GetUnwindLibType(const llvm::opt::ArgList &Args) const override; + UnwindTableLevel + getDefaultUnwindTableLevel(const llvm::opt::ArgList &Args) const override; void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; diff --git a/clang/test/Driver/riscv-features.c b/clang/test/Driver/riscv-features.c index a108383e29fb6b..fc5fb0f27e3af4 100644 --- a/clang/test/Driver/riscv-features.c +++ b/clang/test/Driver/riscv-features.c @@ -41,6 +41,14 @@ // FAST-UNALIGNED-ACCESS: "-target-feature" "+fast-unaligned-access" // NO-FAST-UNALIGNED-ACCESS: "-target-feature" "-fast-unaligned-access" +// RUN: %clang --target=riscv32-unknown-elf --gcc-toolchain="" -### %s 2>&1 | FileCheck %s -check-prefix=NOUWTABLE +// RUN: %clang --target=riscv32-unknown-elf --gcc-toolchain="" -fasynchronous-unwind-tables -### %s 2>&1 | FileCheck %s -check-prefix=UWTABLE +// RUN: %clang --target=riscv64-unknown-elf --gcc-toolchain="" -### %s 2>&1 | FileCheck %s -check-prefix=NOUWTABLE +// RUN: %clang --target=riscv64-unknown-elf --gcc-toolchain="" -fasynchronous-unwind-tables -### %s 2>&1 | FileCheck %s -check-prefix=UWTABLE +// +// UWTABLE: "-funwind-tables=2" +// NOUWTABLE-NOT: "-funwind-tables=2" + // RUN: %clang --target=riscv32-linux -### %s -fsyntax-only 2>&1 \ // RUN: | FileCheck %s -check-prefix=DEFAULT-LINUX // RUN: %clang --target=riscv64-linux -### %s -fsyntax-only 2>&1 \ ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Disable generation of asynchronous unwind tables for RISCV baremetal (PR #81727)
https://github.com/kito-cheng closed https://github.com/llvm/llvm-project/pull/81727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RISCV] Disable generation of asynchronous unwind tables for RISCV baremetal (PR #81727)
github-actions[bot] wrote: @quic-garvgupt Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested by our [build bots](https://lab.llvm.org/buildbot/). If there is a problem with a build, you may recieve a report in an email or a comment on this PR. Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues. How to do this, and the rest of the post-merge process, is covered in detail [here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr). If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of [LLVM development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy). You can fix your changes and open a new PR to merge them again. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! https://github.com/llvm/llvm-project/pull/81727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3b3d097 - [Clang] Fix acle_sme_zero.c once more.
Author: Sander de Smalen Date: 2024-02-23T12:13:14Z New Revision: 3b3d0978c334702114131e4dab549aa25b9f0ad4 URL: https://github.com/llvm/llvm-project/commit/3b3d0978c334702114131e4dab549aa25b9f0ad4 DIFF: https://github.com/llvm/llvm-project/commit/3b3d0978c334702114131e4dab549aa25b9f0ad4.diff LOG: [Clang] Fix acle_sme_zero.c once more. Added: Modified: clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c Removed: diff --git a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c index 8ea80bc6568fec..a852ffa09c60e5 100644 --- a/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c +++ b/clang/test/Sema/aarch64-sme-intrinsics/acle_sme_zero.c @@ -1,6 +1,8 @@ // REQUIRES: aarch64-registered-target // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sve -fsyntax-only -verify %s +#include + void test_svzero_args(uint64_t m) { svzero_za(0); // expected-error {{too many arguments to function call, expected 0, have 1}} svzero_za(m); // expected-error {{too many arguments to function call, expected 0, have 1}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ddb4450 - [ClangFormat] Fix indent in child lines within a macro argument. (#82523)
Author: r4nt Date: 2024-02-23T13:18:00+01:00 New Revision: ddb4450a468072b5c066c29f4821edec4689d500 URL: https://github.com/llvm/llvm-project/commit/ddb4450a468072b5c066c29f4821edec4689d500 DIFF: https://github.com/llvm/llvm-project/commit/ddb4450a468072b5c066c29f4821edec4689d500.diff LOG: [ClangFormat] Fix indent in child lines within a macro argument. (#82523) When reconstructing lines from a macro expansion, make sure that lines at different levels in the expanded code get indented correctly as part of the macro argument. Added: Modified: clang/lib/Format/MacroCallReconstructor.cpp clang/lib/Format/Macros.h clang/lib/Format/UnwrappedLineParser.cpp clang/lib/Format/UnwrappedLineParser.h clang/unittests/Format/FormatTestMacroExpansion.cpp clang/unittests/Format/MacroCallReconstructorTest.cpp Removed: diff --git a/clang/lib/Format/MacroCallReconstructor.cpp b/clang/lib/Format/MacroCallReconstructor.cpp index cbdd1683c54d1a..101acefdfe7a31 100644 --- a/clang/lib/Format/MacroCallReconstructor.cpp +++ b/clang/lib/Format/MacroCallReconstructor.cpp @@ -33,7 +33,7 @@ void forEachToken(const UnwrappedLine &Line, const T &Call, FormatToken *Parent = nullptr) { bool First = true; for (const auto &N : Line.Tokens) { -Call(N.Tok, Parent, First); +Call(N.Tok, Parent, First, Line.Level); First = false; for (const auto &Child : N.Children) forEachToken(Child, Call, N.Tok); @@ -44,7 +44,7 @@ MacroCallReconstructor::MacroCallReconstructor( unsigned Level, const llvm::DenseMap> &ActiveExpansions) -: Level(Level), IdToReconstructed(ActiveExpansions) { +: Result(Level), IdToReconstructed(ActiveExpansions) { Result.Tokens.push_back(std::make_unique()); ActiveReconstructedLines.push_back(&Result); } @@ -52,9 +52,8 @@ MacroCallReconstructor::MacroCallReconstructor( void MacroCallReconstructor::addLine(const UnwrappedLine &Line) { assert(State != Finalized); LLVM_DEBUG(llvm::dbgs() << "MCR: new line...\n"); - forEachToken(Line, [&](FormatToken *Token, FormatToken *Parent, bool First) { -add(Token, Parent, First); - }); + forEachToken(Line, [&](FormatToken *Token, FormatToken *Parent, bool First, + unsigned Level) { add(Token, Parent, First, Level); }); assert(InProgress || finished()); } @@ -62,8 +61,8 @@ UnwrappedLine MacroCallReconstructor::takeResult() && { finalize(); assert(Result.Tokens.size() == 1 && Result.Tokens.front()->Children.size() == 1); - UnwrappedLine Final = - createUnwrappedLine(*Result.Tokens.front()->Children.front(), Level); + UnwrappedLine Final = createUnwrappedLine( + *Result.Tokens.front()->Children.front(), Result.Level); assert(!Final.Tokens.empty()); return Final; } @@ -72,7 +71,8 @@ UnwrappedLine MacroCallReconstructor::takeResult() && { // ExpandedParent in the incoming unwrapped line. \p First specifies whether it // is the first token in a given unwrapped line. void MacroCallReconstructor::add(FormatToken *Token, - FormatToken *ExpandedParent, bool First) { + FormatToken *ExpandedParent, bool First, + unsigned Level) { LLVM_DEBUG( llvm::dbgs() << "MCR: Token: " << Token->TokenText << ", Parent: " << (ExpandedParent ? ExpandedParent->TokenText : "") @@ -102,7 +102,7 @@ void MacroCallReconstructor::add(FormatToken *Token, First = true; } - prepareParent(ExpandedParent, First); + prepareParent(ExpandedParent, First, Level); if (Token->MacroCtx) { // If this token was generated by a macro call, add the reconstructed @@ -129,7 +129,7 @@ void MacroCallReconstructor::add(FormatToken *Token, // is the parent of ActiveReconstructedLines.back() in the reconstructed // unwrapped line. void MacroCallReconstructor::prepareParent(FormatToken *ExpandedParent, - bool NewLine) { + bool NewLine, unsigned Level) { LLVM_DEBUG({ llvm::dbgs() << "ParentMap:\n"; debugParentMap(); @@ -172,7 +172,7 @@ void MacroCallReconstructor::prepareParent(FormatToken *ExpandedParent, } assert(!ActiveReconstructedLines.empty()); ActiveReconstructedLines.back()->Tokens.back()->Children.push_back( -std::make_unique()); +std::make_unique(Level)); ActiveReconstructedLines.push_back( &*ActiveReconstructedLines.back()->Tokens.back()->Children.back()); } else if (parentLine().Tokens.back()->Tok != Parent) { @@ -424,7 +424,8 @@ bool MacroCallReconstructor::processNextReconstructed() { SpelledParentToReconstructedParent[MacroCallStructure.back() .ParentLastToken] = Token; appendToken(Token); -
[clang] [ClangFormat] Fix indent in child lines within a macro argument. (PR #82523)
https://github.com/r4nt closed https://github.com/llvm/llvm-project/pull/82523 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ad49fe3 - [clang][Interp] Don't return success for already failed global variables
Author: Timm Bäder Date: 2024-02-23T14:05:19+01:00 New Revision: ad49fe3e89c3b3950956548f14cdb5c159ba0aec URL: https://github.com/llvm/llvm-project/commit/ad49fe3e89c3b3950956548f14cdb5c159ba0aec DIFF: https://github.com/llvm/llvm-project/commit/ad49fe3e89c3b3950956548f14cdb5c159ba0aec.diff LOG: [clang][Interp] Don't return success for already failed global variables We might be visiting them more than once. We used to return true for second and subsequent cases, just because we had already visited it before. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/SemaCXX/PR20334-std_initializer_list_diagnosis_assertion.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 27e0986192165c..7f97d8ce9fb804 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2510,6 +2510,12 @@ template bool ByteCodeExprGen::visitDecl(const VarDecl *VD) { assert(!VD->isInvalidDecl() && "Trying to constant evaluate an invalid decl"); + // Global variable we've already seen but that's uninitialized means + // evaluating the initializer failed. Just return failure. + if (std::optional Index = P.getGlobal(VD); + Index && !P.getPtrGlobal(*Index).isInitialized()) +return false; + // Create and initialize the variable. if (!this->visitVarDecl(VD)) return false; diff --git a/clang/test/SemaCXX/PR20334-std_initializer_list_diagnosis_assertion.cpp b/clang/test/SemaCXX/PR20334-std_initializer_list_diagnosis_assertion.cpp index ec672089b84aaa..fb1feee01b29f1 100644 --- a/clang/test/SemaCXX/PR20334-std_initializer_list_diagnosis_assertion.cpp +++ b/clang/test/SemaCXX/PR20334-std_initializer_list_diagnosis_assertion.cpp @@ -1,5 +1,8 @@ // RUN: %clang_cc1 -std=c++11 -verify -emit-llvm-only %s // RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s -DCPP98 +// RUN: %clang_cc1 -std=c++11 -verify -emit-llvm-only %s -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s -DCPP98 -fexperimental-new-constant-interpreter + namespace std { template ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libc] [llvm] [openmp] [libc] Rework the GPU build to be a regular target (PR #81921)
jhuber6 wrote: > @jhuber6 , looks like these changes break the following builds > > * https://lab.llvm.org/buildbot/#/builders/235/builds/5630 > > * https://lab.llvm.org/buildbot/#/builders/232/builds/19808 > > > there are a lot of CMake error messages started with > > ``` > CMake Error at cmake/modules/AddLLVM.cmake:631 (set_target_properties): > set_target_properties called with incorrect number of arguments. > Call Stack (most recent call first): > cmake/modules/AddLLVM.cmake:854 (llvm_add_library) > lib/Transforms/Hello/CMakeLists.txt:13 (add_llvm_library) > -- Targeting X86 > -- Targeting NVPTX > CMake Error at CMakeLists.txt:1213 (add_subdirectory): > add_subdirectory given source "/unittest" which is not an existing > directory. > CMake Error at tools/llvm-config/CMakeLists.txt:54 (string): > string sub-command REGEX, mode MATCH needs at least 5 arguments total to > command. > ... > ``` > > would you take care of it? I'll look into it, my guess is that I used `LLVM_DEFAULT_TARGET_TRIPLE` instead of one of the runtime ones or something. https://github.com/llvm/llvm-project/pull/81921 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libc] [llvm] [openmp] [libc] Rework the GPU build to be a regular target (PR #81921)
jhuber6 wrote: @vvereschaka Should be fixed now. https://github.com/llvm/llvm-project/pull/81921 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang-tidy] Add new check `modernize-use-designated-initializers` (PR #80541)
Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= , Danny =?utf-8?q?M=C3=B6sch?= Message-ID: In-Reply-To: PiotrZSL wrote: @SimplyDanny It's crashing on this construction: "S2 s25 = {.i=1, 2};" https://github.com/llvm/llvm-project/pull/80541 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
https://github.com/hokein edited https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -1446,6 +1447,58 @@ namespace { return inherited::TransformFunctionProtoType(TLB, TL); } +QualType TransformInjectedClassNameType(TypeLocBuilder &TLB, +InjectedClassNameTypeLoc TL) { + auto Type = inherited::TransformInjectedClassNameType(TLB, TL); + // Special case for transforming a deduction guide, we return a + // transformed TemplateSpecializationType. + if (Type.isNull() && + SemaRef.CodeSynthesisContexts.back().Kind == + Sema::CodeSynthesisContext::BuildingDeductionGuides) { +// Return a TemplateSpecializationType for transforming a deduction +// guide. +if (auto *ICT = TL.getType()->getAs()) { + auto Type = + inherited::TransformType(ICT->getInjectedSpecializationType()); + TLB.pushTrivial(SemaRef.Context, Type, TL.getNameLoc()); + return Type; +} + } + return Type; +} +// Override the default version to handle a rewrite-template-arg-pack case +// for building a deduction guide. +bool TransformTemplateArgument(const TemplateArgumentLoc &Input, + TemplateArgumentLoc &Output, + bool Uneval = false) { + const TemplateArgument &Arg = Input.getArgument(); + std::vector TArgs; + switch (Arg.getKind()) { + case TemplateArgument::Pack: +// Iterially rewrite the template argument pack, instead of unpacking +// it. +assert( +SemaRef.CodeSynthesisContexts.back().Kind == +Sema::CodeSynthesisContext::BuildingDeductionGuides && +"Transforming a template argument pack is only allowed in building " +"deduction guide"); +for (auto &pack : Arg.getPackAsArray()) { + TemplateArgumentLoc Input = SemaRef.getTrivialTemplateArgumentLoc( + pack, QualType(), SourceLocation{}); + TemplateArgumentLoc Output; + if (!SemaRef.SubstTemplateArgument(Input, TemplateArgs, Output)) +TArgs.push_back(Output.getArgument()); hokein wrote: Good catch. Added the bailout. https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform { SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } +}; - FunctionTemplateDecl *buildDeductionGuide( - TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, - ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, - SourceLocation Loc, SourceLocation LocEnd, - llvm::ArrayRef MaterializedTypedefs = {}) { -DeclarationNameInfo Name(DeductionGuideName, Loc); -ArrayRef Params = -TInfo->getTypeLoc().castAs().getParams(); +// Find all template parameters of the AliasTemplate that appear in the +// given DeducedArgs. +SmallVector +FindAppearedTemplateParamsInAlias(ArrayRef DeducedArgs, + TypeAliasTemplateDecl *AliasTemplate) { + struct FindAppearedTemplateParams + : public RecursiveASTVisitor { +llvm::DenseSet TemplateParamsInAlias; +llvm::DenseSet AppearedTemplateParams; + +FindAppearedTemplateParams(ArrayRef TemplateParamsInAlias) +: TemplateParamsInAlias(TemplateParamsInAlias.begin(), +TemplateParamsInAlias.end()) {} + +bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { + TTP->getIndex(); + MarkAppeared(TTP->getDecl()); + return true; +} +bool VisitDeclRefExpr(DeclRefExpr *DRE) { + MarkAppeared(DRE->getFoundDecl()); + return true; +} -// Build the implicit deduction guide template. -auto *Guide = -CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name, - TInfo->getType(), TInfo, LocEnd, Ctor); -Guide->setImplicit(); -Guide->setParams(Params); +void MarkAppeared(NamedDecl *ND) { + if (TemplateParamsInAlias.contains(ND)) +AppearedTemplateParams.insert(ND); +} + }; + ArrayRef TemplateParamsInAlias = + AliasTemplate->getTemplateParameters()->asArray(); + FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias); + MarkAppeared.TraverseTemplateArguments(DeducedArgs); -for (auto *Param : Params) - Param->setDeclContext(Guide); -for (auto *TD : MaterializedTypedefs) - TD->setDeclContext(Guide); + SmallVector Results; + for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) { +if (MarkAppeared.AppearedTemplateParams.contains( +TemplateParamsInAlias[Index])) + Results.push_back(Index); + } + return Results; +} -auto *GuideTemplate = FunctionTemplateDecl::Create( -SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide); -GuideTemplate->setImplicit(); -Guide->setDescribedFunctionTemplate(GuideTemplate); +bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) { + // Check whether we've already declared deduction guides for this template. + // FIXME: Consider storing a flag on the template to indicate this. + auto Existing = DC->lookup(Name); + for (auto *D : Existing) +if (D->isImplicit()) + return true; + return false; +} -if (isa(DC)) { - Guide->setAccess(AS_public); - GuideTemplate->setAccess(AS_public); +// Build deduction guides for a type alias template. +void DeclareImplicitDeductionGuidesForTypeAlias( +Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) { + auto &Context = SemaRef.Context; + // FIXME: if there is an explicit deduction guide after the first use of the + // type alias usage, we will not cover this explicit deduction guide. fix this + // case. + if (hasDeclaredDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext())) +return; + // Unrap the sugar ElaboratedType. + auto RhsType = AliasTemplate->getTemplatedDecl() + ->getUnderlyingType() + .getSingleStepDesugaredType(Context); + TemplateDecl *Template = nullptr; + llvm::ArrayRef AliasRhsTemplateArgs; + if (const auto *TST = RhsType->getAs()) { +// TemplateName in TEST can be a TypeAliasTemplateDecl if +// the right hand side of the alias is also a type alias, e.g. +// +// template +// using AliasFoo1 = Foo; // Foo is a class template +// specialization +// +// template +// using AliasFoo2 = AliasFoo1; // AliasFoo1 is a type alias +Template = TST->getTemplateName().getAsTemplateDecl(); +AliasRhsTemplateArgs = TST->template_arguments(); + } else if (const auto *RT = RhsType->getAs()) { +// Cases where template arguments in the RHS of the alias are not +// dependent. e.g. +// using AliasFoo = Foo; +if (const auto *CTSD = llvm::dyn_cast( +RT->getAsCXXRecordDecl())) { + Template = CTSD->getSpecializedTemplate(); + AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray(); +} hokein wrote: It cov
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -2258,6 +2260,94 @@ class ExtractTypeForDeductionGuide } }; +// Build a deduction guide with the specified parameter types. +FunctionTemplateDecl * +buildDeductionGuide(Sema &SemaRef, TemplateDecl *OriginalTemplate, +TemplateParameterList *TemplateParams, +CXXConstructorDecl *Ctor, ExplicitSpecifier ES, +TypeSourceInfo *TInfo, SourceLocation LocStart, +SourceLocation Loc, SourceLocation LocEnd, bool IsImplicit, +llvm::ArrayRef MaterializedTypedefs = {}) { hokein wrote: For a function declaration, e.g. `void func();`, `Loc` points to the `func` token, `LocStart ` points to the `void` token, `LocEnd` points to `)`. https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -10598,10 +10598,34 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( if (TemplateName.isDependent()) return SubstAutoTypeDependent(TSInfo->getType()); - // We can only perform deduction for class templates. + // We can only perform deduction for class templates or alias templates. auto *Template = dyn_cast_or_null(TemplateName.getAsTemplateDecl()); + TemplateDecl* LookupTemplateDecl = Template; + if (!Template && getLangOpts().CPlusPlus20) { // type alias template +if (auto *AliasTemplate = dyn_cast_or_null( +TemplateName.getAsTemplateDecl()); +AliasTemplate) { + LookupTemplateDecl = AliasTemplate; + auto UnderlyingType = AliasTemplate->getTemplatedDecl() +->getUnderlyingType() +.getDesugaredType(Context); + if (const auto *TST = + UnderlyingType->getAs()) { +Template = dyn_cast_or_null( +TST->getTemplateName().getAsTemplateDecl()); + } else if (const auto *RT = UnderlyingType->getAs()) { +// Cases where template arguments in the RHS of the alias are not +// dependent. e.g. +// using AliasFoo = Foo; +if (const auto *CTSD = llvm::dyn_cast( +RT->getAsCXXRecordDecl())) + Template = CTSD->getSpecializedTemplate(); + } hokein wrote: added one. https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform { SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } +}; - FunctionTemplateDecl *buildDeductionGuide( - TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, - ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, - SourceLocation Loc, SourceLocation LocEnd, - llvm::ArrayRef MaterializedTypedefs = {}) { -DeclarationNameInfo Name(DeductionGuideName, Loc); -ArrayRef Params = -TInfo->getTypeLoc().castAs().getParams(); +// Find all template parameters of the AliasTemplate that appear in the +// given DeducedArgs. +SmallVector +FindAppearedTemplateParamsInAlias(ArrayRef DeducedArgs, + TypeAliasTemplateDecl *AliasTemplate) { + struct FindAppearedTemplateParams + : public RecursiveASTVisitor { +llvm::DenseSet TemplateParamsInAlias; +llvm::DenseSet AppearedTemplateParams; + +FindAppearedTemplateParams(ArrayRef TemplateParamsInAlias) +: TemplateParamsInAlias(TemplateParamsInAlias.begin(), +TemplateParamsInAlias.end()) {} + +bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { + TTP->getIndex(); + MarkAppeared(TTP->getDecl()); + return true; +} +bool VisitDeclRefExpr(DeclRefExpr *DRE) { + MarkAppeared(DRE->getFoundDecl()); + return true; +} -// Build the implicit deduction guide template. -auto *Guide = -CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name, - TInfo->getType(), TInfo, LocEnd, Ctor); -Guide->setImplicit(); -Guide->setParams(Params); +void MarkAppeared(NamedDecl *ND) { + if (TemplateParamsInAlias.contains(ND)) +AppearedTemplateParams.insert(ND); +} + }; + ArrayRef TemplateParamsInAlias = + AliasTemplate->getTemplateParameters()->asArray(); + FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias); + MarkAppeared.TraverseTemplateArguments(DeducedArgs); -for (auto *Param : Params) - Param->setDeclContext(Guide); -for (auto *TD : MaterializedTypedefs) - TD->setDeclContext(Guide); + SmallVector Results; + for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) { +if (MarkAppeared.AppearedTemplateParams.contains( +TemplateParamsInAlias[Index])) + Results.push_back(Index); + } + return Results; +} -auto *GuideTemplate = FunctionTemplateDecl::Create( -SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide); -GuideTemplate->setImplicit(); -Guide->setDescribedFunctionTemplate(GuideTemplate); +bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) { + // Check whether we've already declared deduction guides for this template. + // FIXME: Consider storing a flag on the template to indicate this. + auto Existing = DC->lookup(Name); + for (auto *D : Existing) +if (D->isImplicit()) + return true; + return false; +} -if (isa(DC)) { - Guide->setAccess(AS_public); - GuideTemplate->setAccess(AS_public); +// Build deduction guides for a type alias template. +void DeclareImplicitDeductionGuidesForTypeAlias( +Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) { + auto &Context = SemaRef.Context; + // FIXME: if there is an explicit deduction guide after the first use of the + // type alias usage, we will not cover this explicit deduction guide. fix this + // case. + if (hasDeclaredDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext())) +return; + // Unrap the sugar ElaboratedType. hokein wrote: Done. https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform { SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } +}; - FunctionTemplateDecl *buildDeductionGuide( - TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, - ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, - SourceLocation Loc, SourceLocation LocEnd, - llvm::ArrayRef MaterializedTypedefs = {}) { -DeclarationNameInfo Name(DeductionGuideName, Loc); -ArrayRef Params = -TInfo->getTypeLoc().castAs().getParams(); +// Find all template parameters of the AliasTemplate that appear in the +// given DeducedArgs. +SmallVector +FindAppearedTemplateParamsInAlias(ArrayRef DeducedArgs, + TypeAliasTemplateDecl *AliasTemplate) { + struct FindAppearedTemplateParams + : public RecursiveASTVisitor { +llvm::DenseSet TemplateParamsInAlias; +llvm::DenseSet AppearedTemplateParams; + +FindAppearedTemplateParams(ArrayRef TemplateParamsInAlias) +: TemplateParamsInAlias(TemplateParamsInAlias.begin(), +TemplateParamsInAlias.end()) {} + +bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { + TTP->getIndex(); + MarkAppeared(TTP->getDecl()); + return true; +} +bool VisitDeclRefExpr(DeclRefExpr *DRE) { + MarkAppeared(DRE->getFoundDecl()); + return true; +} -// Build the implicit deduction guide template. -auto *Guide = -CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name, - TInfo->getType(), TInfo, LocEnd, Ctor); -Guide->setImplicit(); -Guide->setParams(Params); +void MarkAppeared(NamedDecl *ND) { + if (TemplateParamsInAlias.contains(ND)) +AppearedTemplateParams.insert(ND); +} + }; + ArrayRef TemplateParamsInAlias = + AliasTemplate->getTemplateParameters()->asArray(); + FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias); + MarkAppeared.TraverseTemplateArguments(DeducedArgs); -for (auto *Param : Params) - Param->setDeclContext(Guide); -for (auto *TD : MaterializedTypedefs) - TD->setDeclContext(Guide); + SmallVector Results; + for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) { +if (MarkAppeared.AppearedTemplateParams.contains( +TemplateParamsInAlias[Index])) + Results.push_back(Index); + } + return Results; +} -auto *GuideTemplate = FunctionTemplateDecl::Create( -SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide); -GuideTemplate->setImplicit(); -Guide->setDescribedFunctionTemplate(GuideTemplate); +bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) { + // Check whether we've already declared deduction guides for this template. + // FIXME: Consider storing a flag on the template to indicate this. + auto Existing = DC->lookup(Name); + for (auto *D : Existing) +if (D->isImplicit()) + return true; + return false; +} -if (isa(DC)) { - Guide->setAccess(AS_public); - GuideTemplate->setAccess(AS_public); +// Build deduction guides for a type alias template. +void DeclareImplicitDeductionGuidesForTypeAlias( +Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) { + auto &Context = SemaRef.Context; + // FIXME: if there is an explicit deduction guide after the first use of the + // type alias usage, we will not cover this explicit deduction guide. fix this + // case. + if (hasDeclaredDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext())) +return; + // Unrap the sugar ElaboratedType. + auto RhsType = AliasTemplate->getTemplatedDecl() + ->getUnderlyingType() + .getSingleStepDesugaredType(Context); + TemplateDecl *Template = nullptr; + llvm::ArrayRef AliasRhsTemplateArgs; + if (const auto *TST = RhsType->getAs()) { +// TemplateName in TEST can be a TypeAliasTemplateDecl if hokein wrote: Done. https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform { SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } +}; - FunctionTemplateDecl *buildDeductionGuide( - TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, - ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, - SourceLocation Loc, SourceLocation LocEnd, - llvm::ArrayRef MaterializedTypedefs = {}) { -DeclarationNameInfo Name(DeductionGuideName, Loc); -ArrayRef Params = -TInfo->getTypeLoc().castAs().getParams(); +// Find all template parameters of the AliasTemplate that appear in the +// given DeducedArgs. +SmallVector +FindAppearedTemplateParamsInAlias(ArrayRef DeducedArgs, + TypeAliasTemplateDecl *AliasTemplate) { + struct FindAppearedTemplateParams + : public RecursiveASTVisitor { +llvm::DenseSet TemplateParamsInAlias; +llvm::DenseSet AppearedTemplateParams; + +FindAppearedTemplateParams(ArrayRef TemplateParamsInAlias) +: TemplateParamsInAlias(TemplateParamsInAlias.begin(), +TemplateParamsInAlias.end()) {} + +bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { + TTP->getIndex(); + MarkAppeared(TTP->getDecl()); + return true; +} +bool VisitDeclRefExpr(DeclRefExpr *DRE) { + MarkAppeared(DRE->getFoundDecl()); + return true; +} -// Build the implicit deduction guide template. -auto *Guide = -CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name, - TInfo->getType(), TInfo, LocEnd, Ctor); -Guide->setImplicit(); -Guide->setParams(Params); +void MarkAppeared(NamedDecl *ND) { + if (TemplateParamsInAlias.contains(ND)) +AppearedTemplateParams.insert(ND); +} + }; + ArrayRef TemplateParamsInAlias = + AliasTemplate->getTemplateParameters()->asArray(); + FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias); + MarkAppeared.TraverseTemplateArguments(DeducedArgs); -for (auto *Param : Params) - Param->setDeclContext(Guide); -for (auto *TD : MaterializedTypedefs) - TD->setDeclContext(Guide); + SmallVector Results; + for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) { +if (MarkAppeared.AppearedTemplateParams.contains( +TemplateParamsInAlias[Index])) + Results.push_back(Index); + } + return Results; +} -auto *GuideTemplate = FunctionTemplateDecl::Create( -SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide); -GuideTemplate->setImplicit(); -Guide->setDescribedFunctionTemplate(GuideTemplate); +bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) { + // Check whether we've already declared deduction guides for this template. + // FIXME: Consider storing a flag on the template to indicate this. + auto Existing = DC->lookup(Name); + for (auto *D : Existing) +if (D->isImplicit()) + return true; hokein wrote: Done. https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform { SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } +}; - FunctionTemplateDecl *buildDeductionGuide( - TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, - ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, - SourceLocation Loc, SourceLocation LocEnd, - llvm::ArrayRef MaterializedTypedefs = {}) { -DeclarationNameInfo Name(DeductionGuideName, Loc); -ArrayRef Params = -TInfo->getTypeLoc().castAs().getParams(); +// Find all template parameters of the AliasTemplate that appear in the +// given DeducedArgs. +SmallVector +FindAppearedTemplateParamsInAlias(ArrayRef DeducedArgs, + TypeAliasTemplateDecl *AliasTemplate) { + struct FindAppearedTemplateParams + : public RecursiveASTVisitor { +llvm::DenseSet TemplateParamsInAlias; +llvm::DenseSet AppearedTemplateParams; + +FindAppearedTemplateParams(ArrayRef TemplateParamsInAlias) +: TemplateParamsInAlias(TemplateParamsInAlias.begin(), +TemplateParamsInAlias.end()) {} + +bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { + TTP->getIndex(); + MarkAppeared(TTP->getDecl()); + return true; +} +bool VisitDeclRefExpr(DeclRefExpr *DRE) { + MarkAppeared(DRE->getFoundDecl()); + return true; +} -// Build the implicit deduction guide template. -auto *Guide = -CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name, - TInfo->getType(), TInfo, LocEnd, Ctor); -Guide->setImplicit(); -Guide->setParams(Params); +void MarkAppeared(NamedDecl *ND) { + if (TemplateParamsInAlias.contains(ND)) +AppearedTemplateParams.insert(ND); +} + }; + ArrayRef TemplateParamsInAlias = + AliasTemplate->getTemplateParameters()->asArray(); + FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias); + MarkAppeared.TraverseTemplateArguments(DeducedArgs); -for (auto *Param : Params) - Param->setDeclContext(Guide); -for (auto *TD : MaterializedTypedefs) - TD->setDeclContext(Guide); + SmallVector Results; + for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) { +if (MarkAppeared.AppearedTemplateParams.contains( +TemplateParamsInAlias[Index])) + Results.push_back(Index); + } + return Results; +} -auto *GuideTemplate = FunctionTemplateDecl::Create( -SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide); -GuideTemplate->setImplicit(); -Guide->setDescribedFunctionTemplate(GuideTemplate); +bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) { + // Check whether we've already declared deduction guides for this template. + // FIXME: Consider storing a flag on the template to indicate this. + auto Existing = DC->lookup(Name); + for (auto *D : Existing) +if (D->isImplicit()) + return true; + return false; +} -if (isa(DC)) { - Guide->setAccess(AS_public); - GuideTemplate->setAccess(AS_public); +// Build deduction guides for a type alias template. +void DeclareImplicitDeductionGuidesForTypeAlias( +Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) { + auto &Context = SemaRef.Context; + // FIXME: if there is an explicit deduction guide after the first use of the + // type alias usage, we will not cover this explicit deduction guide. fix this + // case. + if (hasDeclaredDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext())) +return; + // Unrap the sugar ElaboratedType. + auto RhsType = AliasTemplate->getTemplatedDecl() + ->getUnderlyingType() + .getSingleStepDesugaredType(Context); + TemplateDecl *Template = nullptr; + llvm::ArrayRef AliasRhsTemplateArgs; + if (const auto *TST = RhsType->getAs()) { +// TemplateName in TEST can be a TypeAliasTemplateDecl if +// the right hand side of the alias is also a type alias, e.g. +// +// template +// using AliasFoo1 = Foo; // Foo is a class template +// specialization +// +// template +// using AliasFoo2 = AliasFoo1; // AliasFoo1 is a type alias +Template = TST->getTemplateName().getAsTemplateDecl(); +AliasRhsTemplateArgs = TST->template_arguments(); + } else if (const auto *RT = RhsType->getAs()) { +// Cases where template arguments in the RHS of the alias are not +// dependent. e.g. +// using AliasFoo = Foo; +if (const auto *CTSD = llvm::dyn_cast( +RT->getAsCXXRecordDecl())) { + Template = CTSD->getSpecializedTemplate(); + AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray(); +} + } + if (!Template) +return; +
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform { SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } +}; - FunctionTemplateDecl *buildDeductionGuide( - TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, - ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, - SourceLocation Loc, SourceLocation LocEnd, - llvm::ArrayRef MaterializedTypedefs = {}) { -DeclarationNameInfo Name(DeductionGuideName, Loc); -ArrayRef Params = -TInfo->getTypeLoc().castAs().getParams(); +// Find all template parameters of the AliasTemplate that appear in the +// given DeducedArgs. +SmallVector +FindAppearedTemplateParamsInAlias(ArrayRef DeducedArgs, hokein wrote: I'm leaning towards `Appeared` to align with the C++ standard. It basically does "_whose template parameter list consists of all the template parameters of A (including their default template arguments) that appear in the above deductions_" https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -10525,9 +10534,11 @@ class Sema final { SourceLocation PointOfInstantiation, FunctionDecl *Decl, ArrayRef TemplateArgs, ConstraintSatisfaction &Satisfaction); - FunctionDecl *InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, - const TemplateArgumentList *Args, - SourceLocation Loc); + FunctionDecl *InstantiateFunctionDeclaration( + FunctionTemplateDecl *FTD, const TemplateArgumentList *Args, + SourceLocation Loc, + CodeSynthesisContext::SynthesisKind CSC = + CodeSynthesisContext::ExplicitTemplateArgumentSubstitution); hokein wrote: This is a refactoring and non-functional change, before this patch, we always use the `CodeSynthesisContext::ExplicitTemplateArgumentSubstitution` in this API [implementation](https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp#L4865), the change here is to promote it to a function parameter (making a default value so that we don't need to change all existing callsites) https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -39,6 +40,7 @@ #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/Casting.h" hokein wrote: Done. https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
https://github.com/hokein commented: Thanks for the initial review. https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform { SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } +}; - FunctionTemplateDecl *buildDeductionGuide( - TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, - ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, - SourceLocation Loc, SourceLocation LocEnd, - llvm::ArrayRef MaterializedTypedefs = {}) { -DeclarationNameInfo Name(DeductionGuideName, Loc); -ArrayRef Params = -TInfo->getTypeLoc().castAs().getParams(); +// Find all template parameters of the AliasTemplate that appear in the +// given DeducedArgs. +SmallVector +FindAppearedTemplateParamsInAlias(ArrayRef DeducedArgs, + TypeAliasTemplateDecl *AliasTemplate) { + struct FindAppearedTemplateParams + : public RecursiveASTVisitor { +llvm::DenseSet TemplateParamsInAlias; +llvm::DenseSet AppearedTemplateParams; + +FindAppearedTemplateParams(ArrayRef TemplateParamsInAlias) +: TemplateParamsInAlias(TemplateParamsInAlias.begin(), +TemplateParamsInAlias.end()) {} + +bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { + TTP->getIndex(); + MarkAppeared(TTP->getDecl()); + return true; +} +bool VisitDeclRefExpr(DeclRefExpr *DRE) { + MarkAppeared(DRE->getFoundDecl()); + return true; +} -// Build the implicit deduction guide template. -auto *Guide = -CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name, - TInfo->getType(), TInfo, LocEnd, Ctor); -Guide->setImplicit(); -Guide->setParams(Params); +void MarkAppeared(NamedDecl *ND) { + if (TemplateParamsInAlias.contains(ND)) +AppearedTemplateParams.insert(ND); +} + }; + ArrayRef TemplateParamsInAlias = + AliasTemplate->getTemplateParameters()->asArray(); + FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias); + MarkAppeared.TraverseTemplateArguments(DeducedArgs); -for (auto *Param : Params) - Param->setDeclContext(Guide); -for (auto *TD : MaterializedTypedefs) - TD->setDeclContext(Guide); + SmallVector Results; + for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) { +if (MarkAppeared.AppearedTemplateParams.contains( +TemplateParamsInAlias[Index])) + Results.push_back(Index); + } + return Results; +} -auto *GuideTemplate = FunctionTemplateDecl::Create( -SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide); -GuideTemplate->setImplicit(); -Guide->setDescribedFunctionTemplate(GuideTemplate); +bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) { + // Check whether we've already declared deduction guides for this template. + // FIXME: Consider storing a flag on the template to indicate this. + auto Existing = DC->lookup(Name); + for (auto *D : Existing) +if (D->isImplicit()) + return true; + return false; +} -if (isa(DC)) { - Guide->setAccess(AS_public); - GuideTemplate->setAccess(AS_public); +// Build deduction guides for a type alias template. +void DeclareImplicitDeductionGuidesForTypeAlias( +Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) { + auto &Context = SemaRef.Context; + // FIXME: if there is an explicit deduction guide after the first use of the + // type alias usage, we will not cover this explicit deduction guide. fix this + // case. + if (hasDeclaredDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext())) +return; + // Unrap the sugar ElaboratedType. + auto RhsType = AliasTemplate->getTemplatedDecl() + ->getUnderlyingType() + .getSingleStepDesugaredType(Context); + TemplateDecl *Template = nullptr; + llvm::ArrayRef AliasRhsTemplateArgs; + if (const auto *TST = RhsType->getAs()) { +// TemplateName in TEST can be a TypeAliasTemplateDecl if +// the right hand side of the alias is also a type alias, e.g. +// +// template +// using AliasFoo1 = Foo; // Foo is a class template +// specialization +// +// template +// using AliasFoo2 = AliasFoo1; // AliasFoo1 is a type alias +Template = TST->getTemplateName().getAsTemplateDecl(); +AliasRhsTemplateArgs = TST->template_arguments(); + } else if (const auto *RT = RhsType->getAs()) { +// Cases where template arguments in the RHS of the alias are not +// dependent. e.g. +// using AliasFoo = Foo; +if (const auto *CTSD = llvm::dyn_cast( +RT->getAsCXXRecordDecl())) { + Template = CTSD->getSpecializedTemplate(); + AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray(); +} + } + if (!Template) +return; +
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform { SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } +}; - FunctionTemplateDecl *buildDeductionGuide( - TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, - ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, - SourceLocation Loc, SourceLocation LocEnd, - llvm::ArrayRef MaterializedTypedefs = {}) { -DeclarationNameInfo Name(DeductionGuideName, Loc); -ArrayRef Params = -TInfo->getTypeLoc().castAs().getParams(); +// Find all template parameters of the AliasTemplate that appear in the +// given DeducedArgs. +SmallVector +FindAppearedTemplateParamsInAlias(ArrayRef DeducedArgs, + TypeAliasTemplateDecl *AliasTemplate) { + struct FindAppearedTemplateParams + : public RecursiveASTVisitor { +llvm::DenseSet TemplateParamsInAlias; +llvm::DenseSet AppearedTemplateParams; + +FindAppearedTemplateParams(ArrayRef TemplateParamsInAlias) +: TemplateParamsInAlias(TemplateParamsInAlias.begin(), +TemplateParamsInAlias.end()) {} + +bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { + TTP->getIndex(); + MarkAppeared(TTP->getDecl()); + return true; +} +bool VisitDeclRefExpr(DeclRefExpr *DRE) { + MarkAppeared(DRE->getFoundDecl()); + return true; +} -// Build the implicit deduction guide template. -auto *Guide = -CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name, - TInfo->getType(), TInfo, LocEnd, Ctor); -Guide->setImplicit(); -Guide->setParams(Params); +void MarkAppeared(NamedDecl *ND) { + if (TemplateParamsInAlias.contains(ND)) +AppearedTemplateParams.insert(ND); +} + }; + ArrayRef TemplateParamsInAlias = + AliasTemplate->getTemplateParameters()->asArray(); + FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias); + MarkAppeared.TraverseTemplateArguments(DeducedArgs); -for (auto *Param : Params) - Param->setDeclContext(Guide); -for (auto *TD : MaterializedTypedefs) - TD->setDeclContext(Guide); + SmallVector Results; + for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) { +if (MarkAppeared.AppearedTemplateParams.contains( +TemplateParamsInAlias[Index])) + Results.push_back(Index); + } + return Results; +} -auto *GuideTemplate = FunctionTemplateDecl::Create( -SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide); -GuideTemplate->setImplicit(); -Guide->setDescribedFunctionTemplate(GuideTemplate); +bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) { + // Check whether we've already declared deduction guides for this template. + // FIXME: Consider storing a flag on the template to indicate this. + auto Existing = DC->lookup(Name); + for (auto *D : Existing) +if (D->isImplicit()) + return true; + return false; +} -if (isa(DC)) { - Guide->setAccess(AS_public); - GuideTemplate->setAccess(AS_public); +// Build deduction guides for a type alias template. +void DeclareImplicitDeductionGuidesForTypeAlias( +Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) { + auto &Context = SemaRef.Context; + // FIXME: if there is an explicit deduction guide after the first use of the + // type alias usage, we will not cover this explicit deduction guide. fix this + // case. + if (hasDeclaredDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext())) +return; + // Unrap the sugar ElaboratedType. + auto RhsType = AliasTemplate->getTemplatedDecl() + ->getUnderlyingType() + .getSingleStepDesugaredType(Context); + TemplateDecl *Template = nullptr; + llvm::ArrayRef AliasRhsTemplateArgs; + if (const auto *TST = RhsType->getAs()) { +// TemplateName in TEST can be a TypeAliasTemplateDecl if +// the right hand side of the alias is also a type alias, e.g. +// +// template +// using AliasFoo1 = Foo; // Foo is a class template +// specialization +// +// template +// using AliasFoo2 = AliasFoo1; // AliasFoo1 is a type alias +Template = TST->getTemplateName().getAsTemplateDecl(); +AliasRhsTemplateArgs = TST->template_arguments(); + } else if (const auto *RT = RhsType->getAs()) { +// Cases where template arguments in the RHS of the alias are not +// dependent. e.g. +// using AliasFoo = Foo; +if (const auto *CTSD = llvm::dyn_cast( +RT->getAsCXXRecordDecl())) { + Template = CTSD->getSpecializedTemplate(); + AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray(); +} + } + if (!Template) +return; +
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
https://github.com/hokein edited https://github.com/llvm/llvm-project/pull/77890 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement CTAD for type alias template. (PR #77890)
@@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform { SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); return NewParam; } +}; - FunctionTemplateDecl *buildDeductionGuide( - TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, - ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, - SourceLocation Loc, SourceLocation LocEnd, - llvm::ArrayRef MaterializedTypedefs = {}) { -DeclarationNameInfo Name(DeductionGuideName, Loc); -ArrayRef Params = -TInfo->getTypeLoc().castAs().getParams(); +// Find all template parameters of the AliasTemplate that appear in the +// given DeducedArgs. +SmallVector +FindAppearedTemplateParamsInAlias(ArrayRef DeducedArgs, + TypeAliasTemplateDecl *AliasTemplate) { + struct FindAppearedTemplateParams + : public RecursiveASTVisitor { +llvm::DenseSet TemplateParamsInAlias; +llvm::DenseSet AppearedTemplateParams; + +FindAppearedTemplateParams(ArrayRef TemplateParamsInAlias) +: TemplateParamsInAlias(TemplateParamsInAlias.begin(), +TemplateParamsInAlias.end()) {} + +bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { + TTP->getIndex(); + MarkAppeared(TTP->getDecl()); + return true; +} +bool VisitDeclRefExpr(DeclRefExpr *DRE) { + MarkAppeared(DRE->getFoundDecl()); + return true; +} -// Build the implicit deduction guide template. -auto *Guide = -CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name, - TInfo->getType(), TInfo, LocEnd, Ctor); -Guide->setImplicit(); -Guide->setParams(Params); +void MarkAppeared(NamedDecl *ND) { + if (TemplateParamsInAlias.contains(ND)) +AppearedTemplateParams.insert(ND); +} + }; + ArrayRef TemplateParamsInAlias = + AliasTemplate->getTemplateParameters()->asArray(); + FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias); + MarkAppeared.TraverseTemplateArguments(DeducedArgs); -for (auto *Param : Params) - Param->setDeclContext(Guide); -for (auto *TD : MaterializedTypedefs) - TD->setDeclContext(Guide); + SmallVector Results; + for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) { +if (MarkAppeared.AppearedTemplateParams.contains( +TemplateParamsInAlias[Index])) + Results.push_back(Index); + } + return Results; +} -auto *GuideTemplate = FunctionTemplateDecl::Create( -SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide); -GuideTemplate->setImplicit(); -Guide->setDescribedFunctionTemplate(GuideTemplate); +bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) { + // Check whether we've already declared deduction guides for this template. + // FIXME: Consider storing a flag on the template to indicate this. + auto Existing = DC->lookup(Name); + for (auto *D : Existing) +if (D->isImplicit()) + return true; + return false; +} -if (isa(DC)) { - Guide->setAccess(AS_public); - GuideTemplate->setAccess(AS_public); +// Build deduction guides for a type alias template. +void DeclareImplicitDeductionGuidesForTypeAlias( +Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) { + auto &Context = SemaRef.Context; + // FIXME: if there is an explicit deduction guide after the first use of the + // type alias usage, we will not cover this explicit deduction guide. fix this + // case. + if (hasDeclaredDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext())) +return; + // Unrap the sugar ElaboratedType. + auto RhsType = AliasTemplate->getTemplatedDecl() + ->getUnderlyingType() + .getSingleStepDesugaredType(Context); + TemplateDecl *Template = nullptr; + llvm::ArrayRef AliasRhsTemplateArgs; + if (const auto *TST = RhsType->getAs()) { +// TemplateName in TEST can be a TypeAliasTemplateDecl if +// the right hand side of the alias is also a type alias, e.g. +// +// template +// using AliasFoo1 = Foo; // Foo is a class template +// specialization +// +// template +// using AliasFoo2 = AliasFoo1; // AliasFoo1 is a type alias +Template = TST->getTemplateName().getAsTemplateDecl(); +AliasRhsTemplateArgs = TST->template_arguments(); + } else if (const auto *RT = RhsType->getAs()) { +// Cases where template arguments in the RHS of the alias are not +// dependent. e.g. +// using AliasFoo = Foo; +if (const auto *CTSD = llvm::dyn_cast( +RT->getAsCXXRecordDecl())) { + Template = CTSD->getSpecializedTemplate(); + AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray(); +} cor3ntin wrote: An `
[clang] [AArch64][SME2] Refactor arm_sme.td into multiclasses (PR #78169)
https://github.com/sdesmalen-arm requested changes to this pull request. There isn't that much commonality factored out by these multi-classes as I had initially hoped, but I can understand why it's difficult to group these together in a better way. Given the above and the fact that the original format is a bit easier to search in (i.e. I can just search for `svmls.*za32.*vg1x4` and I would find the intrinsic that I'm looking for), I think I'd prefer to stick with the original format. https://github.com/llvm/llvm-project/pull/78169 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Thread safety analysis: provide printSCFG definition. (PR #80277)
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/80277 >From bb1a8f86e0b9ce3748af03625757d20900e053fc Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 1 Feb 2024 12:41:29 +0100 Subject: [PATCH 1/2] Thread safety analysis: provide printSCFG definition. I'm calling this function when investigating the issue (https://github.com/llvm/llvm-project/issues/78131), and I'm surprised to see the definition is commented out. I think it makes sense to provide the definition even though the implementation is not stable. --- clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h | 1 + clang/lib/Analysis/ThreadSafetyCommon.cpp | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 13e37ac2b56b64..4edd3374dd61bf 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -528,6 +528,7 @@ class SExprBuilder { }; // Dump an SCFG to llvm::errs(). +// The implementation is not stable, and used for debugging only. void printSCFG(CFGWalker &Walker); } // namespace threadSafety diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index 2fe0f85897c3bc..fc5b7d3b6f1977 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -995,7 +995,6 @@ void SExprBuilder::exitCFG(const CFGBlock *Last) { IncompleteArgs.clear(); } -/* namespace { class TILPrinter : @@ -1016,4 +1015,3 @@ void printSCFG(CFGWalker &Walker) { } // namespace threadSafety } // namespace clang -*/ >From 575775d3e7d1f30f456c7d2fcc340cd271fc8731 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 23 Feb 2024 15:21:53 +0100 Subject: [PATCH 2/2] printSCFG function is available for debug-only. --- clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h | 3 ++- clang/lib/Analysis/ThreadSafetyCommon.cpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 4edd3374dd61bf..7bdb9052e57e74 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -527,9 +527,10 @@ class SExprBuilder { BlockInfo *CurrentBlockInfo = nullptr; }; +#ifndef NDEBUG // Dump an SCFG to llvm::errs(). -// The implementation is not stable, and used for debugging only. void printSCFG(CFGWalker &Walker); +#endif // NDEBUG } // namespace threadSafety } // namespace clang diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index fc5b7d3b6f1977..3a864f079f75b1 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -995,6 +995,7 @@ void SExprBuilder::exitCFG(const CFGBlock *Last) { IncompleteArgs.clear(); } +#ifndef NDEBUG namespace { class TILPrinter : @@ -1012,6 +1013,7 @@ void printSCFG(CFGWalker &Walker) { til::SCFG *Scfg = SxBuilder.buildCFG(Walker); TILPrinter::print(Scfg, llvm::errs()); } +#endif // NDEBUG } // namespace threadSafety } // namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Thread safety analysis: provide printSCFG definition. (PR #80277)
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/80277 >From bb1a8f86e0b9ce3748af03625757d20900e053fc Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 1 Feb 2024 12:41:29 +0100 Subject: [PATCH 1/2] Thread safety analysis: provide printSCFG definition. I'm calling this function when investigating the issue (https://github.com/llvm/llvm-project/issues/78131), and I'm surprised to see the definition is commented out. I think it makes sense to provide the definition even though the implementation is not stable. --- clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h | 1 + clang/lib/Analysis/ThreadSafetyCommon.cpp | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 13e37ac2b56b64..4edd3374dd61bf 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -528,6 +528,7 @@ class SExprBuilder { }; // Dump an SCFG to llvm::errs(). +// The implementation is not stable, and used for debugging only. void printSCFG(CFGWalker &Walker); } // namespace threadSafety diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index 2fe0f85897c3bc..fc5b7d3b6f1977 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -995,7 +995,6 @@ void SExprBuilder::exitCFG(const CFGBlock *Last) { IncompleteArgs.clear(); } -/* namespace { class TILPrinter : @@ -1016,4 +1015,3 @@ void printSCFG(CFGWalker &Walker) { } // namespace threadSafety } // namespace clang -*/ >From 0a230f8cca97922a5f32155a432859fea65a84d4 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 23 Feb 2024 15:21:53 +0100 Subject: [PATCH 2/2] printSCFG function is available for debug-only. --- clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h | 3 ++- clang/lib/Analysis/ThreadSafetyCommon.cpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 4edd3374dd61bf..7bdb9052e57e74 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -527,9 +527,10 @@ class SExprBuilder { BlockInfo *CurrentBlockInfo = nullptr; }; +#ifndef NDEBUG // Dump an SCFG to llvm::errs(). -// The implementation is not stable, and used for debugging only. void printSCFG(CFGWalker &Walker); +#endif // NDEBUG } // namespace threadSafety } // namespace clang diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index fc5b7d3b6f1977..33f1f466df2444 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -995,6 +995,7 @@ void SExprBuilder::exitCFG(const CFGBlock *Last) { IncompleteArgs.clear(); } +#ifndef NDEBUG namespace { class TILPrinter : @@ -1015,3 +1016,4 @@ void printSCFG(CFGWalker &Walker) { } // namespace threadSafety } // namespace clang +#endif // NDEBUG ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Thread safety analysis: provide printSCFG definition. (PR #80277)
hokein wrote: > This sounds like a good idea! Done. https://github.com/llvm/llvm-project/pull/80277 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)
https://github.com/AMS21 updated https://github.com/llvm/llvm-project/pull/82673 >From 84b816ae115808c9144f4a0808849844a6fcab00 Mon Sep 17 00:00:00 2001 From: AMS21 Date: Thu, 22 Feb 2024 19:24:43 +0100 Subject: [PATCH] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` Fixes #82023 --- .../clang-tidy/bugprone/UseAfterMoveCheck.cpp | 89 +-- clang-tools-extra/docs/ReleaseNotes.rst | 4 + .../checkers/bugprone/use-after-move.cpp | 37 3 files changed, 103 insertions(+), 27 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index c5b6b541096ca9..760053b1b64983 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -330,7 +330,8 @@ void UseAfterMoveFinder::getReinits( traverse(TK_AsIs, DeclRefMatcher), unless(parmVarDecl(hasType( references(qualType(isConstQualified())), -unless(callee(functionDecl(hasName("::std::move"))) +unless(callee(functionDecl( +hasAnyName("::std::move", "::std::forward"))) .bind("reinit"); Stmts->clear(); @@ -359,24 +360,55 @@ void UseAfterMoveFinder::getReinits( } } +enum class MoveType +{ + Move,// std::move + Forward, // std::forward +}; + +static MoveType determineMoveType(const FunctionDecl* FuncDecl) +{ + if (FuncDecl->getName() == "move") +return MoveType::Move; + if (FuncDecl->getName() == "forward") +return MoveType::Forward; + + assert(false && "Invalid move type"); +} + static void emitDiagnostic(const Expr *MovingCall, const DeclRefExpr *MoveArg, const UseAfterMove &Use, ClangTidyCheck *Check, - ASTContext *Context) { + ASTContext *Context, MoveType Type) { SourceLocation UseLoc = Use.DeclRef->getExprLoc(); SourceLocation MoveLoc = MovingCall->getExprLoc(); - Check->diag(UseLoc, "'%0' used after it was moved") - << MoveArg->getDecl()->getName(); - Check->diag(MoveLoc, "move occurred here", DiagnosticIDs::Note); + StringRef ActionType; + StringRef ActionTypePastTense; + switch (Type) { + case MoveType::Move: +ActionType = "move"; +ActionTypePastTense = "moved"; +break; + case MoveType::Forward: +ActionType = "forward"; +ActionTypePastTense = "forwarded"; +break; + } + + Check->diag(UseLoc, "'%0' used after it was %1") + << MoveArg->getDecl()->getName() << ActionTypePastTense; + Check->diag(MoveLoc, "%0 occurred here", DiagnosticIDs::Note) + << ActionType; if (Use.EvaluationOrderUndefined) { Check->diag(UseLoc, -"the use and move are unsequenced, i.e. there is no guarantee " +"the use and %0 are unsequenced, i.e. there is no guarantee " "about the order in which they are evaluated", -DiagnosticIDs::Note); +DiagnosticIDs::Note) +<< ActionType; } else if (UseLoc < MoveLoc || Use.DeclRef == MoveArg) { -Check->diag(UseLoc, -"the use happens in a later loop iteration than the move", -DiagnosticIDs::Note); +Check->diag(UseLoc, "the use happens in a later loop iteration than the %0", +DiagnosticIDs::Note) +<< ActionType; } } @@ -387,22 +419,23 @@ void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) { // the bool. auto TryEmplaceMatcher = cxxMemberCallExpr(callee(cxxMethodDecl(hasName("try_emplace"; - auto CallMoveMatcher = - callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), - hasArgument(0, declRefExpr().bind("arg")), - unless(inDecltypeOrTemplateArg()), - unless(hasParent(TryEmplaceMatcher)), expr().bind("call-move"), - anyOf(hasAncestor(compoundStmt( - hasParent(lambdaExpr().bind("containing-lambda", - hasAncestor(functionDecl(anyOf( - cxxConstructorDecl( - hasAnyConstructorInitializer(withInitializer( - expr(anyOf(equalsBoundNode("call-move"), -hasDescendant(expr( - equalsBoundNode("call-move") - .bind("containing-ctor-init" - .bind("containing-ctor"), - functionDecl().bind("containing-func")); + auto CallMoveMatcher = callExpr( + argumentCountIs(1), + callee(functionDecl(hasAnyName("::std::move", "::std::forward")).bind("move-decl")), + hasArgument(0, declRefExp
[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)
AMS21 wrote: Rebased and address review comment https://github.com/llvm/llvm-project/pull/82673 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)
https://github.com/AMS21 updated https://github.com/llvm/llvm-project/pull/82673 >From 803386786f2011d1c8e5ff96795012f8e120880a Mon Sep 17 00:00:00 2001 From: AMS21 Date: Thu, 22 Feb 2024 19:24:43 +0100 Subject: [PATCH] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` Fixes #82023 --- .../clang-tidy/bugprone/UseAfterMoveCheck.cpp | 57 +++ clang-tools-extra/docs/ReleaseNotes.rst | 4 ++ .../checkers/bugprone/use-after-move.cpp | 37 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index c5b6b541096ca9..19702cec42dcb7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -330,7 +330,8 @@ void UseAfterMoveFinder::getReinits( traverse(TK_AsIs, DeclRefMatcher), unless(parmVarDecl(hasType( references(qualType(isConstQualified())), -unless(callee(functionDecl(hasName("::std::move"))) +unless(callee(functionDecl( +hasAnyName("::std::move", "::std::forward"))) .bind("reinit"); Stmts->clear(); @@ -359,24 +360,52 @@ void UseAfterMoveFinder::getReinits( } } +enum class MoveType { + Move,// std::move + Forward, // std::forward +}; + +static MoveType determineMoveType(const FunctionDecl *FuncDecl) { + if (FuncDecl->getName() == "move") +return MoveType::Move; + if (FuncDecl->getName() == "forward") +return MoveType::Forward; + + assert(false && "Invalid move type"); +} + static void emitDiagnostic(const Expr *MovingCall, const DeclRefExpr *MoveArg, const UseAfterMove &Use, ClangTidyCheck *Check, - ASTContext *Context) { + ASTContext *Context, MoveType Type) { SourceLocation UseLoc = Use.DeclRef->getExprLoc(); SourceLocation MoveLoc = MovingCall->getExprLoc(); - Check->diag(UseLoc, "'%0' used after it was moved") - << MoveArg->getDecl()->getName(); - Check->diag(MoveLoc, "move occurred here", DiagnosticIDs::Note); + StringRef ActionType; + StringRef ActionTypePastTense; + switch (Type) { + case MoveType::Move: +ActionType = "move"; +ActionTypePastTense = "moved"; +break; + case MoveType::Forward: +ActionType = "forward"; +ActionTypePastTense = "forwarded"; +break; + } + + Check->diag(UseLoc, "'%0' used after it was %1") + << MoveArg->getDecl()->getName() << ActionTypePastTense; + Check->diag(MoveLoc, "%0 occurred here", DiagnosticIDs::Note) << ActionType; if (Use.EvaluationOrderUndefined) { Check->diag(UseLoc, -"the use and move are unsequenced, i.e. there is no guarantee " +"the use and %0 are unsequenced, i.e. there is no guarantee " "about the order in which they are evaluated", -DiagnosticIDs::Note); +DiagnosticIDs::Note) +<< ActionType; } else if (UseLoc < MoveLoc || Use.DeclRef == MoveArg) { -Check->diag(UseLoc, -"the use happens in a later loop iteration than the move", -DiagnosticIDs::Note); +Check->diag(UseLoc, "the use happens in a later loop iteration than the %0", +DiagnosticIDs::Note) +<< ActionType; } } @@ -388,7 +417,9 @@ void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) { auto TryEmplaceMatcher = cxxMemberCallExpr(callee(cxxMethodDecl(hasName("try_emplace"; auto CallMoveMatcher = - callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), + callExpr(argumentCountIs(1), + callee(functionDecl(hasAnyName("::std::move", "::std::forward")) + .bind("move-decl")), hasArgument(0, declRefExpr().bind("arg")), unless(inDecltypeOrTemplateArg()), unless(hasParent(TryEmplaceMatcher)), expr().bind("call-move"), @@ -436,6 +467,7 @@ void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) { const auto *CallMove = Result.Nodes.getNodeAs("call-move"); const auto *MovingCall = Result.Nodes.getNodeAs("moving-call"); const auto *Arg = Result.Nodes.getNodeAs("arg"); + const auto *MoveDecl = Result.Nodes.getNodeAs("move-decl"); if (!MovingCall || !MovingCall->getExprLoc().isValid()) MovingCall = CallMove; @@ -470,7 +502,8 @@ void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) { UseAfterMoveFinder Finder(Result.Context); UseAfterMove Use; if (Finder.find(CodeBlock, MovingCall, Arg->getDecl(), &Use)) - emitDiagnostic(MovingCall, Arg, Use, this, Result.Context); + emitDiagnostic(MovingCall, Arg, Use, t
[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)
@@ -8069,6 +8069,38 @@ static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(::new (S.Context) AMDGPUNumVGPRAttr(S.Context, AL, NumVGPR)); } +static void handleAMDGPUMaxNumWorkGroupsAttr(Sema &S, Decl *D, + const ParsedAttr &AL) { + if (AL.getNumArgs() != 3) { +S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 3; +return; + } + uint32_t NumWGX = 0; + uint32_t NumWGY = 0; + uint32_t NumWGZ = 0; + Expr *NumWGXExpr = AL.getArgAsExpr(0); + Expr *NumWGYExpr = AL.getArgAsExpr(1); + Expr *NumWGZExpr = AL.getArgAsExpr(2); + if (!checkUInt32Argument(S, AL, NumWGXExpr, NumWGX, 0, true)) +return; + if (!checkUInt32Argument(S, AL, NumWGYExpr, NumWGY, 1, true)) +return; + if (!checkUInt32Argument(S, AL, NumWGZExpr, NumWGZ, 2, true)) +return; + + if (NumWGX == 0 || NumWGY == 0 || NumWGZ == 0) { erichkeane wrote: It seems that this whole function is effectively just `handleWorkGroupSize`. Can we just use that function here instead? It seems to do exactly what you want here without such awkward layout. https://github.com/llvm/llvm-project/pull/79035 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)
@@ -8069,6 +8069,38 @@ static void handleAMDGPUNumVGPRAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(::new (S.Context) AMDGPUNumVGPRAttr(S.Context, AL, NumVGPR)); } +static void handleAMDGPUMaxNumWorkGroupsAttr(Sema &S, Decl *D, + const ParsedAttr &AL) { + if (AL.getNumArgs() != 3) { +S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 3; +return; + } + uint32_t NumWGX = 0; + uint32_t NumWGY = 0; + uint32_t NumWGZ = 0; + Expr *NumWGXExpr = AL.getArgAsExpr(0); + Expr *NumWGYExpr = AL.getArgAsExpr(1); + Expr *NumWGZExpr = AL.getArgAsExpr(2); + if (!checkUInt32Argument(S, AL, NumWGXExpr, NumWGX, 0, true)) +return; + if (!checkUInt32Argument(S, AL, NumWGYExpr, NumWGY, 1, true)) +return; + if (!checkUInt32Argument(S, AL, NumWGZExpr, NumWGZ, 2, true)) +return; + + if (NumWGX == 0 || NumWGY == 0 || NumWGZ == 0) { +Expr *E = NumWGZExpr; +if (NumWGY == 0) + E = NumWGYExpr; +if (NumWGX == 0) + E = NumWGXExpr; +S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero) +<< AL << E->getSourceRange(); + } else +D->addAttr(::new (S.Context) AMDGPUMaxNumWorkGroupsAttr( erichkeane wrote: still need curley brackets around the 'else'. https://github.com/llvm/llvm-project/pull/79035 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)
@@ -194,3 +204,87 @@ __global__ void non_cexpr_waves_per_eu_2() {} // expected-error@+1{{'amdgpu_waves_per_eu' attribute requires parameter 1 to be an integer constant}} __attribute__((amdgpu_waves_per_eu(2, ipow2(2 __global__ void non_cexpr_waves_per_eu_2_4() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires exactly 3 arguments}} +__attribute__((amdgpu_max_num_work_groups(32))) +__global__ void max_num_work_groups_32() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires exactly 3 arguments}} +__attribute__((amdgpu_max_num_work_groups(32, 1))) +__global__ void max_num_work_groups_32_1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires exactly 3 arguments}} +__attribute__((amdgpu_max_num_work_groups(32, 1, 1, 1))) +__global__ void max_num_work_groups_32_1_1_1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires parameter 0 to be an integer constant}} +__attribute__((amdgpu_max_num_work_groups(ipow2(5), 1, 1))) +__global__ void max_num_work_groups_32_1_1_non_int_arg0() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires parameter 1 to be an integer constant}} +__attribute__((amdgpu_max_num_work_groups(32, "1", 1))) +__global__ void max_num_work_groups_32_1_1_non_int_arg1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires a non-negative integral compile time constant expression}} +__attribute__((amdgpu_max_num_work_groups(-32, 1, 1))) +__global__ void max_num_work_groups_32_1_1_neg_int_arg0() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires a non-negative integral compile time constant expression}} +__attribute__((amdgpu_max_num_work_groups(32, -1, 1))) +__global__ void max_num_work_groups_32_1_1_neg_int_arg1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires a non-negative integral compile time constant expression}} +__attribute__((amdgpu_max_num_work_groups(32, 1, -1))) +__global__ void max_num_work_groups_32_1_1_neg_int_arg2() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute must be greater than 0}} +__attribute__((amdgpu_max_num_work_groups(0, 1, 1))) +__global__ void max_num_work_groups_0_1_1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute must be greater than 0}} +__attribute__((amdgpu_max_num_work_groups(32, 0, 1))) +__global__ void max_num_work_groups_32_0_1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute must be greater than 0}} +__attribute__((amdgpu_max_num_work_groups(32, 1, 0))) +__global__ void max_num_work_groups_32_1_0() {} + + +int num_wg_x = 32; +int num_wg_y = 1; +int num_wg_z = 1; +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires parameter 0 to be an integer constant}} +__attribute__((amdgpu_max_num_work_groups(num_wg_x, 1, 1))) +__global__ void max_num_work_groups_32_1_1_non_const_arg0() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires parameter 1 to be an integer constant}} +__attribute__((amdgpu_max_num_work_groups(32, num_wg_y, 1))) +__global__ void max_num_work_groups_32_1_1_non_const_arg1() {} + +// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires parameter 2 to be an integer constant}} +__attribute__((amdgpu_max_num_work_groups(32, 1, num_wg_z))) +__global__ void max_num_work_groups_32_1_1_non_const_arg2() {} + +const int c_num_wg_x = 32; +__attribute__((amdgpu_max_num_work_groups(c_num_wg_x, 1, 1))) +__global__ void max_num_work_groups_32_1_1_const_arg0() {} + +// expected-error@+2{{'amdgpu_max_num_work_groups' attribute requires parameter 0 to be an integer constant}} erichkeane wrote: This isn't a good diagnostic, `a` IS an integer constant! All of these are actually integer constants and likely should work. https://github.com/llvm/llvm-project/pull/79035 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [include-cleaner] Dont apply name-match for non-owning headers (PR #82625)
https://github.com/hokein approved this pull request. https://github.com/llvm/llvm-project/pull/82625 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/82673 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)
@@ -359,24 +360,52 @@ void UseAfterMoveFinder::getReinits( } } +enum class MoveType { + Move,// std::move + Forward, // std::forward +}; + +static MoveType determineMoveType(const FunctionDecl *FuncDecl) { + if (FuncDecl->getName() == "move") +return MoveType::Move; + if (FuncDecl->getName() == "forward") +return MoveType::Forward; + + assert(false && "Invalid move type"); +} + static void emitDiagnostic(const Expr *MovingCall, const DeclRefExpr *MoveArg, const UseAfterMove &Use, ClangTidyCheck *Check, - ASTContext *Context) { + ASTContext *Context, MoveType Type) { SourceLocation UseLoc = Use.DeclRef->getExprLoc(); SourceLocation MoveLoc = MovingCall->getExprLoc(); - Check->diag(UseLoc, "'%0' used after it was moved") - << MoveArg->getDecl()->getName(); - Check->diag(MoveLoc, "move occurred here", DiagnosticIDs::Note); + StringRef ActionType; + StringRef ActionTypePastTense; + switch (Type) { + case MoveType::Move: +ActionType = "move"; +ActionTypePastTense = "moved"; +break; + case MoveType::Forward: +ActionType = "forward"; +ActionTypePastTense = "forwarded"; +break; + } + + Check->diag(UseLoc, "'%0' used after it was %1") + << MoveArg->getDecl()->getName() << ActionTypePastTense; + Check->diag(MoveLoc, "%0 occurred here", DiagnosticIDs::Note) << ActionType; if (Use.EvaluationOrderUndefined) { Check->diag(UseLoc, -"the use and move are unsequenced, i.e. there is no guarantee " +"the use and %0 are unsequenced, i.e. there is no guarantee " "about the order in which they are evaluated", -DiagnosticIDs::Note); +DiagnosticIDs::Note) +<< ActionType; } else if (UseLoc < MoveLoc || Use.DeclRef == MoveArg) { -Check->diag(UseLoc, -"the use happens in a later loop iteration than the move", -DiagnosticIDs::Note); +Check->diag(UseLoc, "the use happens in a later loop iteration than the %0", +DiagnosticIDs::Note) +<< ActionType; 5chmidti wrote: You could use the diagnostics 'select' syntax to do this in a more compact way: https://github.com/llvm/llvm-project/blob/be083dba95dfbbb0286d798cc06fbe021715bc03/clang-tools-extra/clang-tidy/hicpp/SignedBitwiseCheck.cpp#L96-L98 https://github.com/llvm/llvm-project/pull/82673 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)
https://github.com/5chmidti commented: Please add a short explanation that `forward` is also checked in the check's docs here https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/docs/clang-tidy/checks/bugprone/use-after-move.rst. https://github.com/llvm/llvm-project/pull/82673 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)
@@ -359,24 +360,52 @@ void UseAfterMoveFinder::getReinits( } } +enum class MoveType { + Move,// std::move + Forward, // std::forward +}; + +static MoveType determineMoveType(const FunctionDecl *FuncDecl) { + if (FuncDecl->getName() == "move") +return MoveType::Move; + if (FuncDecl->getName() == "forward") +return MoveType::Forward; + + assert(false && "Invalid move type"); 5chmidti wrote: Use `llvm_unreachable("Invalid move type")` if this code should truly be unreachable (which it is from what I can tell). https://github.com/llvm/llvm-project/pull/82673 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang serialization unittests: fix some leaks (PR #82773)
https://github.com/krasimirgg created https://github.com/llvm/llvm-project/pull/82773 No functional changes intended. Fixes some leaks found by running under asan with `--gtest_repeat=2`. >From 43f8b15fa3e5465f1939d0359ff5dcfc83ed1717 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 23 Feb 2024 15:11:51 + Subject: [PATCH] clang serialization unittests: fix some leaks No functional changes intended. Fixes some leaks found by running under asan with --gtest_repeat=2. --- .../Serialization/ModuleCacheTest.cpp | 18 ++ .../Serialization/VarDeclConstantInitTest.cpp | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp b/clang/unittests/Serialization/ModuleCacheTest.cpp index c3e347ffec660c..76aeee60f5a435 100644 --- a/clang/unittests/Serialization/ModuleCacheTest.cpp +++ b/clang/unittests/Serialization/ModuleCacheTest.cpp @@ -88,6 +88,16 @@ class ModuleCacheTest : public ::testing::Test { } )cpp"); } + + std::unique_ptr createInvocationAndEnableFree( + ArrayRef Args, CreateInvocationOptions Opts) { +std::unique_ptr Invocation = +createInvocation(Args, Opts); +if (Invocation) + Invocation->getFrontendOpts().DisableFree = false; + +return Invocation; + } }; TEST_F(ModuleCacheTest, CachedModuleNewPath) { @@ -106,7 +116,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) { MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation = - createInvocation(Args, CIOpts); + createInvocationAndEnableFree(Args, CIOpts); ASSERT_TRUE(Invocation); CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); @@ -129,7 +139,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) { "-Fframeworks", MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation2 = - createInvocation(Args2, CIOpts); + createInvocationAndEnableFree(Args2, CIOpts); ASSERT_TRUE(Invocation2); CompilerInstance Instance2(Instance.getPCHContainerOperations(), &Instance.getModuleCache()); @@ -156,7 +166,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) { MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation = - createInvocation(Args, CIOpts); + createInvocationAndEnableFree(Args, CIOpts); ASSERT_TRUE(Invocation); CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); @@ -173,7 +183,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) { TestDir.c_str(), "-Xclang", "-fallow-pcm-with-compiler-errors", "test.m"}; std::shared_ptr Invocation2 = - createInvocation(Args2, CIOpts); + createInvocationAndEnableFree(Args2, CIOpts); ASSERT_TRUE(Invocation2); CompilerInstance Instance2(Instance.getPCHContainerOperations(), &Instance.getModuleCache()); diff --git a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp index 86ae929e7f17e4..7efa1c1d64a964 100644 --- a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp +++ b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp @@ -103,6 +103,7 @@ export namespace Fibonacci std::shared_ptr Invocation = createInvocation(Args, CIOpts); ASSERT_TRUE(Invocation); + Invocation->getFrontendOpts().DisableFree = false; CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang serialization unittests: fix some leaks (PR #82773)
https://github.com/krasimirgg ready_for_review https://github.com/llvm/llvm-project/pull/82773 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang serialization unittests: fix some leaks (PR #82773)
llvmbot wrote: @llvm/pr-subscribers-clang-modules Author: Krasimir Georgiev (krasimirgg) Changes No functional changes intended. Fixes some leaks found by running under asan with `--gtest_repeat=2`. --- Full diff: https://github.com/llvm/llvm-project/pull/82773.diff 2 Files Affected: - (modified) clang/unittests/Serialization/ModuleCacheTest.cpp (+14-4) - (modified) clang/unittests/Serialization/VarDeclConstantInitTest.cpp (+1) ``diff diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp b/clang/unittests/Serialization/ModuleCacheTest.cpp index c3e347ffec660c..76aeee60f5a435 100644 --- a/clang/unittests/Serialization/ModuleCacheTest.cpp +++ b/clang/unittests/Serialization/ModuleCacheTest.cpp @@ -88,6 +88,16 @@ class ModuleCacheTest : public ::testing::Test { } )cpp"); } + + std::unique_ptr createInvocationAndEnableFree( + ArrayRef Args, CreateInvocationOptions Opts) { +std::unique_ptr Invocation = +createInvocation(Args, Opts); +if (Invocation) + Invocation->getFrontendOpts().DisableFree = false; + +return Invocation; + } }; TEST_F(ModuleCacheTest, CachedModuleNewPath) { @@ -106,7 +116,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) { MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation = - createInvocation(Args, CIOpts); + createInvocationAndEnableFree(Args, CIOpts); ASSERT_TRUE(Invocation); CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); @@ -129,7 +139,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) { "-Fframeworks", MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation2 = - createInvocation(Args2, CIOpts); + createInvocationAndEnableFree(Args2, CIOpts); ASSERT_TRUE(Invocation2); CompilerInstance Instance2(Instance.getPCHContainerOperations(), &Instance.getModuleCache()); @@ -156,7 +166,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) { MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation = - createInvocation(Args, CIOpts); + createInvocationAndEnableFree(Args, CIOpts); ASSERT_TRUE(Invocation); CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); @@ -173,7 +183,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) { TestDir.c_str(), "-Xclang", "-fallow-pcm-with-compiler-errors", "test.m"}; std::shared_ptr Invocation2 = - createInvocation(Args2, CIOpts); + createInvocationAndEnableFree(Args2, CIOpts); ASSERT_TRUE(Invocation2); CompilerInstance Instance2(Instance.getPCHContainerOperations(), &Instance.getModuleCache()); diff --git a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp index 86ae929e7f17e4..7efa1c1d64a964 100644 --- a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp +++ b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp @@ -103,6 +103,7 @@ export namespace Fibonacci std::shared_ptr Invocation = createInvocation(Args, CIOpts); ASSERT_TRUE(Invocation); + Invocation->getFrontendOpts().DisableFree = false; CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); `` https://github.com/llvm/llvm-project/pull/82773 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang serialization unittests: fix some leaks (PR #82773)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Krasimir Georgiev (krasimirgg) Changes No functional changes intended. Fixes some leaks found by running under asan with `--gtest_repeat=2`. --- Full diff: https://github.com/llvm/llvm-project/pull/82773.diff 2 Files Affected: - (modified) clang/unittests/Serialization/ModuleCacheTest.cpp (+14-4) - (modified) clang/unittests/Serialization/VarDeclConstantInitTest.cpp (+1) ``diff diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp b/clang/unittests/Serialization/ModuleCacheTest.cpp index c3e347ffec660c..76aeee60f5a435 100644 --- a/clang/unittests/Serialization/ModuleCacheTest.cpp +++ b/clang/unittests/Serialization/ModuleCacheTest.cpp @@ -88,6 +88,16 @@ class ModuleCacheTest : public ::testing::Test { } )cpp"); } + + std::unique_ptr createInvocationAndEnableFree( + ArrayRef Args, CreateInvocationOptions Opts) { +std::unique_ptr Invocation = +createInvocation(Args, Opts); +if (Invocation) + Invocation->getFrontendOpts().DisableFree = false; + +return Invocation; + } }; TEST_F(ModuleCacheTest, CachedModuleNewPath) { @@ -106,7 +116,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) { MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation = - createInvocation(Args, CIOpts); + createInvocationAndEnableFree(Args, CIOpts); ASSERT_TRUE(Invocation); CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); @@ -129,7 +139,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) { "-Fframeworks", MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation2 = - createInvocation(Args2, CIOpts); + createInvocationAndEnableFree(Args2, CIOpts); ASSERT_TRUE(Invocation2); CompilerInstance Instance2(Instance.getPCHContainerOperations(), &Instance.getModuleCache()); @@ -156,7 +166,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) { MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation = - createInvocation(Args, CIOpts); + createInvocationAndEnableFree(Args, CIOpts); ASSERT_TRUE(Invocation); CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); @@ -173,7 +183,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) { TestDir.c_str(), "-Xclang", "-fallow-pcm-with-compiler-errors", "test.m"}; std::shared_ptr Invocation2 = - createInvocation(Args2, CIOpts); + createInvocationAndEnableFree(Args2, CIOpts); ASSERT_TRUE(Invocation2); CompilerInstance Instance2(Instance.getPCHContainerOperations(), &Instance.getModuleCache()); diff --git a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp index 86ae929e7f17e4..7efa1c1d64a964 100644 --- a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp +++ b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp @@ -103,6 +103,7 @@ export namespace Fibonacci std::shared_ptr Invocation = createInvocation(Args, CIOpts); ASSERT_TRUE(Invocation); + Invocation->getFrontendOpts().DisableFree = false; CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); `` https://github.com/llvm/llvm-project/pull/82773 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang serialization unittests: fix some leaks (PR #82773)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 3b232f066d40a3e91ac27e421a3baeaca0cd59ec 43f8b15fa3e5465f1939d0359ff5dcfc83ed1717 -- clang/unittests/Serialization/ModuleCacheTest.cpp clang/unittests/Serialization/VarDeclConstantInitTest.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp b/clang/unittests/Serialization/ModuleCacheTest.cpp index 76aeee60f5..a7ca98549b 100644 --- a/clang/unittests/Serialization/ModuleCacheTest.cpp +++ b/clang/unittests/Serialization/ModuleCacheTest.cpp @@ -88,9 +88,10 @@ public: } )cpp"); } - - std::unique_ptr createInvocationAndEnableFree( - ArrayRef Args, CreateInvocationOptions Opts) { + + std::unique_ptr + createInvocationAndEnableFree(ArrayRef Args, +CreateInvocationOptions Opts) { std::unique_ptr Invocation = createInvocation(Args, Opts); if (Invocation) `` https://github.com/llvm/llvm-project/pull/82773 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang serialization unittests: fix some leaks (PR #82773)
https://github.com/krasimirgg updated https://github.com/llvm/llvm-project/pull/82773 >From 43f8b15fa3e5465f1939d0359ff5dcfc83ed1717 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 23 Feb 2024 15:11:51 + Subject: [PATCH 1/2] clang serialization unittests: fix some leaks No functional changes intended. Fixes some leaks found by running under asan with --gtest_repeat=2. --- .../Serialization/ModuleCacheTest.cpp | 18 ++ .../Serialization/VarDeclConstantInitTest.cpp | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp b/clang/unittests/Serialization/ModuleCacheTest.cpp index c3e347ffec660c..76aeee60f5a435 100644 --- a/clang/unittests/Serialization/ModuleCacheTest.cpp +++ b/clang/unittests/Serialization/ModuleCacheTest.cpp @@ -88,6 +88,16 @@ class ModuleCacheTest : public ::testing::Test { } )cpp"); } + + std::unique_ptr createInvocationAndEnableFree( + ArrayRef Args, CreateInvocationOptions Opts) { +std::unique_ptr Invocation = +createInvocation(Args, Opts); +if (Invocation) + Invocation->getFrontendOpts().DisableFree = false; + +return Invocation; + } }; TEST_F(ModuleCacheTest, CachedModuleNewPath) { @@ -106,7 +116,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) { MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation = - createInvocation(Args, CIOpts); + createInvocationAndEnableFree(Args, CIOpts); ASSERT_TRUE(Invocation); CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); @@ -129,7 +139,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPath) { "-Fframeworks", MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation2 = - createInvocation(Args2, CIOpts); + createInvocationAndEnableFree(Args2, CIOpts); ASSERT_TRUE(Invocation2); CompilerInstance Instance2(Instance.getPCHContainerOperations(), &Instance.getModuleCache()); @@ -156,7 +166,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) { MCPArg.c_str(), "-working-directory", TestDir.c_str(), "test.m"}; std::shared_ptr Invocation = - createInvocation(Args, CIOpts); + createInvocationAndEnableFree(Args, CIOpts); ASSERT_TRUE(Invocation); CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); @@ -173,7 +183,7 @@ TEST_F(ModuleCacheTest, CachedModuleNewPathAllowErrors) { TestDir.c_str(), "-Xclang", "-fallow-pcm-with-compiler-errors", "test.m"}; std::shared_ptr Invocation2 = - createInvocation(Args2, CIOpts); + createInvocationAndEnableFree(Args2, CIOpts); ASSERT_TRUE(Invocation2); CompilerInstance Instance2(Instance.getPCHContainerOperations(), &Instance.getModuleCache()); diff --git a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp index 86ae929e7f17e4..7efa1c1d64a964 100644 --- a/clang/unittests/Serialization/VarDeclConstantInitTest.cpp +++ b/clang/unittests/Serialization/VarDeclConstantInitTest.cpp @@ -103,6 +103,7 @@ export namespace Fibonacci std::shared_ptr Invocation = createInvocation(Args, CIOpts); ASSERT_TRUE(Invocation); + Invocation->getFrontendOpts().DisableFree = false; CompilerInstance Instance; Instance.setDiagnostics(Diags.get()); >From 4ab1858f489d9222ce114bf8a351ac1e8012ec00 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 23 Feb 2024 15:20:32 + Subject: [PATCH 2/2] reformat --- clang/unittests/Serialization/ModuleCacheTest.cpp | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/unittests/Serialization/ModuleCacheTest.cpp b/clang/unittests/Serialization/ModuleCacheTest.cpp index 76aeee60f5a435..a7ca98549b4125 100644 --- a/clang/unittests/Serialization/ModuleCacheTest.cpp +++ b/clang/unittests/Serialization/ModuleCacheTest.cpp @@ -88,9 +88,10 @@ class ModuleCacheTest : public ::testing::Test { } )cpp"); } - - std::unique_ptr createInvocationAndEnableFree( - ArrayRef Args, CreateInvocationOptions Opts) { + + std::unique_ptr + createInvocationAndEnableFree(ArrayRef Args, +CreateInvocationOptions Opts) { std::unique_ptr Invocation = createInvocation(Args, Opts); if (Invocation) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)
https://github.com/hokein created https://github.com/llvm/llvm-project/pull/82776 This patch implements a clang builtin `__builtin_start_object_lifetime`, it has the same semantics as C++23's `std::start_lifetime_as`, but without the implicit-lifetime type restriction, it could be used for implementing `std::start_lifetime_as` in the future. Due to the current clang lowering, the builtin reuses the existing `__builtin_launder` implementation: - it is a no-op for the most part; - with `-fstrict-vtable-pointers` flag, we update the vtpr assumption correctly (mark the load/store vptr with appropriate invariant group intrinsics) to prevent incorrect vptr load folding; - for now, it is non-constant, thus cannot be executed in constant evaluation; CAVEAT: - this builtin may cause TBAA miscomplies without the `-fno-strict-aliasing` flag. These TBAA miscompiles are known issues and may need more LLVM IR support for the fix, fixing them is orthogonal to the implementation of the builtin. Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy >From baf6f2eeda35182fcc1e04adf7334b513160419c Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 23 Feb 2024 10:03:16 +0100 Subject: [PATCH] [clang] Add __builtin_start_object_lifetime builtin. This patch implements a clang built `__builtin_start_object_lifetime`, it has the same semantics as C++23's `std::start_lifetime_as`, but without the implicit-lifetime type restriction, it can be used for implementing `std::start_lifetime_as` in the future. Due to the current clang lowering, the builtin reuses the existing `__builtin_launder` implementation: - it is a no-op for the most part; - with `-fstrict-vtable-pointers` flag, we update the vtpr assumption correctly (mark the load/store vptr with appropriate invariant group intrinsics) to prevent incorrect vptr load folding; - for now, the builtin is non-constant, cannot be executed in constant evaluation; CAVEAT: - this builtin may cause TBAA miscomplies without the `-fno-strict-alias` flag. These TBAA miscompiles are known issues and may need more LLVM IR support for the fix, fixing them is orthogonal to the implementaton of the builtin. Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy/76961 --- clang/include/clang/Basic/Builtins.td | 6 +++ clang/lib/CodeGen/CGBuiltin.cpp | 1 + clang/lib/Sema/SemaChecking.cpp | 2 + clang/test/CodeGen/builtins.c | 10 .../builtin-start-object-life-time.cpp| 49 +++ clang/test/SemaCXX/builtins.cpp | 33 - 6 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeGenCXX/builtin-start-object-life-time.cpp diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..70361afe69a980 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -896,6 +896,12 @@ def Launder : Builtin { let Prototype = "void*(void*)"; } +def StartObjectLifeTime : Builtin { + let Spellings = ["__builtin_start_object_lifetime"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "void*(void*)"; +} + def IsConstantEvaluated : LangBuiltin<"CXX_LANG"> { let Spellings = ["__builtin_is_constant_evaluated"]; let Attributes = [NoThrow, Constexpr]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index d454ccc1dd8613..7a98f734f32ada 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -4386,6 +4386,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(nullptr); } + case Builtin::BI__builtin_start_object_lifetime: case Builtin::BI__builtin_launder: { const Expr *Arg = E->getArg(0); QualType ArgTy = Arg->getType()->getPointeeType(); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 8e76338477..f79cb7e0445260 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -37,6 +37,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/UnresolvedSet.h" #include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" @@ -2386,6 +2387,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, TheCall->setType(Context.IntTy); break; } + case Builtin::BI__builtin_start_object_lifetime: case Builtin::BI__builtin_launder: return SemaBuiltinLaunder(*this, TheCall); case Builtin::BI__sync_fetch_and_add: diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c index 88282120283b8a..f46d6eb7632afc 100644 --- a/clang/test/CodeGen/builtins.c +++ b/clang/test/CodeGen/builtins.c @@ -143,6 +143,7 @@ int main(void) {
[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Haojian Wu (hokein) Changes This patch implements a clang builtin `__builtin_start_object_lifetime`, it has the same semantics as C++23's `std::start_lifetime_as`, but without the implicit-lifetime type restriction, it could be used for implementing `std::start_lifetime_as` in the future. Due to the current clang lowering, the builtin reuses the existing `__builtin_launder` implementation: - it is a no-op for the most part; - with `-fstrict-vtable-pointers` flag, we update the vtpr assumption correctly (mark the load/store vptr with appropriate invariant group intrinsics) to prevent incorrect vptr load folding; - for now, it is non-constant, thus cannot be executed in constant evaluation; CAVEAT: - this builtin may cause TBAA miscomplies without the `-fno-strict-aliasing` flag. These TBAA miscompiles are known issues and may need more LLVM IR support for the fix, fixing them is orthogonal to the implementation of the builtin. Context: https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy --- Full diff: https://github.com/llvm/llvm-project/pull/82776.diff 6 Files Affected: - (modified) clang/include/clang/Basic/Builtins.td (+6) - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+1) - (modified) clang/lib/Sema/SemaChecking.cpp (+2) - (modified) clang/test/CodeGen/builtins.c (+10) - (added) clang/test/CodeGenCXX/builtin-start-object-life-time.cpp (+49) - (modified) clang/test/SemaCXX/builtins.cpp (+32-1) ``diff diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..70361afe69a980 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -896,6 +896,12 @@ def Launder : Builtin { let Prototype = "void*(void*)"; } +def StartObjectLifeTime : Builtin { + let Spellings = ["__builtin_start_object_lifetime"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "void*(void*)"; +} + def IsConstantEvaluated : LangBuiltin<"CXX_LANG"> { let Spellings = ["__builtin_is_constant_evaluated"]; let Attributes = [NoThrow, Constexpr]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index d454ccc1dd8613..7a98f734f32ada 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -4386,6 +4386,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(nullptr); } + case Builtin::BI__builtin_start_object_lifetime: case Builtin::BI__builtin_launder: { const Expr *Arg = E->getArg(0); QualType ArgTy = Arg->getType()->getPointeeType(); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 8e76338477..f79cb7e0445260 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -37,6 +37,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/UnresolvedSet.h" #include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" @@ -2386,6 +2387,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, TheCall->setType(Context.IntTy); break; } + case Builtin::BI__builtin_start_object_lifetime: case Builtin::BI__builtin_launder: return SemaBuiltinLaunder(*this, TheCall); case Builtin::BI__sync_fetch_and_add: diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c index 88282120283b8a..f46d6eb7632afc 100644 --- a/clang/test/CodeGen/builtins.c +++ b/clang/test/CodeGen/builtins.c @@ -143,6 +143,7 @@ int main(void) { P(signbit, (1.0)); R(launder, (&N)); + R(start_object_lifetime, (&N)); return 0; } @@ -511,6 +512,15 @@ void test_builtin_launder(int *p) { int *d = __builtin_launder(p); } +/// It should be a NOP in C since there are no vtables. +// CHECK-LABEL: define{{.*}} void @test_builtin_start_object_lifetime +void test_builtin_start_object_lifetime(int *p) { + // CHECK: [[TMP:%.*]] = load ptr, + // CHECK-NOT: @llvm.launder + // CHECK: store ptr [[TMP]], + int *d = __builtin_start_object_lifetime(p); +} + // __warn_memset_zero_len should be NOP, see https://sourceware.org/bugzilla/show_bug.cgi?id=25399 // CHECK-LABEL: define{{.*}} void @test___warn_memset_zero_len void test___warn_memset_zero_len(void) { diff --git a/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp b/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp new file mode 100644 index 00..58012f52cc0ef5 --- /dev/null +++ b/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -fstrict-vtable-pointers -o - %s \ +// RUN: | FileCheck --check-prefixes=CHECK,CHECK-STRICT %s +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s \ +// RUN: | FileCheck --che
[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)
https://github.com/erichkeane commented: This would also need a release note I believe. I don't have the codegen expertise to review this with high confidence, but it looks right to me. https://github.com/llvm/llvm-project/pull/82776 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/82776 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)
@@ -4386,6 +4386,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(nullptr); } + case Builtin::BI__builtin_start_object_lifetime: case Builtin::BI__builtin_launder: { erichkeane wrote: Should the `TypeRequiresBuiltinLaunder` function be generalized, at least in name? https://github.com/llvm/llvm-project/pull/82776 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve `google-explicit-constructor` checks handling of `explicit(bool)` (PR #82689)
@@ -130,18 +134,30 @@ void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) { return; } - if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() || + if (ExplicitSpec.isExplicit() || Ctor->isCopyOrMoveConstructor() || TakesInitializerList) return; + // Don't complain about explicit(false) + const Expr *ExplicitExpr = ExplicitSpec.getExpr(); + if (ExplicitExpr) { +ExplicitExpr = ExplicitExpr->IgnoreImplicit(); +if (isa(ExplicitExpr)) + return; + } + bool SingleArgument = EugeneZelenko wrote: Should be `const`. https://github.com/llvm/llvm-project/pull/82689 ___ 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 support for determining constness of more expressions. (PR #82617)
@@ -34,69 +36,185 @@ void extractNodesByIdTo(ArrayRef Matches, StringRef ID, Nodes.insert(Match.getNodeAs(ID)); } +// A matcher that matches DeclRefExprs that are used in ways such that the +// underlying declaration is not modified. +// If the declaration is of pointer type, `Indirections` specifies the level +// of indirection of the object whose mutations we are tracking. +// +// For example, given: +// ``` +// int i; +// int* p; +// p = &i; // (A) +// *p = 3; // (B) +// ``` +// +// `declRefExpr(to(varDecl(hasName("p"))), doesNotMutateObject(0))` matches +// (B), but `declRefExpr(to(varDecl(hasName("p"))), doesNotMutateObject(1))` +// matches (A). +// +AST_MATCHER_P(DeclRefExpr, doesNotMutateObject, int, Indirections) { + // We walk up the parents of the DeclRefExpr recursively until we end up on a + // parent that cannot modify the underlying object. There are a few kinds of + // expressions: + // - Those that cannot be used to mutate the underlying object. We can stop + //recursion there. + // - Those that can be used to mutate the underlying object in analyzable + //ways (such as taking the address or accessing a subobject). We have to + //examine the parents. + // - Those that we don't know how to analyze. In that case we stop there and + //we assume that they can mutate the underlying expression. + + struct StackEntry { +StackEntry(const Expr *E, int Indirections) +: E(E), Indirections(Indirections) {} +// The expression to analyze. +const Expr *E; +// The number of pointer indirections of the object being tracked (how +// many times an address was taken). +int Indirections; + }; + + llvm::SmallVector Stack; + Stack.emplace_back(&Node, Indirections); + auto &Ctx = Finder->getASTContext(); + + while (!Stack.empty()) { +const StackEntry Entry = Stack.back(); +Stack.pop_back(); + +// If the expression type is const-qualified at the appropriate indirection +// level then we can not mutate the object. +QualType Ty = Entry.E->getType().getCanonicalType(); +for (int I = 0; I < Entry.Indirections; ++I) { + assert(Ty->isPointerType()); + Ty = Ty->getPointeeType().getCanonicalType(); +} +if (Ty.isConstQualified()) { + continue; +} + +// Otherwise we have to look at the parents to see how the expression is +// used. +const auto Parents = Ctx.getParents(*Entry.E); +// Note: most nodes have a single parents, but there exist nodes that have +// several parents, such as `InitListExpr` that have semantic and syntactic +// forms. +for (const auto &Parent : Parents) { + if (Parent.get()) { +// Unused block-scope statement. +continue; + } + const Expr *const P = Parent.get(); EugeneZelenko wrote: `auto` could be used here - type is explicitly stated. https://github.com/llvm/llvm-project/pull/82617 ___ 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 support for determining constness of more expressions. (PR #82617)
https://github.com/EugeneZelenko edited https://github.com/llvm/llvm-project/pull/82617 ___ 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 support for determining constness of more expressions. (PR #82617)
https://github.com/EugeneZelenko commented: Please mention changes in Release Notes. https://github.com/llvm/llvm-project/pull/82617 ___ 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 support for determining constness of more expressions. (PR #82617)
@@ -34,69 +36,185 @@ void extractNodesByIdTo(ArrayRef Matches, StringRef ID, Nodes.insert(Match.getNodeAs(ID)); } +// A matcher that matches DeclRefExprs that are used in ways such that the +// underlying declaration is not modified. +// If the declaration is of pointer type, `Indirections` specifies the level +// of indirection of the object whose mutations we are tracking. +// +// For example, given: +// ``` +// int i; +// int* p; +// p = &i; // (A) +// *p = 3; // (B) +// ``` +// +// `declRefExpr(to(varDecl(hasName("p"))), doesNotMutateObject(0))` matches +// (B), but `declRefExpr(to(varDecl(hasName("p"))), doesNotMutateObject(1))` +// matches (A). +// +AST_MATCHER_P(DeclRefExpr, doesNotMutateObject, int, Indirections) { + // We walk up the parents of the DeclRefExpr recursively until we end up on a + // parent that cannot modify the underlying object. There are a few kinds of + // expressions: + // - Those that cannot be used to mutate the underlying object. We can stop + //recursion there. + // - Those that can be used to mutate the underlying object in analyzable + //ways (such as taking the address or accessing a subobject). We have to + //examine the parents. + // - Those that we don't know how to analyze. In that case we stop there and + //we assume that they can mutate the underlying expression. + + struct StackEntry { +StackEntry(const Expr *E, int Indirections) +: E(E), Indirections(Indirections) {} +// The expression to analyze. +const Expr *E; +// The number of pointer indirections of the object being tracked (how +// many times an address was taken). +int Indirections; + }; + + llvm::SmallVector Stack; + Stack.emplace_back(&Node, Indirections); + auto &Ctx = Finder->getASTContext(); + + while (!Stack.empty()) { +const StackEntry Entry = Stack.back(); +Stack.pop_back(); + +// If the expression type is const-qualified at the appropriate indirection +// level then we can not mutate the object. +QualType Ty = Entry.E->getType().getCanonicalType(); +for (int I = 0; I < Entry.Indirections; ++I) { + assert(Ty->isPointerType()); + Ty = Ty->getPointeeType().getCanonicalType(); +} +if (Ty.isConstQualified()) { + continue; +} + +// Otherwise we have to look at the parents to see how the expression is +// used. +const auto Parents = Ctx.getParents(*Entry.E); EugeneZelenko wrote: Please don't use `auto` - type is not spelled. https://github.com/llvm/llvm-project/pull/82617 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][ARM][AArch64] Deduplicated code. (PR #82785)
https://github.com/DanielKristofKiss created https://github.com/llvm/llvm-project/pull/82785 Add the SignReturnAddressScopeKind to the BranchProtectionInfo class. >From f1de474eb318c06272a2ac8008af5de6762b7617 Mon Sep 17 00:00:00 2001 From: Daniel Kiss Date: Fri, 23 Feb 2024 17:12:26 +0100 Subject: [PATCH] [NFC][ARM][AArch64] Deduplicated code. Add the SignReturnAddressScopeKind to the BranchProtectionInfo class. --- clang/include/clang/Basic/TargetInfo.h | 21 ++--- clang/lib/CodeGen/Targets/AArch64.cpp | 3 +-- clang/lib/CodeGen/Targets/ARM.cpp | 8 +--- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 48e9cec482755c..2eb4f0e2ca42a6 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1369,13 +1369,20 @@ class TargetInfo : public TransferrableTargetInfo, } struct BranchProtectionInfo { -LangOptions::SignReturnAddressScopeKind SignReturnAddr = -LangOptions::SignReturnAddressScopeKind::None; -LangOptions::SignReturnAddressKeyKind SignKey = -LangOptions::SignReturnAddressKeyKind::AKey; -bool BranchTargetEnforcement = false; -bool BranchProtectionPAuthLR = false; -bool GuardedControlStack = false; +LangOptions::SignReturnAddressScopeKind SignReturnAddr; +LangOptions::SignReturnAddressKeyKind SignKey; +bool BranchTargetEnforcement; +bool BranchProtectionPAuthLR; +bool GuardedControlStack; + +BranchProtectionInfo() = default; + +const char *getSignReturnAddrStr() const { + static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"}; + assert(static_cast(SignReturnAddr) <= 2 && + "Unexpected SignReturnAddressScopeKind"); + return SignReturnAddrStr[static_cast(SignReturnAddr)]; +} }; /// Determine if the Architecture in this TargetInfo supports branch diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 94f8e7be2ee6eb..f0af87b00b91f4 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -125,8 +125,7 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { assert(Error.empty()); auto *Fn = cast(GV); -static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"}; -Fn->addFnAttr("sign-return-address", SignReturnAddrStr[static_cast(BPI.SignReturnAddr)]); +Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr()); if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) { Fn->addFnAttr("sign-return-address-key", diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp index d7d175ff1724f7..5d42e6286e525b 100644 --- a/clang/lib/CodeGen/Targets/ARM.cpp +++ b/clang/lib/CodeGen/Targets/ARM.cpp @@ -152,13 +152,7 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo { diag::warn_target_unsupported_branch_protection_attribute) << Arch; } else { - static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"}; - assert(static_cast(BPI.SignReturnAddr) <= 2 && - "Unexpected SignReturnAddressScopeKind"); - Fn->addFnAttr( - "sign-return-address", - SignReturnAddrStr[static_cast(BPI.SignReturnAddr)]); - + Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr()); Fn->addFnAttr("branch-target-enforcement", BPI.BranchTargetEnforcement ? "true" : "false"); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][ARM][AArch64] Deduplicated code. (PR #82785)
llvmbot wrote: @llvm/pr-subscribers-clang @llvm/pr-subscribers-backend-arm Author: Dani (DanielKristofKiss) Changes Add the SignReturnAddressScopeKind to the BranchProtectionInfo class. --- Full diff: https://github.com/llvm/llvm-project/pull/82785.diff 3 Files Affected: - (modified) clang/include/clang/Basic/TargetInfo.h (+14-7) - (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+1-2) - (modified) clang/lib/CodeGen/Targets/ARM.cpp (+1-7) ``diff diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 48e9cec482755c..2eb4f0e2ca42a6 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1369,13 +1369,20 @@ class TargetInfo : public TransferrableTargetInfo, } struct BranchProtectionInfo { -LangOptions::SignReturnAddressScopeKind SignReturnAddr = -LangOptions::SignReturnAddressScopeKind::None; -LangOptions::SignReturnAddressKeyKind SignKey = -LangOptions::SignReturnAddressKeyKind::AKey; -bool BranchTargetEnforcement = false; -bool BranchProtectionPAuthLR = false; -bool GuardedControlStack = false; +LangOptions::SignReturnAddressScopeKind SignReturnAddr; +LangOptions::SignReturnAddressKeyKind SignKey; +bool BranchTargetEnforcement; +bool BranchProtectionPAuthLR; +bool GuardedControlStack; + +BranchProtectionInfo() = default; + +const char *getSignReturnAddrStr() const { + static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"}; + assert(static_cast(SignReturnAddr) <= 2 && + "Unexpected SignReturnAddressScopeKind"); + return SignReturnAddrStr[static_cast(SignReturnAddr)]; +} }; /// Determine if the Architecture in this TargetInfo supports branch diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 94f8e7be2ee6eb..f0af87b00b91f4 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -125,8 +125,7 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { assert(Error.empty()); auto *Fn = cast(GV); -static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"}; -Fn->addFnAttr("sign-return-address", SignReturnAddrStr[static_cast(BPI.SignReturnAddr)]); +Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr()); if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) { Fn->addFnAttr("sign-return-address-key", diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp index d7d175ff1724f7..5d42e6286e525b 100644 --- a/clang/lib/CodeGen/Targets/ARM.cpp +++ b/clang/lib/CodeGen/Targets/ARM.cpp @@ -152,13 +152,7 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo { diag::warn_target_unsupported_branch_protection_attribute) << Arch; } else { - static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"}; - assert(static_cast(BPI.SignReturnAddr) <= 2 && - "Unexpected SignReturnAddressScopeKind"); - Fn->addFnAttr( - "sign-return-address", - SignReturnAddrStr[static_cast(BPI.SignReturnAddr)]); - + Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr()); Fn->addFnAttr("branch-target-enforcement", BPI.BranchTargetEnforcement ? "true" : "false"); } `` https://github.com/llvm/llvm-project/pull/82785 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -565,37 +565,67 @@ til::SExpr *SExprBuilder::translateBinaryOperator(const BinaryOperator *BO, case BO_PtrMemI: return new (Arena) til::Undefined(BO); - case BO_Mul: return translateBinOp(til::BOP_Mul, BO, Ctx); - case BO_Div: return translateBinOp(til::BOP_Div, BO, Ctx); - case BO_Rem: return translateBinOp(til::BOP_Rem, BO, Ctx); - case BO_Add: return translateBinOp(til::BOP_Add, BO, Ctx); - case BO_Sub: return translateBinOp(til::BOP_Sub, BO, Ctx); - case BO_Shl: return translateBinOp(til::BOP_Shl, BO, Ctx); - case BO_Shr: return translateBinOp(til::BOP_Shr, BO, Ctx); - case BO_LT: return translateBinOp(til::BOP_Lt, BO, Ctx); - case BO_GT: return translateBinOp(til::BOP_Lt, BO, Ctx, true); - case BO_LE: return translateBinOp(til::BOP_Leq, BO, Ctx); - case BO_GE: return translateBinOp(til::BOP_Leq, BO, Ctx, true); - case BO_EQ: return translateBinOp(til::BOP_Eq, BO, Ctx); - case BO_NE: return translateBinOp(til::BOP_Neq, BO, Ctx); - case BO_Cmp: return translateBinOp(til::BOP_Cmp, BO, Ctx); - case BO_And: return translateBinOp(til::BOP_BitAnd, BO, Ctx); - case BO_Xor: return translateBinOp(til::BOP_BitXor, BO, Ctx); - case BO_Or: return translateBinOp(til::BOP_BitOr,BO, Ctx); - case BO_LAnd: return translateBinOp(til::BOP_LogicAnd, BO, Ctx); - case BO_LOr: return translateBinOp(til::BOP_LogicOr, BO, Ctx); - - case BO_Assign:return translateBinAssign(til::BOP_Eq, BO, Ctx, true); - case BO_MulAssign: return translateBinAssign(til::BOP_Mul, BO, Ctx); - case BO_DivAssign: return translateBinAssign(til::BOP_Div, BO, Ctx); - case BO_RemAssign: return translateBinAssign(til::BOP_Rem, BO, Ctx); - case BO_AddAssign: return translateBinAssign(til::BOP_Add, BO, Ctx); - case BO_SubAssign: return translateBinAssign(til::BOP_Sub, BO, Ctx); - case BO_ShlAssign: return translateBinAssign(til::BOP_Shl, BO, Ctx); - case BO_ShrAssign: return translateBinAssign(til::BOP_Shr, BO, Ctx); - case BO_AndAssign: return translateBinAssign(til::BOP_BitAnd, BO, Ctx); - case BO_XorAssign: return translateBinAssign(til::BOP_BitXor, BO, Ctx); - case BO_OrAssign: return translateBinAssign(til::BOP_BitOr, BO, Ctx); + case BO_Mul: +return translateBinOp(til::BOP_Mul, BO, Ctx); + case BO_Div: +return translateBinOp(til::BOP_Div, BO, Ctx); + case BO_Rem: +return translateBinOp(til::BOP_Rem, BO, Ctx); + case BO_Add: +return translateBinOp(til::BOP_Add, BO, Ctx); + case BO_Sub: +return translateBinOp(til::BOP_Sub, BO, Ctx); + case BO_Shl: +return translateBinOp(til::BOP_Shl, BO, Ctx); + case BO_Shr: +return translateBinOp(til::BOP_Shr, BO, Ctx); + case BO_LT: +return translateBinOp(til::BOP_Lt, BO, Ctx); + case BO_GT: +return translateBinOp(til::BOP_Lt, BO, Ctx, true); + case BO_LE: +return translateBinOp(til::BOP_Leq, BO, Ctx); + case BO_GE: +return translateBinOp(til::BOP_Leq, BO, Ctx, true); + case BO_EQ: +return translateBinOp(til::BOP_Eq, BO, Ctx); + case BO_NE: +return translateBinOp(til::BOP_Neq, BO, Ctx); + case BO_Cmp: +return translateBinOp(til::BOP_Cmp, BO, Ctx); + case BO_And: +return translateBinOp(til::BOP_BitAnd, BO, Ctx); + case BO_Xor: +return translateBinOp(til::BOP_BitXor, BO, Ctx); + case BO_Or: +return translateBinOp(til::BOP_BitOr, BO, Ctx); + case BO_LAnd: +return translateBinOp(til::BOP_LogicAnd, BO, Ctx); + case BO_LOr: +return translateBinOp(til::BOP_LogicOr, BO, Ctx); + + case BO_Assign: +return translateBinAssign(til::BOP_Eq, BO, Ctx, true); + case BO_MulAssign: +return translateBinAssign(til::BOP_Mul, BO, Ctx); + case BO_DivAssign: +return translateBinAssign(til::BOP_Div, BO, Ctx); + case BO_RemAssign: +return translateBinAssign(til::BOP_Rem, BO, Ctx); + case BO_AddAssign: +return translateBinAssign(til::BOP_Add, BO, Ctx); + case BO_SubAssign: +return translateBinAssign(til::BOP_Sub, BO, Ctx); + case BO_ShlAssign: +return translateBinAssign(til::BOP_Shl, BO, Ctx); + case BO_ShrAssign: +return translateBinAssign(til::BOP_Shr, BO, Ctx); + case BO_AndAssign: +return translateBinAssign(til::BOP_BitAnd, BO, Ctx); + case BO_XorAssign: +return translateBinAssign(til::BOP_BitXor, BO, Ctx); + case BO_OrAssign: +return translateBinAssign(til::BOP_BitOr, BO, Ctx); steakhal wrote: ```suggestion // clang-format off case BO_Mul: return translateBinOp(til::BOP_Mul, BO, Ctx); case BO_Div: return translateBinOp(til::BOP_Div, BO, Ctx); case BO_Rem: return translateBinOp(til::BOP_Rem, BO, Ctx); case BO_Add: return translateBinOp(til::BOP_Add, BO, Ctx); case BO_Sub: return translateBinOp(til::BOP_Sub, BO, Ctx); case BO_Shl: return translateBinOp(til::BOP_Shl, BO, Ctx); case BO_Shr: return translateBinOp(til::BOP_Shr, BO, Ctx); case BO_LT: return translateBinOp(til::BOP_Lt, BO, Ctx); case BO_GT: return translateBinOp(til::BOP_Lt, BO,
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
https://github.com/steakhal edited https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -535,7 +545,8 @@ void CFNumberChecker::checkPreStmt(const CallExpr *CE, } //===--===// -// CFRetain/CFRelease/CFMakeCollectable/CFAutorelease checking for null arguments. +// CFRetain/CFRelease/CFMakeCollectable/CFAutorelease checking for null +// arguments. steakhal wrote: This is debatable formatting. https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -18,37 +18,57 @@ using namespace til; StringRef til::getUnaryOpcodeString(TIL_UnaryOpcode Op) { switch (Op) { -case UOP_Minus:return "-"; -case UOP_BitNot: return "~"; -case UOP_LogicNot: return "!"; + case UOP_Minus: +return "-"; + case UOP_BitNot: +return "~"; + case UOP_LogicNot: +return "!"; } return {}; } StringRef til::getBinaryOpcodeString(TIL_BinaryOpcode Op) { switch (Op) { -case BOP_Mul: return "*"; -case BOP_Div: return "/"; -case BOP_Rem: return "%"; -case BOP_Add: return "+"; -case BOP_Sub: return "-"; -case BOP_Shl: return "<<"; -case BOP_Shr: return ">>"; -case BOP_BitAnd: return "&"; -case BOP_BitXor: return "^"; -case BOP_BitOr:return "|"; -case BOP_Eq: return "=="; -case BOP_Neq: return "!="; -case BOP_Lt: return "<"; -case BOP_Leq: return "<="; -case BOP_Cmp: return "<=>"; -case BOP_LogicAnd: return "&&"; -case BOP_LogicOr: return "||"; + case BOP_Mul: +return "*"; + case BOP_Div: +return "/"; + case BOP_Rem: +return "%"; + case BOP_Add: +return "+"; + case BOP_Sub: +return "-"; + case BOP_Shl: +return "<<"; + case BOP_Shr: +return ">>"; + case BOP_BitAnd: +return "&"; + case BOP_BitXor: +return "^"; + case BOP_BitOr: +return "|"; + case BOP_Eq: +return "=="; + case BOP_Neq: +return "!="; + case BOP_Lt: +return "<"; + case BOP_Leq: +return "<="; + case BOP_Cmp: +return "<=>"; + case BOP_LogicAnd: +return "&&"; + case BOP_LogicOr: +return "||"; steakhal wrote: ```suggestion // clang-format off case BOP_Mul: return "*"; case BOP_Div: return "/"; case BOP_Rem: return "%"; case BOP_Add: return "+"; case BOP_Sub: return "-"; case BOP_Shl: return "<<"; case BOP_Shr: return ">>"; case BOP_BitAnd: return "&"; case BOP_BitXor: return "^"; case BOP_BitOr:return "|"; case BOP_Eq: return "=="; case BOP_Neq: return "!="; case BOP_Lt: return "<"; case BOP_Leq: return "<="; case BOP_Cmp: return "<=>"; case BOP_LogicAnd: return "&&"; case BOP_LogicOr: return "||"; // clang-format on ``` https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -380,27 +376,41 @@ enum CFNumberType { }; static std::optional GetCFNumberSize(ASTContext &Ctx, uint64_t i) { - static const unsigned char FixedSize[] = { 8, 16, 32, 64, 32, 64 }; + static const unsigned char FixedSize[] = {8, 16, 32, 64, 32, 64}; if (i < kCFNumberCharType) -return FixedSize[i-1]; +return FixedSize[i - 1]; QualType T; switch (i) { -case kCFNumberCharType: T = Ctx.CharTy; break; -case kCFNumberShortType:T = Ctx.ShortTy;break; -case kCFNumberIntType: T = Ctx.IntTy; break; -case kCFNumberLongType: T = Ctx.LongTy; break; -case kCFNumberLongLongType: T = Ctx.LongLongTy; break; -case kCFNumberFloatType:T = Ctx.FloatTy;break; -case kCFNumberDoubleType: T = Ctx.DoubleTy; break; -case kCFNumberCFIndexType: -case kCFNumberNSIntegerType: -case kCFNumberCGFloatType: - // FIXME: We need a way to map from names to Type*. -default: - return std::nullopt; + case kCFNumberCharType: +T = Ctx.CharTy; +break; + case kCFNumberShortType: +T = Ctx.ShortTy; +break; + case kCFNumberIntType: +T = Ctx.IntTy; +break; + case kCFNumberLongType: +T = Ctx.LongTy; +break; + case kCFNumberLongLongType: +T = Ctx.LongLongTy; +break; + case kCFNumberFloatType: +T = Ctx.FloatTy; +break; + case kCFNumberDoubleType: +T = Ctx.DoubleTy; +break; + case kCFNumberCFIndexType: + case kCFNumberNSIntegerType: + case kCFNumberCGFloatType: +// FIXME: We need a way to map from names to Type*. + default: +return std::nullopt; steakhal wrote: ```suggestion // clang-format off case kCFNumberCharType: T = Ctx.CharTy; break; case kCFNumberShortType:T = Ctx.ShortTy;break; case kCFNumberIntType: T = Ctx.IntTy; break; case kCFNumberLongType: T = Ctx.LongTy; break; case kCFNumberLongLongType: T = Ctx.LongLongTy; break; case kCFNumberFloatType:T = Ctx.FloatTy;break; case kCFNumberDoubleType: T = Ctx.DoubleTy; break; case kCFNumberCFIndexType: case kCFNumberNSIntegerType: case kCFNumberCGFloatType: // FIXME: We need a way to map from names to Type*. default: return std::nullopt; // clang-format on ``` https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -33,30 +33,17 @@ namespace ento { /// checking. /// /// \sa CheckerContext -class CheckerDocumentation : public Checker< check::PreStmt, - check::PostStmt, - check::PreObjCMessage, - check::PostObjCMessage, - check::ObjCMessageNil, - check::PreCall, - check::PostCall, - check::BranchCondition, - check::NewAllocator, - check::Location, - check::Bind, - check::DeadSymbols, - check::BeginFunction, - check::EndFunction, - check::EndAnalysis, - check::EndOfTranslationUnit, - eval::Call, - eval::Assume, - check::LiveSymbols, - check::RegionChanges, - check::PointerEscape, - check::ConstPointerEscape, - check::Event, - check::ASTDecl > { +class CheckerDocumentation +: public Checker< + check::PreStmt, check::PostStmt, + check::PreObjCMessage, check::PostObjCMessage, check::ObjCMessageNil, + check::PreCall, check::PostCall, check::BranchCondition, + check::NewAllocator, check::Location, check::Bind, check::DeadSymbols, + check::BeginFunction, check::EndFunction, check::EndAnalysis, + check::EndOfTranslationUnit, eval::Call, eval::Assume, + check::LiveSymbols, check::RegionChanges, check::PointerEscape, + check::ConstPointerEscape, check::Event, + check::ASTDecl> { steakhal wrote: Bad formatting. https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -244,24 +246,25 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { if (containsBadStrlcpyStrlcatPattern(CE)) { const Expr *DstArg = CE->getArg(0); const Expr *LenArg = CE->getArg(2); - PathDiagnosticLocation Loc = -PathDiagnosticLocation::createBegin(LenArg, BR.getSourceManager(), AC); + PathDiagnosticLocation Loc = PathDiagnosticLocation::createBegin( + LenArg, BR.getSourceManager(), AC); StringRef DstName = getPrintableName(DstArg); SmallString<256> S; llvm::raw_svector_ostream os(S); - os << "The third argument allows to potentially copy more bytes than it should. "; + os << "The third argument allows to potentially copy more bytes than it " +"should. "; os << "Replace with the value "; steakhal wrote: Bad formatting. https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
https://github.com/steakhal commented: Yeey, my review is done. We only have a handful (<50) debatable formatting problems. I'll try to fix them in an other PR. https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -1,4 +1,5 @@ -//===-- SimpleStreamChecker.cpp -*- C++ -*--// +//===-- SimpleStreamChecker.cpp -*- C++ +//-*--// steakhal wrote: ```suggestion //===-- SimpleStreamChecker.cpp ---*- C++ -*--// ``` https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -49,54 +50,44 @@ const char *IsARPBind = "isautoreleasepoolbind"; class ObjCAutoreleaseWriteChecker : public Checker { public: - void checkASTCodeBody(const Decl *D, -AnalysisManager &AM, + void checkASTCodeBody(const Decl *D, AnalysisManager &AM, BugReporter &BR) const; + private: std::vector SelectorsWithAutoreleasingPool = { // Common to NSArray, NSSet, NSOrderedSet - "enumerateObjectsUsingBlock:", - "enumerateObjectsWithOptions:usingBlock:", + "enumerateObjectsUsingBlock:", "enumerateObjectsWithOptions:usingBlock:", // Common to NSArray and NSOrderedSet "enumerateObjectsAtIndexes:options:usingBlock:", "indexOfObjectAtIndexes:options:passingTest:", "indexesOfObjectsAtIndexes:options:passingTest:", - "indexOfObjectPassingTest:", - "indexOfObjectWithOptions:passingTest:", + "indexOfObjectPassingTest:", "indexOfObjectWithOptions:passingTest:", "indexesOfObjectsPassingTest:", "indexesOfObjectsWithOptions:passingTest:", // NSDictionary "enumerateKeysAndObjectsUsingBlock:", "enumerateKeysAndObjectsWithOptions:usingBlock:", - "keysOfEntriesPassingTest:", - "keysOfEntriesWithOptions:passingTest:", + "keysOfEntriesPassingTest:", "keysOfEntriesWithOptions:passingTest:", // NSSet - "objectsPassingTest:", - "objectsWithOptions:passingTest:", + "objectsPassingTest:", "objectsWithOptions:passingTest:", "enumerateIndexPathsWithOptions:usingBlock:", // NSIndexSet - "enumerateIndexesWithOptions:usingBlock:", - "enumerateIndexesUsingBlock:", + "enumerateIndexesWithOptions:usingBlock:", "enumerateIndexesUsingBlock:", "enumerateIndexesInRange:options:usingBlock:", - "enumerateRangesUsingBlock:", - "enumerateRangesWithOptions:usingBlock:", - "enumerateRangesInRange:options:usingBlock:", - "indexPassingTest:", - "indexesPassingTest:", - "indexWithOptions:passingTest:", - "indexesWithOptions:passingTest:", - "indexInRange:options:passingTest:", - "indexesInRange:options:passingTest:" - }; + "enumerateRangesUsingBlock:", "enumerateRangesWithOptions:usingBlock:", + "enumerateRangesInRange:options:usingBlock:", "indexPassingTest:", + "indexesPassingTest:", "indexWithOptions:passingTest:", + "indexesWithOptions:passingTest:", "indexInRange:options:passingTest:", + "indexesInRange:options:passingTest:"}; steakhal wrote: Bad formatting for the `SelectorsWithAutoreleasingPool` member. https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -110,21 +111,41 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, continue; } -assert (B->isCompoundAssignmentOp()); +assert(B->isCompoundAssignmentOp()); switch (Op) { - default: -llvm_unreachable("Invalid opcode for compound assignment."); - case BO_MulAssign: Op = BO_Mul; break; - case BO_DivAssign: Op = BO_Div; break; - case BO_RemAssign: Op = BO_Rem; break; - case BO_AddAssign: Op = BO_Add; break; - case BO_SubAssign: Op = BO_Sub; break; - case BO_ShlAssign: Op = BO_Shl; break; - case BO_ShrAssign: Op = BO_Shr; break; - case BO_AndAssign: Op = BO_And; break; - case BO_XorAssign: Op = BO_Xor; break; - case BO_OrAssign: Op = BO_Or; break; +default: + llvm_unreachable("Invalid opcode for compound assignment."); +case BO_MulAssign: + Op = BO_Mul; + break; +case BO_DivAssign: + Op = BO_Div; + break; +case BO_RemAssign: + Op = BO_Rem; + break; +case BO_AddAssign: + Op = BO_Add; + break; +case BO_SubAssign: + Op = BO_Sub; + break; +case BO_ShlAssign: + Op = BO_Shl; + break; +case BO_ShrAssign: + Op = BO_Shr; + break; +case BO_AndAssign: + Op = BO_And; + break; +case BO_XorAssign: + Op = BO_Xor; + break; +case BO_OrAssign: + Op = BO_Or; + break; steakhal wrote: ```suggestion // clang-format off default: llvm_unreachable("Invalid opcode for compound assignment."); case BO_MulAssign: Op = BO_Mul; break; case BO_DivAssign: Op = BO_Div; break; case BO_RemAssign: Op = BO_Rem; break; case BO_AddAssign: Op = BO_Add; break; case BO_SubAssign: Op = BO_Sub; break; case BO_ShlAssign: Op = BO_Shl; break; case BO_ShrAssign: Op = BO_Shr; break; case BO_AndAssign: Op = BO_And; break; case BO_XorAssign: Op = BO_Xor; break; case BO_OrAssign: Op = BO_Or; break; // clang-format on ``` https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -219,17 +219,19 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { if (containsBadStrncatPattern(CE)) { const Expr *DstArg = CE->getArg(0); const Expr *LenArg = CE->getArg(2); - PathDiagnosticLocation Loc = -PathDiagnosticLocation::createBegin(LenArg, BR.getSourceManager(), AC); + PathDiagnosticLocation Loc = PathDiagnosticLocation::createBegin( + LenArg, BR.getSourceManager(), AC); StringRef DstName = getPrintableName(DstArg); SmallString<256> S; llvm::raw_svector_ostream os(S); os << "Potential buffer overflow. "; if (!DstName.empty()) { -os << "Replace with 'sizeof(" << DstName << ") " - "- strlen(" << DstName <<") - 1'"; +os << "Replace with 'sizeof(" << DstName + << ") " + "- strlen(" + << DstName << ") - 1'"; steakhal wrote: Bad formatting. https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -1,4 +1,5 @@ -//=- DirectIvarAssignment.cpp - Check rules on ObjC properties -*- C++ *-==// +//=- DirectIvarAssignment.cpp - Check rules on ObjC properties -*- C++ +//*-==// steakhal wrote: Bad formatting. ```suggestion //=- DirectIvarAssignment.cpp - Check rules on ObjC properties -*- C++ ---*-==// ``` https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [DRAFT][analyzer][NFC] clang-format our folders (PR #82599)
@@ -1,4 +1,5 @@ -//===-- STLAlgorithmModeling.cpp ---*- C++ -*--// +//===-- STLAlgorithmModeling.cpp ---*- C++ +//-*--// steakhal wrote: ```suggestion //===-- STLAlgorithmModeling.cpp --*- C++ -*--// ``` https://github.com/llvm/llvm-project/pull/82599 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve `google-explicit-constructor` checks handling of `explicit(bool)` (PR #82689)
@@ -130,18 +134,30 @@ void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) { return; } - if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() || + if (ExplicitSpec.isExplicit() || Ctor->isCopyOrMoveConstructor() || TakesInitializerList) return; + // Don't complain about explicit(false) + const Expr *ExplicitExpr = ExplicitSpec.getExpr(); + if (ExplicitExpr) { +ExplicitExpr = ExplicitExpr->IgnoreImplicit(); +if (isa(ExplicitExpr)) + return; + } + 5chmidti wrote: I think that dependent expressions (`isInstantiationDependent`) should also be ignored, e.g. ```c++ template struct I { explicit(Val > 0) I(int); }; template struct J { explicit(Val > 0) J(int); }; void useJ(J<0>, J<100>); ``` should not produce any warnings IMO. https://github.com/llvm/llvm-project/pull/82689 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve `google-explicit-constructor` checks handling of `explicit(bool)` (PR #82689)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/82689 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve `google-explicit-constructor` checks handling of `explicit(bool)` (PR #82689)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/82689 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] clang serialization unittests: fix some leaks (PR #82773)
https://github.com/d0k approved this pull request. https://github.com/llvm/llvm-project/pull/82773 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [LV][LAA] Vectorize math lib calls with mem write-only attribute (PR #78432)
@@ -2405,6 +2421,11 @@ void LoopAccessInfo::analyzeLoop(AAResults *AA, LoopInfo *LI, // Save 'store' instructions. Abort if other instructions write to memory. if (I.mayWriteToMemory()) { +// We can safety handle math functions that have vectorized +// counterparts and have the memory write-only attribute set. +if (isMathLibCallMemWriteOnly(TLI, I)) mgabka wrote: can this change be tested with a loop-access analysis tests using a debug output? if yes then it does not have to depend on the TLI mappings for modf/modff https://github.com/llvm/llvm-project/pull/78432 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)
@@ -0,0 +1,1014 @@ +//===--- SemaAPINotes.cpp - API Notes Handling ===// +// +// 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 +// +//===--===// +// +// This file implements the mapping from API notes to declaration attributes. +// +//===--===// + +#include "clang/APINotes/APINotesReader.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Lex/Lexer.h" +#include "clang/Sema/SemaInternal.h" + +using namespace clang; + +namespace { +enum IsActive_t : bool { IsNotActive, IsActive }; +enum IsReplacement_t : bool { IsNotReplacement, IsReplacement }; + +struct VersionedInfoMetadata { + /// An empty version refers to unversioned metadata. + VersionTuple Version; + unsigned IsActive : 1; + unsigned IsReplacement : 1; + + VersionedInfoMetadata(VersionTuple Version, IsActive_t Active, +IsReplacement_t Replacement) + : Version(Version), IsActive(Active == IsActive_t::IsActive), +IsReplacement(Replacement == IsReplacement_t::IsReplacement) {} +}; +} // end anonymous namespace + +/// Determine whether this is a multi-level pointer type. +static bool isMultiLevelPointerType(QualType Type) { + QualType Pointee = Type->getPointeeType(); + if (Pointee.isNull()) +return false; + + return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() || + Pointee->isMemberPointerType(); +} + +/// Apply nullability to the given declaration. +static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability, + VersionedInfoMetadata Metadata) { + if (!Metadata.IsActive) +return; + + QualType Type; + + // Nullability for a function/method appertains to the retain type. + if (auto Function = dyn_cast(D)) +Type = Function->getReturnType(); + else if (auto Method = dyn_cast(D)) +Type = Method->getReturnType(); + else if (auto Value = dyn_cast(D)) +Type = Value->getType(); + else if (auto Property = dyn_cast(D)) +Type = Property->getType(); + else +return; + + // Check the nullability specifier on this type. + QualType OrigType = Type; + S.CheckImplicitNullabilityTypeSpecifier(Type, Nullability, D->getLocation(), + isa(D), + /*overrideExisting=*/true); + if (Type.getTypePtr() == OrigType.getTypePtr()) +return; compnerd wrote: I was thinking something like: ```c++ auto IsUnmodified = [&S](Decl *D, QualType QT, NullabilityKind Nullability) -> Bool { QualType Original = QT; S.CheckImplicitNullabilityTypeSpecifier(QT, Nullability, D->getLocation(), isa(D), /*OverrideExisting=*/true); return QT.getTypePtr() == Original.getTypePtr(); } ``` Then, we could just do an inline `if (IsUnmodified(...)) return;` allowing us to fold the two if slides together. https://github.com/llvm/llvm-project/pull/78445 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [APINotes] Upstream Sema logic to apply API Notes to decls (PR #78445)
@@ -0,0 +1,995 @@ +//===--- SemaAPINotes.cpp - API Notes Handling ===// +// +// 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 +// +//===--===// +// +// This file implements the mapping from API notes to declaration attributes. +// +//===--===// + +#include "clang/APINotes/APINotesReader.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclObjC.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Lex/Lexer.h" +#include "clang/Sema/SemaInternal.h" + +using namespace clang; + +namespace { +enum class IsActive_t : bool { Inactive, Active }; +enum class IsReplacement_t : bool { Original, Replacement }; + +struct VersionedInfoMetadata { + /// An empty version refers to unversioned metadata. + VersionTuple Version; + unsigned IsActive : 1; + unsigned IsReplacement : 1; + + VersionedInfoMetadata(VersionTuple Version, IsActive_t Active, +IsReplacement_t Replacement) + : Version(Version), IsActive(Active == IsActive_t::Active), +IsReplacement(Replacement == IsReplacement_t::Replacement) {} +}; +} // end anonymous namespace + +/// Determine whether this is a multi-level pointer type. +static bool isIndirectPointerType(QualType Type) { + QualType Pointee = Type->getPointeeType(); + if (Pointee.isNull()) +return false; + + return Pointee->isAnyPointerType() || Pointee->isObjCObjectPointerType() || + Pointee->isMemberPointerType(); +} + +/// Apply nullability to the given declaration. +static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability, + VersionedInfoMetadata Metadata) { + if (!Metadata.IsActive) +return; + + QualType Type; + + // Nullability for a function/method appertains to the retain type. + if (auto Function = dyn_cast(D)) +Type = Function->getReturnType(); + else if (auto Method = dyn_cast(D)) +Type = Method->getReturnType(); + else if (auto Value = dyn_cast(D)) +Type = Value->getType(); + else if (auto Property = dyn_cast(D)) +Type = Property->getType(); + + if (Type.isNull()) +return; + + // Check the nullability specifier on this type. + QualType OrigType = Type; + S.CheckImplicitNullabilityTypeSpecifier(Type, Nullability, D->getLocation(), + isa(D), + /*overrideExisting=*/true); + if (Type.getTypePtr() == OrigType.getTypePtr()) +return; + + if (auto Function = dyn_cast(D)) { +QualType FnType = Function->getType(); +Function->setType(FnType); + } else if (auto Method = dyn_cast(D)) { +Method->setReturnType(Type); + +// Make it a context-sensitive keyword if we can. +if (!isIndirectPointerType(Type)) + Method->setObjCDeclQualifier(Decl::ObjCDeclQualifier( + Method->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability)); + + } else if (auto Value = dyn_cast(D)) { +Value->setType(Type); + +// Make it a context-sensitive keyword if we can. +if (auto Parm = dyn_cast(D)) { + if (Parm->isObjCMethodParameter() && !isIndirectPointerType(Type)) +Parm->setObjCDeclQualifier(Decl::ObjCDeclQualifier( +Parm->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability)); +} + } else if (auto Property = dyn_cast(D)) { +Property->setType(Type, Property->getTypeSourceInfo()); + +// Make it a property attribute if we can. +if (!isIndirectPointerType(Type)) + Property->setPropertyAttributes( + ObjCPropertyAttribute::kind_null_resettable); + + } else +llvm_unreachable("cannot handle nullability here"); compnerd wrote: That should allow us to get rid of this as well. https://github.com/llvm/llvm-project/pull/78445 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [RFC][clang][Support] Extract type persing function. [NFCI] (PR #82797)
https://github.com/fpetrogalli created https://github.com/llvm/llvm-project/pull/82797 I wanted to get a sense if people are OK for me to provide unit tests in `clang/unittests/Support` for the the parsing function I factored out from `clang-tblgen` into `clangSupport`. The refactoring would look like this patch - I haven't added any actual tests because I didn't want to keep working on this if people have strong arguments against it. FWIW, I believe that this refactoring will make it easier to handle new types over time. Pleas note that this is an RFC - I am not asking for a fully detailed review, just for some feedback on the idea. >From e9e5ec780fbc366c4619ae860c9069ee91c77b44 Mon Sep 17 00:00:00 2001 From: Francesco Petrogalli Date: Fri, 23 Feb 2024 17:53:30 +0100 Subject: [PATCH] [RFC][clang][Support] Extract type persing function. [NFCI] --- clang/include/clang/Support/BuiltinsUtils.h | 24 ++ clang/lib/Support/CMakeLists.txt | 1 + clang/lib/Support/ClangBuiltinsUtils.cpp | 81 +++ clang/utils/TableGen/ClangBuiltinsEmitter.cpp | 74 + 4 files changed, 108 insertions(+), 72 deletions(-) create mode 100644 clang/include/clang/Support/BuiltinsUtils.h create mode 100644 clang/lib/Support/ClangBuiltinsUtils.cpp diff --git a/clang/include/clang/Support/BuiltinsUtils.h b/clang/include/clang/Support/BuiltinsUtils.h new file mode 100644 index 00..2ee26f28127ce9 --- /dev/null +++ b/clang/include/clang/Support/BuiltinsUtils.h @@ -0,0 +1,24 @@ +//===--- BuiltinsUtils.h - clang Builtins Utils -*- 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 CLANG_SUPPORT_BUILTINSUTILS_H +#define CLANG_SUPPORT_BUILTINSUTILS_H + +#include "llvm/ADT/StringRef.h" +#include +namespace llvm { +class SMLoc; +} +namespace clang { + +/// Parse builtins prototypes according to the rules in +/// clang/include/clang/Basic/Builtins.def +void ParseBuiltinType(llvm::StringRef T, llvm::StringRef Substitution, + std::string &Type, llvm::SMLoc *Loc); + +} // namespace clang +#endif // CLANG_SUPPORT_BUILTINSUTILS_H diff --git a/clang/lib/Support/CMakeLists.txt b/clang/lib/Support/CMakeLists.txt index 8ea5620052ed84..93959eb8565b6b 100644 --- a/clang/lib/Support/CMakeLists.txt +++ b/clang/lib/Support/CMakeLists.txt @@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS set(clangSupport_sources RISCVVIntrinsicUtils.cpp + ClangBuiltinsUtils.cpp ) add_clang_library(clangSupport ${clangSupport_sources}) diff --git a/clang/lib/Support/ClangBuiltinsUtils.cpp b/clang/lib/Support/ClangBuiltinsUtils.cpp new file mode 100644 index 00..523378322cdf1b --- /dev/null +++ b/clang/lib/Support/ClangBuiltinsUtils.cpp @@ -0,0 +1,81 @@ +#include "clang/Support/BuiltinsUtils.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/SMLoc.h" +#include "llvm/TableGen/Error.h" + +void clang::ParseBuiltinType(llvm::StringRef T, llvm::StringRef Substitution, + std::string &Type, llvm::SMLoc *Loc) { + assert(Loc); + T = T.trim(); + if (T.consume_back("*")) { +ParseBuiltinType(T, Substitution, Type, Loc); +Type += "*"; + } else if (T.consume_back("const")) { +ParseBuiltinType(T, Substitution, Type, Loc); +Type += "C"; + } else if (T.consume_back("volatile")) { +ParseBuiltinType(T, Substitution, Type, Loc); +Type += "D"; + } else if (T.consume_back("restrict")) { +ParseBuiltinType(T, Substitution, Type, Loc); +Type += "R"; + } else if (T.consume_back("&")) { +ParseBuiltinType(T, Substitution, Type, Loc); +Type += "&"; + } else if (T.consume_front("long")) { +Type += "L"; +ParseBuiltinType(T, Substitution, Type, Loc); + } else if (T.consume_front("unsigned")) { +Type += "U"; +ParseBuiltinType(T, Substitution, Type, Loc); + } else if (T.consume_front("_Complex")) { +Type += "X"; +ParseBuiltinType(T, Substitution, Type, Loc); + } else if (T.consume_front("_Constant")) { +Type += "I"; +ParseBuiltinType(T, Substitution, Type, Loc); + } else if (T.consume_front("T")) { +if (Substitution.empty()) + llvm::PrintFatalError(*Loc, "Not a template"); +ParseBuiltinType(Substitution, Substitution, Type, Loc); + } else { +auto ReturnTypeVal = llvm::StringSwitch(T) + .Case("__builtin_va_list_ref", "A") + .Case("__builtin_va_list", "a") + .Case("__float128", "LLd") + .Case("__fp16", "h") + .Case("__int128_t", "LLLi") + .Case("_Float16", "x") + .Case("bool", "b") +
[clang] [RFC][clang][Support] Extract type persing function. [NFCI] (PR #82797)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Francesco Petrogalli (fpetrogalli) Changes I wanted to get a sense if people are OK for me to provide unit tests in `clang/unittests/Support` for the the parsing function I factored out from `clang-tblgen` into `clangSupport`. The refactoring would look like this patch - I haven't added any actual tests because I didn't want to keep working on this if people have strong arguments against it. FWIW, I believe that this refactoring will make it easier to handle new types over time. Pleas note that this is an RFC - I am not asking for a fully detailed review, just for some feedback on the idea. --- Full diff: https://github.com/llvm/llvm-project/pull/82797.diff 4 Files Affected: - (added) clang/include/clang/Support/BuiltinsUtils.h (+24) - (modified) clang/lib/Support/CMakeLists.txt (+1) - (added) clang/lib/Support/ClangBuiltinsUtils.cpp (+81) - (modified) clang/utils/TableGen/ClangBuiltinsEmitter.cpp (+2-72) ``diff diff --git a/clang/include/clang/Support/BuiltinsUtils.h b/clang/include/clang/Support/BuiltinsUtils.h new file mode 100644 index 00..2ee26f28127ce9 --- /dev/null +++ b/clang/include/clang/Support/BuiltinsUtils.h @@ -0,0 +1,24 @@ +//===--- BuiltinsUtils.h - clang Builtins Utils -*- 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 CLANG_SUPPORT_BUILTINSUTILS_H +#define CLANG_SUPPORT_BUILTINSUTILS_H + +#include "llvm/ADT/StringRef.h" +#include +namespace llvm { +class SMLoc; +} +namespace clang { + +/// Parse builtins prototypes according to the rules in +/// clang/include/clang/Basic/Builtins.def +void ParseBuiltinType(llvm::StringRef T, llvm::StringRef Substitution, + std::string &Type, llvm::SMLoc *Loc); + +} // namespace clang +#endif // CLANG_SUPPORT_BUILTINSUTILS_H diff --git a/clang/lib/Support/CMakeLists.txt b/clang/lib/Support/CMakeLists.txt index 8ea5620052ed84..93959eb8565b6b 100644 --- a/clang/lib/Support/CMakeLists.txt +++ b/clang/lib/Support/CMakeLists.txt @@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS set(clangSupport_sources RISCVVIntrinsicUtils.cpp + ClangBuiltinsUtils.cpp ) add_clang_library(clangSupport ${clangSupport_sources}) diff --git a/clang/lib/Support/ClangBuiltinsUtils.cpp b/clang/lib/Support/ClangBuiltinsUtils.cpp new file mode 100644 index 00..523378322cdf1b --- /dev/null +++ b/clang/lib/Support/ClangBuiltinsUtils.cpp @@ -0,0 +1,81 @@ +#include "clang/Support/BuiltinsUtils.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/SMLoc.h" +#include "llvm/TableGen/Error.h" + +void clang::ParseBuiltinType(llvm::StringRef T, llvm::StringRef Substitution, + std::string &Type, llvm::SMLoc *Loc) { + assert(Loc); + T = T.trim(); + if (T.consume_back("*")) { +ParseBuiltinType(T, Substitution, Type, Loc); +Type += "*"; + } else if (T.consume_back("const")) { +ParseBuiltinType(T, Substitution, Type, Loc); +Type += "C"; + } else if (T.consume_back("volatile")) { +ParseBuiltinType(T, Substitution, Type, Loc); +Type += "D"; + } else if (T.consume_back("restrict")) { +ParseBuiltinType(T, Substitution, Type, Loc); +Type += "R"; + } else if (T.consume_back("&")) { +ParseBuiltinType(T, Substitution, Type, Loc); +Type += "&"; + } else if (T.consume_front("long")) { +Type += "L"; +ParseBuiltinType(T, Substitution, Type, Loc); + } else if (T.consume_front("unsigned")) { +Type += "U"; +ParseBuiltinType(T, Substitution, Type, Loc); + } else if (T.consume_front("_Complex")) { +Type += "X"; +ParseBuiltinType(T, Substitution, Type, Loc); + } else if (T.consume_front("_Constant")) { +Type += "I"; +ParseBuiltinType(T, Substitution, Type, Loc); + } else if (T.consume_front("T")) { +if (Substitution.empty()) + llvm::PrintFatalError(*Loc, "Not a template"); +ParseBuiltinType(Substitution, Substitution, Type, Loc); + } else { +auto ReturnTypeVal = llvm::StringSwitch(T) + .Case("__builtin_va_list_ref", "A") + .Case("__builtin_va_list", "a") + .Case("__float128", "LLd") + .Case("__fp16", "h") + .Case("__int128_t", "LLLi") + .Case("_Float16", "x") + .Case("bool", "b") + .Case("char", "c") + .Case("constant_CFString", "F") + .Case("double", "d") + .Case("FILE", "P") + .Case("float", "f") + .Case("
[clang] [RFC][clang][Support] Extract type persing function. [NFCI] (PR #82797)
fpetrogalli wrote: I have added for feedback all people involved in https://github.com/llvm/llvm-project/pull/68324 https://github.com/llvm/llvm-project/pull/82797 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/amy-kwan edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/amy-kwan commented: I think the braces can also be omitted on the conditions within the `clang/*` files. https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -337,12 +350,77 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { return CharUnits::fromQuantity(4); } +ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(QualType Ty, + uint64_t &TypeSize) const { + + assert(Ty->isAnyComplexType()); amy-kwan wrote: It would also be good if the assert has a message. Additionally, for people who do not do assert builds, since `Ty` is only used for the assert, they may get an unused variable warning. https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -271,22 +271,33 @@ namespace { class PPC32_SVR4_ABIInfo : public DefaultABIInfo { bool IsSoftFloatABI; bool IsRetSmallStructInRegABI; + bool isComplexInRegABI; + // Size of GPR in bits amy-kwan wrote: ```suggestion bool IsComplexInRegABI; // Size of GPR in bits. ``` End sentence with a period, and capitalize the boolean variable for consistency. https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -2540,6 +2540,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, Group, HelpText<"Form fused FP ops (e.g. FMAs)">, Values<"fast,on,off,fast-honor-pragmas">; +def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, Group, Visibility<[ClangOption, CC1Option]>, + DocBrief<"Follow the GNU ABI, store Complex values in GPR instead of stack for PowerPC-32">, amy-kwan wrote: ```suggestion DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the stack for PowerPC-32">, ``` https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits