[clang] [clang-tools-extra] [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (PR #90948)
https://github.com/hokein edited https://github.com/llvm/llvm-project/pull/90948 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fc866fd - [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (#90948)
Author: Haojian Wu Date: 2024-05-07T09:10:29+02:00 New Revision: fc866fd2a2cfca6d62f48dcf83778959fd24f559 URL: https://github.com/llvm/llvm-project/commit/fc866fd2a2cfca6d62f48dcf83778959fd24f559 DIFF: https://github.com/llvm/llvm-project/commit/fc866fd2a2cfca6d62f48dcf83778959fd24f559.diff LOG: [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (#90948) With the commit d5308949cf884d8e4b971d51a8b4f73584c4adec, we now preserve the initializer for invalid decls with the recovery-expr. However there is a chance that the original init expr is a typo-expr, we should not preserve it in the final AST, as typo-expr is an internal AST node. We should use the one after the typo correction. This is spotted by a clangd hover crash on the testcase. Added: Modified: clang-tools-extra/clangd/unittests/HoverTests.cpp clang/lib/Sema/SemaDecl.cpp clang/test/AST/ast-dump-recovery.cpp Removed: diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp index 5ead74748f550c..28df24f34827c0 100644 --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -965,6 +965,19 @@ class Foo final {})cpp"; // Bindings are in theory public members of an anonymous struct. HI.AccessSpecifier = "public"; }}, + {// Don't crash on invalid decl with invalid init expr. + R"cpp( + Unknown [[^abc]] = invalid; + // error-ok + )cpp", + [](HoverInfo &HI) { + HI.Name = "abc"; + HI.Kind = index::SymbolKind::Variable; + HI.NamespaceScope = ""; + HI.Definition = "int abc = ()"; + HI.Type = "int"; + HI.AccessSpecifier = "public"; + }}, {// Extra info for function call. R"cpp( void fun(int arg_a, int &arg_b) {}; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 19968452f0d566..590f37837eb2df 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -13530,9 +13530,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { } if (VDecl->isInvalidDecl()) { -CorrectDelayedTyposInExpr(Init, VDecl); +ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl); +SmallVector SubExprs; +if (Res.isUsable()) + SubExprs.push_back(Res.get()); ExprResult Recovery = -CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), {Init}); +CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), SubExprs); if (Expr *E = Recovery.get()) VDecl->setInit(E); return; diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp index 77527743fe8577..a88dff471d9f04 100644 --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -419,6 +419,11 @@ void InitializerOfInvalidDecl() { // CHECK: VarDecl {{.*}} invalid InvalidDecl // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors // CHECK-NEXT: `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'ValidDecl' + + Unknown InvalidDeclWithInvalidInit = Invalid; + // CHECK: VarDecl {{.*}} invalid InvalidDeclWithInvalidInit + // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors + // CHECK-NOT:`-TypoExpr } void RecoverToAnInvalidDecl() { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-tools-extra] [clang] Don't preserve the typo expr in the recovery expr for invalid VarDecls (PR #90948)
https://github.com/hokein closed https://github.com/llvm/llvm-project/pull/90948 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [MSP430][Clang] Update list of MCUs (PR #91258)
https://github.com/maribu updated https://github.com/llvm/llvm-project/pull/91258 >From 182b64a1737d15646a70e5132aa906153b74e7d1 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 6 May 2024 20:42:44 +0200 Subject: [PATCH 1/2] [MSP430][Clang] Update list of MCUs This updates the list of MSP430 MCUs from TI's devices.csv obtained from [1] under the "Header and Support Files" link. A simple python script has been used to generate this list. [1]: https://www.ti.com/tool/MSP430-GCC-OPENSOURCE#downloads --- clang/include/clang/Basic/MSP430Target.def | 581 ++--- 1 file changed, 498 insertions(+), 83 deletions(-) diff --git a/clang/include/clang/Basic/MSP430Target.def b/clang/include/clang/Basic/MSP430Target.def index 7a10be1d54c8d6..a44486848db759 100644 --- a/clang/include/clang/Basic/MSP430Target.def +++ b/clang/include/clang/Basic/MSP430Target.def @@ -8,6 +8,8 @@ // // This file defines the MSP430 devices and their features. // +// Generated from TI's devices.csv in version 1.212 +// //===--===// #ifndef MSP430_MCU_FEAT @@ -24,7 +26,19 @@ MSP430_MCU("msp430c112") MSP430_MCU("msp430c1121") MSP430_MCU("msp430c1331") MSP430_MCU("msp430c1351") +MSP430_MCU("msp430c311s") +MSP430_MCU("msp430c312") +MSP430_MCU("msp430c313") +MSP430_MCU("msp430c314") +MSP430_MCU("msp430c315") +MSP430_MCU("msp430c323") +MSP430_MCU("msp430c325") +MSP430_MCU("msp430c412") +MSP430_MCU("msp430c413") MSP430_MCU("msp430e112") +MSP430_MCU("msp430e313") +MSP430_MCU("msp430e315") +MSP430_MCU("msp430e325") MSP430_MCU("msp430f110") MSP430_MCU("msp430f1101") MSP430_MCU("msp430f1101a") @@ -44,7 +58,6 @@ MSP430_MCU("msp430f135") MSP430_MCU("msp430f155") MSP430_MCU("msp430f156") MSP430_MCU("msp430f157") -MSP430_MCU("msp430p112") MSP430_MCU("msp430f2001") MSP430_MCU("msp430f2011") MSP430_MCU("msp430f2002") @@ -64,6 +77,58 @@ MSP430_MCU("msp430f2272") MSP430_MCU("msp430f2234") MSP430_MCU("msp430f2254") MSP430_MCU("msp430f2274") +MSP430_MCU("msp430f412") +MSP430_MCU("msp430f413") +MSP430_MCU("msp430f415") +MSP430_MCU("msp430f417") +MSP430_MCU("msp430f4132") +MSP430_MCU("msp430f4152") +MSP430_MCU("msp430f435") +MSP430_MCU("msp430f436") +MSP430_MCU("msp430f437") +MSP430_MCU("msp430f4351") +MSP430_MCU("msp430f4361") +MSP430_MCU("msp430f4371") +MSP430_MCU("msp430fe423") +MSP430_MCU("msp430fe425") +MSP430_MCU("msp430fe427") +MSP430_MCU("msp430fe423a") +MSP430_MCU("msp430fe425a") +MSP430_MCU("msp430fe427a") +MSP430_MCU("msp430fe4232") +MSP430_MCU("msp430fe4242") +MSP430_MCU("msp430fe4252") +MSP430_MCU("msp430fe4272") +MSP430_MCU("msp430f4250") +MSP430_MCU("msp430f4260") +MSP430_MCU("msp430f4270") +MSP430_MCU("msp430fg4250") +MSP430_MCU("msp430fg4260") +MSP430_MCU("msp430fg4270") +MSP430_MCU("msp430fw423") +MSP430_MCU("msp430fw425") +MSP430_MCU("msp430fw427") +MSP430_MCU("msp430fw428") +MSP430_MCU("msp430fw429") +MSP430_MCU("msp430fg437") +MSP430_MCU("msp430fg438") +MSP430_MCU("msp430fg439") +MSP430_MCU("msp430f438") +MSP430_MCU("msp430f439") +MSP430_MCU("msp430f477") +MSP430_MCU("msp430f478") +MSP430_MCU("msp430f479") +MSP430_MCU("msp430fg477") +MSP430_MCU("msp430fg478") +MSP430_MCU("msp430fg479") +MSP430_MCU("msp430p112") +MSP430_MCU("msp430p313") +MSP430_MCU("msp430p315") +MSP430_MCU("msp430p315s") +MSP430_MCU("msp430p325") +MSP430_MCU("msp430l092") +MSP430_MCU("msp430c091") +MSP430_MCU("msp430c092") MSP430_MCU("msp430g2211") MSP430_MCU("msp430g2201") MSP430_MCU("msp430g2111") @@ -115,68 +180,32 @@ MSP430_MCU("msp430g2855") MSP430_MCU("msp430g2955") MSP430_MCU("msp430g2230") MSP430_MCU("msp430g2210") -MSP430_MCU("msp430c311s") -MSP430_MCU("msp430c312") -MSP430_MCU("msp430c313") -MSP430_MCU("msp430c314") -MSP430_MCU("msp430c315") -MSP430_MCU("msp430c323") -MSP430_MCU("msp430c325") -MSP430_MCU("msp430c412") -MSP430_MCU("msp430c413") -MSP430_MCU("msp430e313") -MSP430_MCU("msp430e315") -MSP430_MCU("msp430e325") -MSP430_MCU("msp430p313") -MSP430_MCU("msp430p315") -MSP430_MCU("msp430p315s") -MSP430_MCU("msp430p325") -MSP430_MCU("msp430f412") -MSP430_MCU("msp430f413") -MSP430_MCU("msp430f415") -MSP430_MCU("msp430f417") -MSP430_MCU("msp430f4132") -MSP430_MCU("msp430f4152") -MSP430_MCU("msp430f435") -MSP430_MCU("msp430f436") -MSP430_MCU("msp430f437") -MSP430_MCU("msp430f4351") -MSP430_MCU("msp430f4361") -MSP430_MCU("msp430f4371") -MSP430_MCU("msp430fe423") -MSP430_MCU("msp430fe425") -MSP430_MCU("msp430fe427") -MSP430_MCU("msp430fe423a") -MSP430_MCU("msp430fe425a") -MSP430_MCU("msp430fe427a") -MSP430_MCU("msp430fe4232") -MSP430_MCU("msp430fe4242") -MSP430_MCU("msp430fe4252") -MSP430_MCU("msp430fe4272") -MSP430_MCU("msp430f4250") -MSP430_MCU("msp430f4260") -MSP430_MCU("msp430f4270") -MSP430_MCU("msp430fg4250") -MSP430_MCU("msp430fg4260") -MSP430_MCU("msp430fg4270") -MSP430_MCU("msp430fw423") -MSP430_MCU("msp430fw425") -MSP430_MCU("msp430fw427") -MSP430_MCU("msp430fw428") -MSP430_MCU("msp430fw429") -MSP430_MCU("msp430fg437") -MSP430_MC
[clang] [MSP430][Clang] Update list of MCUs (PR #91258)
https://github.com/maribu updated https://github.com/llvm/llvm-project/pull/91258 >From 182b64a1737d15646a70e5132aa906153b74e7d1 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 6 May 2024 20:42:44 +0200 Subject: [PATCH 1/3] [MSP430][Clang] Update list of MCUs This updates the list of MSP430 MCUs from TI's devices.csv obtained from [1] under the "Header and Support Files" link. A simple python script has been used to generate this list. [1]: https://www.ti.com/tool/MSP430-GCC-OPENSOURCE#downloads --- clang/include/clang/Basic/MSP430Target.def | 581 ++--- 1 file changed, 498 insertions(+), 83 deletions(-) diff --git a/clang/include/clang/Basic/MSP430Target.def b/clang/include/clang/Basic/MSP430Target.def index 7a10be1d54c8d..a44486848db75 100644 --- a/clang/include/clang/Basic/MSP430Target.def +++ b/clang/include/clang/Basic/MSP430Target.def @@ -8,6 +8,8 @@ // // This file defines the MSP430 devices and their features. // +// Generated from TI's devices.csv in version 1.212 +// //===--===// #ifndef MSP430_MCU_FEAT @@ -24,7 +26,19 @@ MSP430_MCU("msp430c112") MSP430_MCU("msp430c1121") MSP430_MCU("msp430c1331") MSP430_MCU("msp430c1351") +MSP430_MCU("msp430c311s") +MSP430_MCU("msp430c312") +MSP430_MCU("msp430c313") +MSP430_MCU("msp430c314") +MSP430_MCU("msp430c315") +MSP430_MCU("msp430c323") +MSP430_MCU("msp430c325") +MSP430_MCU("msp430c412") +MSP430_MCU("msp430c413") MSP430_MCU("msp430e112") +MSP430_MCU("msp430e313") +MSP430_MCU("msp430e315") +MSP430_MCU("msp430e325") MSP430_MCU("msp430f110") MSP430_MCU("msp430f1101") MSP430_MCU("msp430f1101a") @@ -44,7 +58,6 @@ MSP430_MCU("msp430f135") MSP430_MCU("msp430f155") MSP430_MCU("msp430f156") MSP430_MCU("msp430f157") -MSP430_MCU("msp430p112") MSP430_MCU("msp430f2001") MSP430_MCU("msp430f2011") MSP430_MCU("msp430f2002") @@ -64,6 +77,58 @@ MSP430_MCU("msp430f2272") MSP430_MCU("msp430f2234") MSP430_MCU("msp430f2254") MSP430_MCU("msp430f2274") +MSP430_MCU("msp430f412") +MSP430_MCU("msp430f413") +MSP430_MCU("msp430f415") +MSP430_MCU("msp430f417") +MSP430_MCU("msp430f4132") +MSP430_MCU("msp430f4152") +MSP430_MCU("msp430f435") +MSP430_MCU("msp430f436") +MSP430_MCU("msp430f437") +MSP430_MCU("msp430f4351") +MSP430_MCU("msp430f4361") +MSP430_MCU("msp430f4371") +MSP430_MCU("msp430fe423") +MSP430_MCU("msp430fe425") +MSP430_MCU("msp430fe427") +MSP430_MCU("msp430fe423a") +MSP430_MCU("msp430fe425a") +MSP430_MCU("msp430fe427a") +MSP430_MCU("msp430fe4232") +MSP430_MCU("msp430fe4242") +MSP430_MCU("msp430fe4252") +MSP430_MCU("msp430fe4272") +MSP430_MCU("msp430f4250") +MSP430_MCU("msp430f4260") +MSP430_MCU("msp430f4270") +MSP430_MCU("msp430fg4250") +MSP430_MCU("msp430fg4260") +MSP430_MCU("msp430fg4270") +MSP430_MCU("msp430fw423") +MSP430_MCU("msp430fw425") +MSP430_MCU("msp430fw427") +MSP430_MCU("msp430fw428") +MSP430_MCU("msp430fw429") +MSP430_MCU("msp430fg437") +MSP430_MCU("msp430fg438") +MSP430_MCU("msp430fg439") +MSP430_MCU("msp430f438") +MSP430_MCU("msp430f439") +MSP430_MCU("msp430f477") +MSP430_MCU("msp430f478") +MSP430_MCU("msp430f479") +MSP430_MCU("msp430fg477") +MSP430_MCU("msp430fg478") +MSP430_MCU("msp430fg479") +MSP430_MCU("msp430p112") +MSP430_MCU("msp430p313") +MSP430_MCU("msp430p315") +MSP430_MCU("msp430p315s") +MSP430_MCU("msp430p325") +MSP430_MCU("msp430l092") +MSP430_MCU("msp430c091") +MSP430_MCU("msp430c092") MSP430_MCU("msp430g2211") MSP430_MCU("msp430g2201") MSP430_MCU("msp430g2111") @@ -115,68 +180,32 @@ MSP430_MCU("msp430g2855") MSP430_MCU("msp430g2955") MSP430_MCU("msp430g2230") MSP430_MCU("msp430g2210") -MSP430_MCU("msp430c311s") -MSP430_MCU("msp430c312") -MSP430_MCU("msp430c313") -MSP430_MCU("msp430c314") -MSP430_MCU("msp430c315") -MSP430_MCU("msp430c323") -MSP430_MCU("msp430c325") -MSP430_MCU("msp430c412") -MSP430_MCU("msp430c413") -MSP430_MCU("msp430e313") -MSP430_MCU("msp430e315") -MSP430_MCU("msp430e325") -MSP430_MCU("msp430p313") -MSP430_MCU("msp430p315") -MSP430_MCU("msp430p315s") -MSP430_MCU("msp430p325") -MSP430_MCU("msp430f412") -MSP430_MCU("msp430f413") -MSP430_MCU("msp430f415") -MSP430_MCU("msp430f417") -MSP430_MCU("msp430f4132") -MSP430_MCU("msp430f4152") -MSP430_MCU("msp430f435") -MSP430_MCU("msp430f436") -MSP430_MCU("msp430f437") -MSP430_MCU("msp430f4351") -MSP430_MCU("msp430f4361") -MSP430_MCU("msp430f4371") -MSP430_MCU("msp430fe423") -MSP430_MCU("msp430fe425") -MSP430_MCU("msp430fe427") -MSP430_MCU("msp430fe423a") -MSP430_MCU("msp430fe425a") -MSP430_MCU("msp430fe427a") -MSP430_MCU("msp430fe4232") -MSP430_MCU("msp430fe4242") -MSP430_MCU("msp430fe4252") -MSP430_MCU("msp430fe4272") -MSP430_MCU("msp430f4250") -MSP430_MCU("msp430f4260") -MSP430_MCU("msp430f4270") -MSP430_MCU("msp430fg4250") -MSP430_MCU("msp430fg4260") -MSP430_MCU("msp430fg4270") -MSP430_MCU("msp430fw423") -MSP430_MCU("msp430fw425") -MSP430_MCU("msp430fw427") -MSP430_MCU("msp430fw428") -MSP430_MCU("msp430fw429") -MSP430_MCU("msp430fg437") -MSP430_MCU(
[clang] [MSP430][Clang] Update list of MCUs (PR #91258)
maribu wrote: Thx for the suggestion. I interpreted `Target/MSP430` as relative to where the definitions are; was this correct? My experience with LLVM is limited to using it, so I do not really know my way around :) https://github.com/llvm/llvm-project/pull/91258 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [MSP430][Clang] Update list of MCUs (PR #91258)
github-actions[bot] wrote: :warning: Python code formatter, darker found issues in your code. :warning: You can test this locally with the following command: ``bash darker --check --diff -r d0be944aa51194145cd15c987af67489f735059d...6d2759a81ff7c3e88fd2098c1e49d41e2426fa24 clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py `` View the diff from darker here. ``diff --- gen-msp430-def.py 2024-05-07 07:12:17.00 + +++ gen-msp430-def.py 2024-05-07 07:15:29.741381 + @@ -48,10 +48,11 @@ #undef MSP430_MCU #undef MSP430_MCU_FEAT """ + def csv2def(csv_path, def_path): """ Parse the devices.csv file at the given path, generate the definitions and write them to the given path. @@ -94,25 +95,25 @@ with open(def_path, "w") as def_file: def_file.write(PREFIX.format(version)) for mcu in mcus_multiplier_sw: -def_file.write(f"MSP430_MCU(\"{mcu}\")\n") +def_file.write(f'MSP430_MCU("{mcu}")\n') def_file.write("\n// With 16-bit hardware multiplier\n") for mcu in mcus_multiplier_hw_16: -def_file.write(f"MSP430_MCU_FEAT(\"{mcu}\", \"16bit\")\n") +def_file.write(f'MSP430_MCU_FEAT("{mcu}", "16bit")\n') def_file.write("\n// With 32-bit hardware multiplier\n") for mcu in mcus_multiplier_hw_32: -def_file.write(f"MSP430_MCU_FEAT(\"{mcu}\", \"32bit\")\n") +def_file.write(f'MSP430_MCU_FEAT("{mcu}", "32bit")\n') def_file.write(SUFFIX) -if __name__ == '__main__': +if __name__ == "__main__": if len(sys.argv) != 3: sys.exit(f"Usage: {sys.argv[0]} ") csv2def(sys.argv[1], sys.argv[2]) `` https://github.com/llvm/llvm-project/pull/91258 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [MSP430][Clang] Update list of MCUs (PR #91258)
github-actions[bot] wrote: :warning: Python code formatter, darker found issues in your code. :warning: You can test this locally with the following command: ``bash darker --check --diff -r d0be944aa51194145cd15c987af67489f735059d...768cdb82749df69e21db874323cdc472c1714619 clang/include/clang/Basic/Target/MSP430/gen-msp430-def.py `` View the diff from darker here. ``diff --- gen-msp430-def.py 2024-05-07 07:13:17.00 + +++ gen-msp430-def.py 2024-05-07 07:15:47.848631 + @@ -55,10 +55,11 @@ #undef MSP430_MCU #undef MSP430_MCU_FEAT """ + def csv2def(csv_path, def_path): """ Parse the devices.csv file at the given path, generate the definitions and write them to the given path. @@ -101,25 +102,25 @@ with open(def_path, "w") as def_file: def_file.write(PREFIX.format(version)) for mcu in mcus_multiplier_sw: -def_file.write(f"MSP430_MCU(\"{mcu}\")\n") +def_file.write(f'MSP430_MCU("{mcu}")\n') def_file.write("\n// With 16-bit hardware multiplier\n") for mcu in mcus_multiplier_hw_16: -def_file.write(f"MSP430_MCU_FEAT(\"{mcu}\", \"16bit\")\n") +def_file.write(f'MSP430_MCU_FEAT("{mcu}", "16bit")\n') def_file.write("\n// With 32-bit hardware multiplier\n") for mcu in mcus_multiplier_hw_32: -def_file.write(f"MSP430_MCU_FEAT(\"{mcu}\", \"32bit\")\n") +def_file.write(f'MSP430_MCU_FEAT("{mcu}", "32bit")\n') def_file.write(SUFFIX) -if __name__ == '__main__': +if __name__ == "__main__": if len(sys.argv) != 3: sys.exit(f"Usage: {sys.argv[0]} ") csv2def(sys.argv[1], sys.argv[2]) `` https://github.com/llvm/llvm-project/pull/91258 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/90588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Member Pointers (PR #91303)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/91303 This adds a `MemberPointer` class along with a `PT_MemberPtr` primitive type. A `MemberPointer` has a `Pointer` Base as well as a `Decl*` (could be `ValueDecl*`?) decl it points to. For the actual logic, this mainly changes the way we handle `PtrMemOp`s in `VisitBinaryOperator`. >From 8c8e25b55446c7824050b60b4a7e0790234da646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 10 Apr 2024 16:42:36 +0200 Subject: [PATCH] Memberpointers --- clang/lib/AST/CMakeLists.txt | 1 + clang/lib/AST/Interp/ByteCodeExprGen.cpp | 103 +- clang/lib/AST/Interp/Context.cpp | 15 +- clang/lib/AST/Interp/Context.h| 2 + clang/lib/AST/Interp/Descriptor.cpp | 1 + clang/lib/AST/Interp/Disasm.cpp | 3 + clang/lib/AST/Interp/Interp.cpp | 30 ++- clang/lib/AST/Interp/Interp.h | 99 ++ clang/lib/AST/Interp/InterpFrame.cpp | 1 + clang/lib/AST/Interp/InterpStack.cpp | 1 + clang/lib/AST/Interp/InterpStack.h| 3 + clang/lib/AST/Interp/MemberPointer.cpp| 80 clang/lib/AST/Interp/MemberPointer.h | 112 +++ clang/lib/AST/Interp/Opcodes.td | 18 +- clang/lib/AST/Interp/Pointer.cpp | 1 + clang/lib/AST/Interp/Pointer.h| 1 + clang/lib/AST/Interp/PrimType.cpp | 1 + clang/lib/AST/Interp/PrimType.h | 8 +- clang/test/AST/Interp/eval-order.cpp | 4 +- clang/test/AST/Interp/literals.cpp| 7 +- clang/test/AST/Interp/memberpointers.cpp | 184 ++ .../mangle-ms-templates-memptrs.cpp | 2 +- .../CodeGenCXX/pointers-to-data-members.cpp | 2 +- clang/test/SemaCXX/attr-weak.cpp | 1 + .../SemaCXX/nullptr_in_arithmetic_ops.cpp | 2 +- clang/unittests/AST/Interp/toAPValue.cpp | 46 + 26 files changed, 699 insertions(+), 29 deletions(-) create mode 100644 clang/lib/AST/Interp/MemberPointer.cpp create mode 100644 clang/lib/AST/Interp/MemberPointer.h create mode 100644 clang/test/AST/Interp/memberpointers.cpp diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index 3faefb54f599f..a5d3dacfc1a84 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -87,6 +87,7 @@ add_clang_library(clangAST Interp/Record.cpp Interp/Source.cpp Interp/State.cpp + Interp/MemberPointer.cpp Interp/InterpShared.cpp ItaniumCXXABI.cpp ItaniumMangle.cpp diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 630fdb60c3518..326eb6bf5d5c6 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -100,6 +100,35 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitMemcpy(CE); } + case CK_DerivedToBaseMemberPointer: { +assert(classifyPrim(CE->getType()) == PT_MemberPtr); +assert(classifyPrim(SubExpr->getType()) == PT_MemberPtr); +const auto *FromMP = SubExpr->getType()->getAs(); +const auto *ToMP = CE->getType()->getAs(); + +unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0), + QualType(FromMP->getClass(), 0)); + +if (!this->visit(SubExpr)) + return false; + +return this->emitGetMemberPtrBasePop(DerivedOffset, CE); + } + + case CK_BaseToDerivedMemberPointer: { +assert(classifyPrim(CE) == PT_MemberPtr); +assert(classifyPrim(SubExpr) == PT_MemberPtr); +const auto *FromMP = SubExpr->getType()->getAs(); +const auto *ToMP = CE->getType()->getAs(); + +unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0), + QualType(ToMP->getClass(), 0)); + +if (!this->visit(SubExpr)) + return false; +return this->emitGetMemberPtrBasePop(-DerivedOffset, CE); + } + case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { if (!this->visit(SubExpr)) @@ -187,7 +216,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitCastFloatingIntegral(*ToT, CE); } - case CK_NullToPointer: { + case CK_NullToPointer: + case CK_NullToMemberPointer: { if (DiscardResult) return true; @@ -326,7 +356,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitCast(*FromT, *ToT, CE); } - case CK_PointerToBoolean: { + case CK_PointerToBoolean: + case CK_MemberPointerToBoolean: { PrimType PtrT = classifyPrim(SubExpr->getType()); // Just emit p != nullptr for this. @@ -534,8 +565,23 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { BO->isComparisonOp()) return this->emitComplexComparison(LHS, RHS, BO); - if (BO->
[clang] [clang][Interp] Member Pointers (PR #91303)
@@ -0,0 +1,80 @@ + + +#include "MemberPointer.h" +#include "Context.h" +#include "FunctionPointer.h" +#include "Program.h" +#include "Record.h" + +namespace clang { +namespace interp { + +std::optional MemberPointer::toPointer(const Context &Ctx) const { + if (!Dcl || isa(Dcl)) +return Base; + const FieldDecl *FD = cast(Dcl); + assert(FD); + + Pointer CastedBase = + (PtrOffset < 0 ? Base.atField(-PtrOffset) : Base.atFieldSub(PtrOffset)); + + // FIXME: The Base Pointer might be a dummy pointer. In that case, we can + // still do all of this and return yet another dummy pointer, but with the + // Base/Offset adjusted. However, right now we don't have the necessary type + // information for dummy pointers. + if (CastedBase.isDummy()) +return std::nullopt; + + const Record *BaseRecord = CastedBase.getRecord(); + assert(BaseRecord); + + if (FD->getParent() == BaseRecord->getDecl()) +return CastedBase.atField(BaseRecord->getField(FD)->Offset); + + unsigned Offset; + const RecordDecl *FieldParent = FD->getParent(); + const Record *FieldRecord = Ctx.getRecord(FieldParent); + + Offset = 0; + Offset += FieldRecord->getField(FD)->Offset; + Offset += CastedBase.block()->getDescriptor()->getMetadataSize(); + + if (Offset > CastedBase.block()->getSize()) +return std::nullopt; + + unsigned O = 0; + if (Base.getDeclPtr().getRecord()->getDecl() != FieldParent) { +O = Ctx.collectBaseOffset(FieldParent, + Pointer(const_cast(Base.block()), 16, 16) + .getRecord() + ->getDecl()); tbaederr wrote: This part needs some work. https://github.com/llvm/llvm-project/pull/91303 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Member Pointers (PR #91303)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) Changes This adds a `MemberPointer` class along with a `PT_MemberPtr` primitive type. A `MemberPointer` has a `Pointer` Base as well as a `Decl*` (could be `ValueDecl*`?) decl it points to. For the actual logic, this mainly changes the way we handle `PtrMemOp`s in `VisitBinaryOperator`. --- Patch is 39.59 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/91303.diff 26 Files Affected: - (modified) clang/lib/AST/CMakeLists.txt (+1) - (modified) clang/lib/AST/Interp/ByteCodeExprGen.cpp (+93-10) - (modified) clang/lib/AST/Interp/Context.cpp (+9-6) - (modified) clang/lib/AST/Interp/Context.h (+2) - (modified) clang/lib/AST/Interp/Descriptor.cpp (+1) - (modified) clang/lib/AST/Interp/Disasm.cpp (+3) - (modified) clang/lib/AST/Interp/Interp.cpp (+26-4) - (modified) clang/lib/AST/Interp/Interp.h (+99) - (modified) clang/lib/AST/Interp/InterpFrame.cpp (+1) - (modified) clang/lib/AST/Interp/InterpStack.cpp (+1) - (modified) clang/lib/AST/Interp/InterpStack.h (+3) - (added) clang/lib/AST/Interp/MemberPointer.cpp (+80) - (added) clang/lib/AST/Interp/MemberPointer.h (+112) - (modified) clang/lib/AST/Interp/Opcodes.td (+16-2) - (modified) clang/lib/AST/Interp/Pointer.cpp (+1) - (modified) clang/lib/AST/Interp/Pointer.h (+1) - (modified) clang/lib/AST/Interp/PrimType.cpp (+1) - (modified) clang/lib/AST/Interp/PrimType.h (+7-1) - (modified) clang/test/AST/Interp/eval-order.cpp (+2-2) - (modified) clang/test/AST/Interp/literals.cpp (+6-1) - (added) clang/test/AST/Interp/memberpointers.cpp (+184) - (modified) clang/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp (+1-1) - (modified) clang/test/CodeGenCXX/pointers-to-data-members.cpp (+1-1) - (modified) clang/test/SemaCXX/attr-weak.cpp (+1) - (modified) clang/test/SemaCXX/nullptr_in_arithmetic_ops.cpp (+1-1) - (modified) clang/unittests/AST/Interp/toAPValue.cpp (+46) ``diff diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index 3faefb54f599fb..a5d3dacfc1a84e 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -87,6 +87,7 @@ add_clang_library(clangAST Interp/Record.cpp Interp/Source.cpp Interp/State.cpp + Interp/MemberPointer.cpp Interp/InterpShared.cpp ItaniumCXXABI.cpp ItaniumMangle.cpp diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 630fdb60c35182..326eb6bf5d5c61 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -100,6 +100,35 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitMemcpy(CE); } + case CK_DerivedToBaseMemberPointer: { +assert(classifyPrim(CE->getType()) == PT_MemberPtr); +assert(classifyPrim(SubExpr->getType()) == PT_MemberPtr); +const auto *FromMP = SubExpr->getType()->getAs(); +const auto *ToMP = CE->getType()->getAs(); + +unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0), + QualType(FromMP->getClass(), 0)); + +if (!this->visit(SubExpr)) + return false; + +return this->emitGetMemberPtrBasePop(DerivedOffset, CE); + } + + case CK_BaseToDerivedMemberPointer: { +assert(classifyPrim(CE) == PT_MemberPtr); +assert(classifyPrim(SubExpr) == PT_MemberPtr); +const auto *FromMP = SubExpr->getType()->getAs(); +const auto *ToMP = CE->getType()->getAs(); + +unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0), + QualType(ToMP->getClass(), 0)); + +if (!this->visit(SubExpr)) + return false; +return this->emitGetMemberPtrBasePop(-DerivedOffset, CE); + } + case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { if (!this->visit(SubExpr)) @@ -187,7 +216,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitCastFloatingIntegral(*ToT, CE); } - case CK_NullToPointer: { + case CK_NullToPointer: + case CK_NullToMemberPointer: { if (DiscardResult) return true; @@ -326,7 +356,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitCast(*FromT, *ToT, CE); } - case CK_PointerToBoolean: { + case CK_PointerToBoolean: + case CK_MemberPointerToBoolean: { PrimType PtrT = classifyPrim(SubExpr->getType()); // Just emit p != nullptr for this. @@ -534,8 +565,23 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { BO->isComparisonOp()) return this->emitComplexComparison(LHS, RHS, BO); - if (BO->isPtrMemOp()) -return this->visit(RHS); + if (BO->isPtrMemOp()) { +if (!this->visit(LHS)) + return false; + +if (!this->visit(RHS)) + return false; + +if (!this->emitToMemberPtr(BO)) + return false; + +if (classifyPrim(BO) == PT_MemberPtr)
[clang] [clang][dataflow] Strengthen pointer comparison. (PR #75170)
martinboehme wrote: > > In summary, if the storage locations for two pointers are the same, we can > > return a true literal for the comparison, but if the storage locations are > > different, we need to return an atom. > > I am wondering, if it would make sense to "fix up" the state when we discover > aliasing? I.e., "merging" the two storage locations. Consider: > > ``` > void f(MyBoolPair* a, MyBoolPair *b) { > if (a == b && a->first && !b->second) > { > // Here, we should know: a->first == b->first == true and a->second == > b->second == false > } > } > ``` This sounds great -- but I think getting this to work wouldn't be trivial. At least, I don't yet have any good ideas on how to make it work. I think we'd have to do something like this: 1. When we evaluate `a == b`, associate this expression with an atom, then remember that this atom means that the storage locations for the two pointers are the same. 2. When we enter a new block, if we can prove from the flow condition that the atom mentioned in step 1 is true, remember that the storage locations for `a` and `b` must alias. 3. When we evaluate `b->first` -- I guess we iterate over all of the storage locations that must alias with the storage location for `b`, and if, for at least one of them, we can prove that `b->first` is true, we know it must be true? (I'm not super-conversant in alias analysis -- would have to read up more about this.) Would require some more thought and definitely quite a bit of effort to implement, I think. https://github.com/llvm/llvm-project/pull/75170 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [MSP430][Clang] Update list of MCUs (PR #91258)
https://github.com/maribu updated https://github.com/llvm/llvm-project/pull/91258 >From 182b64a1737d15646a70e5132aa906153b74e7d1 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 6 May 2024 20:42:44 +0200 Subject: [PATCH 1/4] [MSP430][Clang] Update list of MCUs This updates the list of MSP430 MCUs from TI's devices.csv obtained from [1] under the "Header and Support Files" link. A simple python script has been used to generate this list. [1]: https://www.ti.com/tool/MSP430-GCC-OPENSOURCE#downloads --- clang/include/clang/Basic/MSP430Target.def | 581 ++--- 1 file changed, 498 insertions(+), 83 deletions(-) diff --git a/clang/include/clang/Basic/MSP430Target.def b/clang/include/clang/Basic/MSP430Target.def index 7a10be1d54c8d..a44486848db75 100644 --- a/clang/include/clang/Basic/MSP430Target.def +++ b/clang/include/clang/Basic/MSP430Target.def @@ -8,6 +8,8 @@ // // This file defines the MSP430 devices and their features. // +// Generated from TI's devices.csv in version 1.212 +// //===--===// #ifndef MSP430_MCU_FEAT @@ -24,7 +26,19 @@ MSP430_MCU("msp430c112") MSP430_MCU("msp430c1121") MSP430_MCU("msp430c1331") MSP430_MCU("msp430c1351") +MSP430_MCU("msp430c311s") +MSP430_MCU("msp430c312") +MSP430_MCU("msp430c313") +MSP430_MCU("msp430c314") +MSP430_MCU("msp430c315") +MSP430_MCU("msp430c323") +MSP430_MCU("msp430c325") +MSP430_MCU("msp430c412") +MSP430_MCU("msp430c413") MSP430_MCU("msp430e112") +MSP430_MCU("msp430e313") +MSP430_MCU("msp430e315") +MSP430_MCU("msp430e325") MSP430_MCU("msp430f110") MSP430_MCU("msp430f1101") MSP430_MCU("msp430f1101a") @@ -44,7 +58,6 @@ MSP430_MCU("msp430f135") MSP430_MCU("msp430f155") MSP430_MCU("msp430f156") MSP430_MCU("msp430f157") -MSP430_MCU("msp430p112") MSP430_MCU("msp430f2001") MSP430_MCU("msp430f2011") MSP430_MCU("msp430f2002") @@ -64,6 +77,58 @@ MSP430_MCU("msp430f2272") MSP430_MCU("msp430f2234") MSP430_MCU("msp430f2254") MSP430_MCU("msp430f2274") +MSP430_MCU("msp430f412") +MSP430_MCU("msp430f413") +MSP430_MCU("msp430f415") +MSP430_MCU("msp430f417") +MSP430_MCU("msp430f4132") +MSP430_MCU("msp430f4152") +MSP430_MCU("msp430f435") +MSP430_MCU("msp430f436") +MSP430_MCU("msp430f437") +MSP430_MCU("msp430f4351") +MSP430_MCU("msp430f4361") +MSP430_MCU("msp430f4371") +MSP430_MCU("msp430fe423") +MSP430_MCU("msp430fe425") +MSP430_MCU("msp430fe427") +MSP430_MCU("msp430fe423a") +MSP430_MCU("msp430fe425a") +MSP430_MCU("msp430fe427a") +MSP430_MCU("msp430fe4232") +MSP430_MCU("msp430fe4242") +MSP430_MCU("msp430fe4252") +MSP430_MCU("msp430fe4272") +MSP430_MCU("msp430f4250") +MSP430_MCU("msp430f4260") +MSP430_MCU("msp430f4270") +MSP430_MCU("msp430fg4250") +MSP430_MCU("msp430fg4260") +MSP430_MCU("msp430fg4270") +MSP430_MCU("msp430fw423") +MSP430_MCU("msp430fw425") +MSP430_MCU("msp430fw427") +MSP430_MCU("msp430fw428") +MSP430_MCU("msp430fw429") +MSP430_MCU("msp430fg437") +MSP430_MCU("msp430fg438") +MSP430_MCU("msp430fg439") +MSP430_MCU("msp430f438") +MSP430_MCU("msp430f439") +MSP430_MCU("msp430f477") +MSP430_MCU("msp430f478") +MSP430_MCU("msp430f479") +MSP430_MCU("msp430fg477") +MSP430_MCU("msp430fg478") +MSP430_MCU("msp430fg479") +MSP430_MCU("msp430p112") +MSP430_MCU("msp430p313") +MSP430_MCU("msp430p315") +MSP430_MCU("msp430p315s") +MSP430_MCU("msp430p325") +MSP430_MCU("msp430l092") +MSP430_MCU("msp430c091") +MSP430_MCU("msp430c092") MSP430_MCU("msp430g2211") MSP430_MCU("msp430g2201") MSP430_MCU("msp430g2111") @@ -115,68 +180,32 @@ MSP430_MCU("msp430g2855") MSP430_MCU("msp430g2955") MSP430_MCU("msp430g2230") MSP430_MCU("msp430g2210") -MSP430_MCU("msp430c311s") -MSP430_MCU("msp430c312") -MSP430_MCU("msp430c313") -MSP430_MCU("msp430c314") -MSP430_MCU("msp430c315") -MSP430_MCU("msp430c323") -MSP430_MCU("msp430c325") -MSP430_MCU("msp430c412") -MSP430_MCU("msp430c413") -MSP430_MCU("msp430e313") -MSP430_MCU("msp430e315") -MSP430_MCU("msp430e325") -MSP430_MCU("msp430p313") -MSP430_MCU("msp430p315") -MSP430_MCU("msp430p315s") -MSP430_MCU("msp430p325") -MSP430_MCU("msp430f412") -MSP430_MCU("msp430f413") -MSP430_MCU("msp430f415") -MSP430_MCU("msp430f417") -MSP430_MCU("msp430f4132") -MSP430_MCU("msp430f4152") -MSP430_MCU("msp430f435") -MSP430_MCU("msp430f436") -MSP430_MCU("msp430f437") -MSP430_MCU("msp430f4351") -MSP430_MCU("msp430f4361") -MSP430_MCU("msp430f4371") -MSP430_MCU("msp430fe423") -MSP430_MCU("msp430fe425") -MSP430_MCU("msp430fe427") -MSP430_MCU("msp430fe423a") -MSP430_MCU("msp430fe425a") -MSP430_MCU("msp430fe427a") -MSP430_MCU("msp430fe4232") -MSP430_MCU("msp430fe4242") -MSP430_MCU("msp430fe4252") -MSP430_MCU("msp430fe4272") -MSP430_MCU("msp430f4250") -MSP430_MCU("msp430f4260") -MSP430_MCU("msp430f4270") -MSP430_MCU("msp430fg4250") -MSP430_MCU("msp430fg4260") -MSP430_MCU("msp430fg4270") -MSP430_MCU("msp430fw423") -MSP430_MCU("msp430fw425") -MSP430_MCU("msp430fw427") -MSP430_MCU("msp430fw428") -MSP430_MCU("msp430fw429") -MSP430_MCU("msp430fg437") -MSP430_MCU(
[clang] [llvm] [AArch64] Add intrinsics for multi-vector to ZA array vector accumulators (PR #88266)
https://github.com/CarolineConcatto approved this pull request. https://github.com/llvm/llvm-project/pull/88266 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Update FEAT_PAuth_LR behaviour for AArch64 (PR #90614)
https://github.com/Stylie777 updated https://github.com/llvm/llvm-project/pull/90614 >From fa5d76b2d6d095abad76d892e59751727ac2e556 Mon Sep 17 00:00:00 2001 From: Jack Styles Date: Wed, 17 Apr 2024 14:17:51 +0100 Subject: [PATCH 1/4] [NFC] Add Extension Lookup to AArch64TargetParser Currently, an extension cannot be found using the ExtID. To address this, the function `lookupExtensionByID` has been added to the `ExtensionSet` Class so it can be targeted from outside the function. This will allow for the Extensions Information to be searched for and stored externally to the ExtensionSet Class. This enables being able to search for if Architecture Features have been enabled by the user in the command line. --- llvm/include/llvm/TargetParser/AArch64TargetParser.h | 2 ++ llvm/lib/TargetParser/AArch64TargetParser.cpp| 5 + 2 files changed, 7 insertions(+) diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h index f372cee7633f6..866711a632c60 100644 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -858,6 +858,8 @@ inline constexpr Alias CpuAliases[] = {{"cobalt-100", "neoverse-n2"}, inline constexpr Alias ExtAliases[] = {{"rdma", "rdm"}}; +const ExtensionInfo &getExtensionByID(ArchExtKind(ExtID)); + bool getExtensionFeatures( const AArch64::ExtensionBitset &Extensions, std::vector &Features); diff --git a/llvm/lib/TargetParser/AArch64TargetParser.cpp b/llvm/lib/TargetParser/AArch64TargetParser.cpp index 71099462d5ecf..026214e7e2eac 100644 --- a/llvm/lib/TargetParser/AArch64TargetParser.cpp +++ b/llvm/lib/TargetParser/AArch64TargetParser.cpp @@ -280,3 +280,8 @@ bool AArch64::ExtensionSet::parseModifier(StringRef Modifier) { } return false; } + +const AArch64::ExtensionInfo & +AArch64::getExtensionByID(AArch64::ArchExtKind ExtID) { + return lookupExtensionByID(ExtID); +} >From ff848b0183afc0184fbf9cdfb64281b51b23cd42 Mon Sep 17 00:00:00 2001 From: Jack Styles Date: Wed, 17 Apr 2024 14:35:43 +0100 Subject: [PATCH 2/4] [AArch64] Enable PAuthLR by default for standard branch protection when the feature is available Currently, LLVM implements the `standard` option as `bti+pac-ret` for ARM and AArch64. Following discussions with the GNU developemnt team within Arm it was decided to align the behaviour of `standard` to match across the different compilers. To ensure the behaviour is aligned. LLVM has been updated to implement `standard` as `bti+pac-ret+pc` by default when `+pauth-lr` is passed as part of the `-march` argument. --- clang/lib/Basic/Targets/AArch64.cpp| 2 +- clang/lib/Driver/ToolChains/Clang.cpp | 18 +- .../Preprocessor/aarch64-target-features.c | 4 llvm/docs/ReleaseNotes.rst | 5 + .../llvm/TargetParser/ARMTargetParserCommon.h | 2 +- .../lib/TargetParser/ARMTargetParserCommon.cpp | 3 ++- 6 files changed, 30 insertions(+), 4 deletions(-) diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index c8d243a8fb7ae..5a46a3e6c6fd3 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -224,7 +224,7 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, BranchProtectionInfo &BPI, StringRef &Err) const { llvm::ARM::ParsedBranchProtection PBP; - if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) + if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, HasPAuthLR)) return false; BPI.SignReturnAddr = diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 1f08c5958dfb6..63e04bfbf93c0 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1511,7 +1511,23 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, } else { StringRef DiagMsg; llvm::ARM::ParsedBranchProtection PBP; -if (!llvm::ARM::parseBranchProtection(A->getValue(), PBP, DiagMsg)) + +// To know if we need to enable PAuth-LR As part of the standard branch +// protection option, it needs to be determined if the feature has been +// activated in the `march` argument. This information is stored within the +// CmdArgs variable and can be found using a search. +if (isAArch64) { + auto isPAuthLR = [](const char *member) { +llvm::AArch64::ExtensionInfo pauthlr_extension = +llvm::AArch64::getExtensionByID(llvm::AArch64::AEK_PAUTHLR); +return (pauthlr_extension.Feature.compare(member) == 0); + }; + + if (std::any_of(CmdArgs.begin(), CmdArgs.end(), isPAuthLR)) +EnablePAuthLR = true; +} +if (!llvm::ARM::parseBranchProtection(A->getValue(), PBP, DiagMsg, +
[clang] [llvm] [AArch64] Add intrinsics for 16-bit non-widening FMLA/FMLS (PR #88553)
https://github.com/CarolineConcatto approved this pull request. https://github.com/llvm/llvm-project/pull/88553 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Strengthen pointer comparison. (PR #75170)
martinboehme wrote: CI failure (DataFlowSanitizer-x86_64 :: release_shadow_space.c) looks unrelated. https://github.com/llvm/llvm-project/pull/75170 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f3fbd21 - [clang][dataflow] Strengthen pointer comparison. (#75170)
Author: martinboehme Date: 2024-05-07T10:12:23+02:00 New Revision: f3fbd21fa4e25496725c22d987e4e47e4c39c8b0 URL: https://github.com/llvm/llvm-project/commit/f3fbd21fa4e25496725c22d987e4e47e4c39c8b0 DIFF: https://github.com/llvm/llvm-project/commit/f3fbd21fa4e25496725c22d987e4e47e4c39c8b0.diff LOG: [clang][dataflow] Strengthen pointer comparison. (#75170) - Instead of comparing the identity of the `PointerValue`s, compare the underlying `StorageLocation`s. - If the `StorageLocation`s are the same, return a definite "true" as the result of the comparison. Before, if the `PointerValue`s were different, we would return an atom, even if the storage locations themselves were the same. - If the `StorageLocation`s are different, return an atom (as before). Pointers that have different storage locations may still alias, so we can't return a definite "false" in this case. The application-level gains from this are relatively modest. For the Crubit nullability check running on an internal codebase, this change reduces the number of functions on which the SAT solver times out from 223 to 221; the number of "pointer expression not modeled" errors reduces from 3815 to 3778. Still, it seems that the gain in precision is generally worthwhile. @Xazax-hun inspired me to think about this with his [comments](https://github.com/llvm/llvm-project/pull/73860#pullrequestreview-1761484615) on a different PR. Added: Modified: clang/lib/Analysis/FlowSensitive/Transfer.cpp clang/unittests/Analysis/FlowSensitive/TransferTest.cpp Removed: diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 5a57f11b000d8a..4214488c98e5de 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -68,6 +68,14 @@ static BoolValue &evaluateBooleanEquality(const Expr &LHS, const Expr &RHS, if (auto *RHSBool = dyn_cast_or_null(RHSValue)) return Env.makeIff(*LHSBool, *RHSBool); + if (auto *LHSPtr = dyn_cast_or_null(LHSValue)) +if (auto *RHSPtr = dyn_cast_or_null(RHSValue)) + // If the storage locations are the same, the pointers definitely compare + // the same. If the storage locations are diff erent, they may still alias, + // so we fall through to the case below that returns an atom. + if (&LHSPtr->getPointeeLoc() == &RHSPtr->getPointeeLoc()) +return Env.getBoolLiteralValue(true); + return Env.makeAtomicBoolValue(); } diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 6743e778a2ffeb..e1fb16b64fd6f5 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -4709,6 +4709,94 @@ TEST(TransferTest, BooleanInequality) { }); } +TEST(TransferTest, PointerEquality) { + std::string Code = R"cc( +void target() { + int i = 0; + int i_other = 0; + int *p1 = &i; + int *p2 = &i; + int *p_other = &i_other; + int *null = nullptr; + + bool p1_eq_p1 = (p1 == p1); + bool p1_eq_p2 = (p1 == p2); + bool p1_eq_p_other = (p1 == p_other); + + bool p1_eq_null = (p1 == null); + bool p1_eq_nullptr = (p1 == nullptr); + bool null_eq_nullptr = (null == nullptr); + bool nullptr_eq_nullptr = (nullptr == nullptr); + + // We won't duplicate all of the tests above with `!=`, as we know that + // the implementation simply negates the result of the `==` comparison. + // Instaed, just spot-check one case. + bool p1_ne_p1 = (p1 != p1); + + (void)0; // [[p]] +} + )cc"; + runDataflow( + Code, + [](const llvm::StringMap> &Results, + ASTContext &ASTCtx) { +const Environment &Env = getEnvironmentAtAnnotation(Results, "p"); + +// Check the we have indeed set things up so that `p1` and `p2` have +// diff erent pointer values. +EXPECT_NE(&getValueForDecl(ASTCtx, Env, "p1"), + &getValueForDecl(ASTCtx, Env, "p2")); + +EXPECT_EQ(&getValueForDecl(ASTCtx, Env, "p1_eq_p1"), + &Env.getBoolLiteralValue(true)); +EXPECT_EQ(&getValueForDecl(ASTCtx, Env, "p1_eq_p2"), + &Env.getBoolLiteralValue(true)); +EXPECT_TRUE(isa( +getValueForDecl(ASTCtx, Env, "p1_eq_p_other"))); + +EXPECT_TRUE(isa( +getValueForDecl(ASTCtx, Env, "p1_eq_null"))); +EXPECT_TRUE(isa( +getValueForDecl(ASTCtx, Env, "p1_eq_nullptr"))); +EXPECT_EQ(&getValueForDecl(ASTCtx, Env, "null_eq_nullptr"), + &Env.getBoolLiteralValue(true)); +EXPECT_EQ( +&getValueForDecl(ASTCtx, Env, "nullptr_eq_nullptr"), +&Env.getBoolLiteralValue(true)); + +EXPECT_EQ(&getValueForD
[clang] [clang][dataflow] Strengthen pointer comparison. (PR #75170)
https://github.com/martinboehme closed https://github.com/llvm/llvm-project/pull/75170 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Add __builtin_selectvector and use it for AVX512 intrinsics (PR #91306)
https://github.com/philnik777 edited https://github.com/llvm/llvm-project/pull/91306 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Fix malformed AST for anonymous class access in template. (PR #90842)
https://github.com/martinboehme updated https://github.com/llvm/llvm-project/pull/90842 >From 4cbb2ae74abba0cff20d2c9018680c7bcc743316 Mon Sep 17 00:00:00 2001 From: Martin Braenne Date: Thu, 2 May 2024 09:59:16 + Subject: [PATCH 1/3] [Clang][Sema] Fix malformed AST for anonymous class access in template. # Observed erroneous behavior Prior to this change, a `MemberExpr` that accesses an anonymous class might have a prvalue as its base (even though C++ mandates that the base of a `MemberExpr` must be a glvalue), if the code containing the `MemberExpr` was in a template. Here's an example on [godbolt](https://godbolt.org/z/Gz1Mer9oz) (that is essentially identical to the new test this patch adds). This example sets up a struct containing an anonymous struct: ```cxx struct S { struct { int i; }; }; ``` It then accesses the member `i` using the expression `S().i`. When we do this in a non-template function, we get the following AST: ``` `-ExprWithCleanups 'int' `-ImplicitCastExpr 'int' `-MemberExpr 'int' xvalue .i 0xbdcb3c0 `-MemberExpr 'S::(anonymous struct at line:2:3)' xvalue .S::(anonymous struct at line:2:3) 0xbdcb488 `-MaterializeTemporaryExpr 'S' xvalue `-CXXTemporaryObjectExpr 'S' 'void () noexcept' zeroing ``` As expected, the AST contains a `MaterializeTemporarExpr` to materialize the prvalue `S()` before accessing its members. When we perform this access in a function template (that doesn't actually even use its template parameter), the AST for the template itself looks the same as above. However, the AST for an instantiation of the template looks different: ``` `-ExprWithCleanups 'int' `-ImplicitCastExpr 'int' `-MemberExpr 'int' xvalue .i 0xbdcb3c0 `-MaterializeTemporaryExpr 'S::(anonymous struct at line:2:3)' xvalue `-MemberExpr 'S::(anonymous struct at line:2:3)' .S::(anonymous struct at line:2:3) 0xbdcb488 `-CXXTemporaryObjectExpr 'S' 'void () noexcept' zeroing ``` Note how the inner `MemberExpr` (the one accessing the anonymous struct) acts on a prvalue. Interestingly, this does not appear to cause any problems for CodeGen, probably because CodeGen is set up to deal with `MemberExpr`s on rvalues in C. However, it does cause issues in the dataflow framework, which only supports C++ today and expects the base of a `MemberExpr` to be a glvalue. Beyond the issues with the dataflow framework, I think this issue should be fixed because it goes contrary to what the C++ standard mandates, and the AST produced for the non-template case indicates that we want to follow the C++ rules here. # Reasons for erroneous behavior Here's why we're getting this malformed AST. First of all, `TreeTransform` [strips any `MaterializeTemporaryExpr`s](https://github.com/llvm/llvm-project/blob/cd132dcbeb0fc79fd657bd5e0a8e9244c3fb5da6/clang/lib/Sema/TreeTransform.h#L14853) from the AST. It is therefore up to [`TreeTransform::RebuildMemberExpr()`](https://github.com/llvm/llvm-project/blob/cd132dcbeb0fc79fd657bd5e0a8e9244c3fb5da6/clang/lib/Sema/TreeTransform.h#L2853) to recreate a `MaterializeTemporaryExpr` if needed. In the [general case](https://github.com/llvm/llvm-project/blob/cd132dcbeb0fc79fd657bd5e0a8e9244c3fb5da6/clang/lib/Sema/TreeTransform.h#L2915), it does this: It calls `Sema::BuildMemberReferenceExpr()`, which ensures that the base is a glvalue by [materializing a temporary](https://github.com/llvm/llvm-project/blob/cd132dcbeb0fc79fd657bd5e0a8e9244c3fb5da6/clang/lib/Sema/SemaExprMember.cpp#L1016) if needed. However, when `TreeTransform::RebuildMemberExpr()` encounters an anonymous class, it [calls `Sema::BuildFieldReferenceExpr()`](https://github.com/llvm/llvm-project/blob/cd132dcbeb0fc79fd657bd5e0a8e9244c3fb5da6/clang/lib/Sema/TreeTransform.h#L2880), which, unlike `Sema::BuildMemberReferenceExpr()`, does not make sure that the base is a glvalue. # Proposed fix I considered several possible ways to fix this issue: - Add logic to `Sema::BuildFieldReferenceExpr()` that materializes a temporary if needed. This appears to work, but it feels like the fix is in the wrong place: - AFAIU, other callers of `Sema::BuildFieldReferenceExpr()` don't need this logic. - The issue is caused by `TreeTransform` removing the `MaterializeTemporaryExpr`, so it seems the fix should also be in `TreeTransform` - Materialize the temporary directly in `TreeTransform::RebuildMemberExpr()` if needed (within the case that deals with anonymous classes). This would work, too, but it would duplicate logic that already exists in `Sema::BuildMemberReferenceExpr()` (which we leverage for the general case). - Use `Sema::BuildMemberReferenceExpr()` instead of `Sema::BuildFieldReferenceExpr()` for the anonymous class case, so that it also uses the existing logic for materializing the temporary. This is the option I've decided to go with here. There's a slight wrinkle in that we c
[clang] [Clang] Add __builtin_selectvector and use it for AVX512 intrinsics (PR #91306)
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 09327efdf0f02c4f865a4536db96cac539bb1c01 25ab7acb3de4abaf6ad72eab3fa52227920f8518 -- clang/test/Sema/builtin-selectvector.c clang/lib/CodeGen/CGBuiltin.cpp clang/lib/Headers/avx512bf16intrin.h clang/lib/Headers/avx512bitalgintrin.h clang/lib/Headers/avx512bwintrin.h clang/lib/Headers/avx512cdintrin.h clang/lib/Headers/avx512dqintrin.h clang/lib/Headers/avx512fintrin.h clang/lib/Headers/avx512fp16intrin.h clang/lib/Headers/avx512ifmaintrin.h clang/lib/Headers/avx512ifmavlintrin.h clang/lib/Headers/avx512vbmi2intrin.h clang/lib/Headers/avx512vbmiintrin.h clang/lib/Headers/avx512vbmivlintrin.h clang/lib/Headers/avx512vlbf16intrin.h clang/lib/Headers/avx512vlbitalgintrin.h clang/lib/Headers/avx512vlbwintrin.h clang/lib/Headers/avx512vlcdintrin.h clang/lib/Headers/avx512vldqintrin.h clang/lib/Headers/avx512vlfp16intrin.h clang/lib/Headers/avx512vlintrin.h clang/lib/Headers/avx512vlvbmi2intrin.h clang/lib/Headers/avx512vlvnniintrin.h clang/lib/Headers/avx512vnniintrin.h clang/lib/Headers/avx512vpopcntdqintrin.h clang/lib/Headers/avx512vpopcntdqvlintrin.h clang/lib/Headers/gfniintrin.h clang/lib/Sema/SemaChecking.cpp clang/test/CodeGen/X86/avx512dq-builtins.c clang/test/CodeGen/X86/avx512f-builtins-constrained.c clang/test/CodeGen/X86/avx512f-builtins.c clang/test/CodeGen/X86/avx512fp16-builtins.c clang/test/CodeGen/X86/avx512vl-builtins.c clang/test/CodeGen/X86/avx512vlfp16-builtins.c `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Headers/avx512vlbwintrin.h b/clang/lib/Headers/avx512vlbwintrin.h index 79be7a645c..e75147b838 100644 --- a/clang/lib/Headers/avx512vlbwintrin.h +++ b/clang/lib/Headers/avx512vlbwintrin.h @@ -1682,7 +1682,7 @@ _mm_mask_unpackhi_epi16(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_maskz_unpackhi_epi16(__mmask8 __U, __m128i __A, __m128i __B) { return (__m128i)__builtin_selectvector((__v8hi)_mm_unpackhi_epi16(__A, __B), - (__v8hi) _mm_setzero_si128(), + (__v8hi)_mm_setzero_si128(), __builtin_bit_cast(__vecmask8, __U)); } @@ -1738,7 +1738,7 @@ _mm_mask_unpacklo_epi16(__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) { static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_maskz_unpacklo_epi16(__mmask8 __U, __m128i __A, __m128i __B) { return (__m128i)__builtin_selectvector((__v8hi)_mm_unpacklo_epi16(__A, __B), - (__v8hi) _mm_setzero_si128(), + (__v8hi)_mm_setzero_si128(), __builtin_bit_cast(__vecmask8, __U)); } @@ -2800,7 +2800,7 @@ _mm256_mask_permutexvar_epi16 (__m256i __W, __mmask16 __M, __m256i __A, static __inline__ short __DEFAULT_FN_ATTRS128 _mm_reduce_add_epi16(__m128i __W) { return __builtin_reduce_add((__v8hi)__W); - } +} static __inline__ short __DEFAULT_FN_ATTRS128 _mm_reduce_mul_epi16(__m128i __W) { diff --git a/clang/lib/Headers/avx512vlintrin.h b/clang/lib/Headers/avx512vlintrin.h index 6d15942a85..8534c565e1 100644 --- a/clang/lib/Headers/avx512vlintrin.h +++ b/clang/lib/Headers/avx512vlintrin.h @@ -4201,7 +4201,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) { static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_rolv_epi32(__m128i __A, __m128i __B) { return (__m128i)__builtin_ia32_prolvd128((__v4si)__A, (__v4si)__B); -} + } static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_mask_rolv_epi32 (__m128i __W, __mmask8 __U, __m128i __A, __m128i __B) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index b219d55866..6dfd015ef2 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3039,8 +3039,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, return ExprError(); } -const auto* LHSVecT = LHST->getAs(); -const auto* MaskVecT = MaskT->getAs(); +const auto *LHSVecT = LHST->getAs(); +const auto *MaskVecT = MaskT->getAs(); if (!LHSVecT) { Diag(LHS.get()->getBeginLoc(), diag::err_builtin_invalid_arg_type) `` https://github.com/llvm/llvm-project/pull/91306 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Fix malformed AST for anonymous class access in template. (PR #90842)
martinboehme wrote: > Thank you for this fix. > > You should reference the issue that this fixes in your summary. There isn't currently a github issue for this. Should I create one? > This also need a release note. Added. How does this look? (Is it in the appropriate section?) https://github.com/llvm/llvm-project/pull/90842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Fix malformed AST for anonymous class access in template. (PR #90842)
martinboehme wrote: > > This is the option I've decided to go with here. There's a slight wrinkle > > in that we create a LookupResult that claims we looked up the unnamed field > > for the anonymous class -- even though we would obviously never be able to > > look up an unnamed field. I think this is defensible and still better than > > the other alternatives, but I would welcome feedback on this from others > > who know the code better. > > I actually prefer option#2. This doesn't really do what it should, so I think > we should just make sure we materialize the temporary if necessary in > `RebuildMemberExpr`. Done. WDYT? https://github.com/llvm/llvm-project/pull/90842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Fix malformed AST for anonymous class access in template. (PR #90842)
martinboehme wrote: > Another possibility to consider: when [transforming a member > access](https://github.com/llvm/llvm-project/blob/ff210b94d449de8ebe1f32cf0d7763ba63b27b39/clang/lib/Sema/TreeTransform.h#L11950), > strip off any implicit member accesses from the base expression before > transforming the base. That way, we'll rebuild the implicit member access > from scratch, which might be a little more work, but should get details like > this one right. (We can then probably also remove the logic to deal with an > absent `DeclName` in `RebuildMemberExpr` since that shouldn't happen any > more.) This sounds enticing, but after experimenting with this a bit, I’ve concluded that it’s unfortunately not so simple to get this working (unless there’s something I’m overlooking). Looking at the relevant part of the AST: ```cxx `-MemberExpr 'int' xvalue .i 0xbdcb3c0 `-MemberExpr 'S::(anonymous struct at line:2:3)' xvalue .S::(anonymous struct at line:2:3) 0xbdcb488 `-MaterializeTemporaryExpr 'S' xvalue `-CXXTemporaryObjectExpr 'S' 'void () noexcept' zeroing ``` What I think you’re suggesting is that while processing the base for the outer `MemberExpr` (the one for `.i`), we strip the inner `MemberExpr` (the one for the anonymous field). The idea would be that the `MemberExpr` for the anonymous field should get recreated within `Sema::BuildMemberReferenceExpr()` when it’s called with the field declaration for `i`. This _would_ work if we handed an `IndirectFieldDecl` to `BuildMemberReferenceExpr()`, but the problem is that we have no easy way of getting to the `IndirectFieldDecl`. The `getMemberDecl()` for the outer `MemberExpr` is a plain `FieldDecl`; the `getFoundDecl()` is, too. The `getFoundDecl()` for the _inner_ `MemberExpr` does refer to the `IndirectFieldDecl` we want. So we could try to retain only this `MemberExpr` and strip the others – but then we run into the issue that there may not even _be_ an inner `MemberExpr` if the anonymous union is declared inside a function rather than inside a class ([example](https://godbolt.org/z/s1qqj5rY3)). My feeling is that rather than trying to deal with all of the various cases involved in stripping, then recreating the implicit `MemberExpr`s, we retain them and merely recreate the `MaterializeTemporaryExpr` if needed. https://github.com/llvm/llvm-project/pull/90842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Fix malformed AST for anonymous class access in template. (PR #90842)
martinboehme wrote: > Note there is a `BuildAnonymousStructUnionMemberReference`, I am not sure it > solves your problem. Thanks. The issue with this is that it requires an `IndirectFieldDecl` to call it, and that's hard to get at -- see also my response to @zygoloid. https://github.com/llvm/llvm-project/pull/90842 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 1fd196c - [AArch64] Diagnose more functions when FP not enabled (#90832)
Author: ostannard Date: 2024-05-07T09:17:05+01:00 New Revision: 1fd196c8df8e9fa4e0ec92b012824d8d1b0b URL: https://github.com/llvm/llvm-project/commit/1fd196c8df8e9fa4e0ec92b012824d8d1b0b DIFF: https://github.com/llvm/llvm-project/commit/1fd196c8df8e9fa4e0ec92b012824d8d1b0b.diff LOG: [AArch64] Diagnose more functions when FP not enabled (#90832) When using a hard-float ABI for a target without FP registers, it's not possible to correctly generate code for functions with arguments which must be passed in floating-point registers. This is diagnosed in CodeGen instead of Sema, to more closely match GCC's behaviour around inline functions, which is relied on by the Linux kernel. Previously, this only checked function signatures as they were code-generated, but this missed some cases: * Calls to functions not defined in this translation unit. * Calls through function pointers. * Calls to variadic functions, where the variadic arguments have a floating-point type. This adds checks to function calls, as well as definitions, so that these cases are correctly diagnosed. Added: Modified: clang/lib/CodeGen/CGCall.cpp clang/lib/CodeGen/TargetInfo.h clang/lib/CodeGen/Targets/AArch64.cpp clang/lib/CodeGen/Targets/X86.cpp clang/test/CodeGen/aarch64-soft-float-abi-errors.c Removed: diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 69548902dc43b..0c7eef59db53c 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5050,13 +5050,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, (TargetDecl->hasAttr() || (CurFuncDecl && CurFuncDecl->hasAttr( checkTargetFeatures(Loc, FD); - -// Some architectures (such as x86-64) have the ABI changed based on -// attribute-target/features. Give them a chance to diagnose. -CGM.getTargetCodeGenInfo().checkFunctionCallABI( -CGM, Loc, dyn_cast_or_null(CurCodeDecl), FD, CallArgs); } + // Some architectures (such as x86-64) have the ABI changed based on + // attribute-target/features. Give them a chance to diagnose. + CGM.getTargetCodeGenInfo().checkFunctionCallABI( + CGM, Loc, dyn_cast_or_null(CurCodeDecl), + dyn_cast_or_null(TargetDecl), CallArgs, RetTy); + // 1. Set up the arguments. // If we're using inalloca, insert the allocation after the stack save. diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index b1dfe5bf8f274..f242d9e36ed40 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -94,7 +94,8 @@ class TargetCodeGenInfo { virtual void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, const FunctionDecl *Callee, -const CallArgList &Args) const {} +const CallArgList &Args, +QualType ReturnType) const {} /// Determines the size of struct _Unwind_Exception on this platform, /// in 8-bit units. The Itanium ABI defines this as: diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 4c32f510101f0..452dc049d51b4 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -170,8 +170,22 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, -const FunctionDecl *Callee, -const CallArgList &Args) const override; +const FunctionDecl *Callee, const CallArgList &Args, +QualType ReturnType) const override; + +private: + // Diagnose calls between functions with incompatible Streaming SVE + // attributes. + void checkFunctionCallABIStreaming(CodeGenModule &CGM, SourceLocation CallLoc, + const FunctionDecl *Caller, + const FunctionDecl *Callee) const; + // Diagnose calls which must pass arguments in floating-point registers when + // the selected target does not have floating-point registers. + void checkFunctionCallABISoftFloat(CodeGenModule &CGM, SourceLocation CallLoc, + const FunctionDecl *Caller, + const FunctionDecl *Callee, + const CallArgList &Args, + QualType ReturnType) const; }; class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { @@ -853,37 +867,42 @@ static bool isStreamingCompatible(const FunctionDecl *F) { return false; } +// Report
[clang] [AArch64] Diagnose more functions when FP not enabled (PR #90832)
https://github.com/ostannard closed https://github.com/llvm/llvm-project/pull/90832 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AArch64] Add support for Qualcomm Oryon processor (PR #91022)
https://github.com/jthackray approved this pull request. LGTM. (You've still got a few FIXMEs in AArch64SchedOryon.td, I assume you know about these) https://github.com/llvm/llvm-project/pull/91022 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AArch64] Add support for Qualcomm Oryon processor (PR #91022)
@@ -85,6 +85,10 @@ def SMEUnsupported : AArch64Unsupported { SME2Unsupported.F); } +def MTEUnsupported : AArch64Unsupported { + let F = [HasMTE]; +} + jthackray wrote: Oh yes. Thanks. https://github.com/llvm/llvm-project/pull/91022 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AArch64] Add support for Qualcomm Oryon processor (PR #91022)
https://github.com/jthackray edited https://github.com/llvm/llvm-project/pull/91022 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] [llvm] [AArch64][TargetParser] autogen ArchExtKind enum - renaming (PR #90320)
tmatheson-arm wrote: Thanks for the comments everyone. Given that this requires an IR break and additions to the importer, and there is still some question about which way to go with the renaming (i.e. FEAT_ names or user-facing names) I think it makes sense to defer renaming until later. For now, I will add mechanisms to handle the various inconsistencies as in https://github.com/llvm/llvm-project/pull/90987. https://github.com/llvm/llvm-project/pull/90320 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [lldb] [llvm] [AArch64][TargetParser] autogen ArchExtKind enum - renaming (PR #90320)
https://github.com/tmatheson-arm closed https://github.com/llvm/llvm-project/pull/90320 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
https://github.com/Keenuts updated https://github.com/llvm/llvm-project/pull/88918 From 94d76dcdfac88d1d50fe705406c0280c33766e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nathan=20Gau=C3=ABr?= Date: Mon, 15 Apr 2024 17:05:40 +0200 Subject: [PATCH 1/4] [clang][SPIR-V] Always add convervence intrinsics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #80680 added bits in the codegen to lazily add convergence intrinsics when required. This logic relied on the LoopStack. The issue is when parsing the condition, the loopstack doesn't yet reflect the correct values, as expected since we are not yet in the loop. However, convergence tokens should sometimes already be available. The solution which seemed the simplest is to greedily generate the tokens when we generate SPIR-V. Fixes #88144 Signed-off-by: Nathan Gauër --- clang/lib/CodeGen/CGBuiltin.cpp | 88 + clang/lib/CodeGen/CGCall.cpp | 3 + clang/lib/CodeGen/CGStmt.cpp | 94 ++ clang/lib/CodeGen/CodeGenFunction.cpp | 9 ++ clang/lib/CodeGen/CodeGenFunction.h | 9 +- .../builtins/RWBuffer-constructor.hlsl| 1 - .../CodeGenHLSL/convergence/do.while.hlsl | 90 + clang/test/CodeGenHLSL/convergence/for.hlsl | 121 ++ clang/test/CodeGenHLSL/convergence/while.hlsl | 119 + 9 files changed, 445 insertions(+), 89 deletions(-) create mode 100644 clang/test/CodeGenHLSL/convergence/do.while.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/for.hlsl create mode 100644 clang/test/CodeGenHLSL/convergence/while.hlsl diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index df7502b8def5314..f5d40a1555fcb57 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -1133,91 +1133,8 @@ struct BitTest { static BitTest decodeBitTestBuiltin(unsigned BuiltinID); }; -// Returns the first convergence entry/loop/anchor instruction found in |BB|. -// std::nullptr otherwise. -llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { - for (auto &I : *BB) { -auto *II = dyn_cast(&I); -if (II && isConvergenceControlIntrinsic(II->getIntrinsicID())) - return II; - } - return nullptr; -} - } // namespace -llvm::CallBase * -CodeGenFunction::addConvergenceControlToken(llvm::CallBase *Input, -llvm::Value *ParentToken) { - llvm::Value *bundleArgs[] = {ParentToken}; - llvm::OperandBundleDef OB("convergencectrl", bundleArgs); - auto Output = llvm::CallBase::addOperandBundle( - Input, llvm::LLVMContext::OB_convergencectrl, OB, Input); - Input->replaceAllUsesWith(Output); - Input->eraseFromParent(); - return Output; -} - -llvm::IntrinsicInst * -CodeGenFunction::emitConvergenceLoopToken(llvm::BasicBlock *BB, - llvm::Value *ParentToken) { - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(&BB->front()); - auto CB = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_loop, {}, {}); - Builder.restoreIP(IP); - - auto I = addConvergenceControlToken(CB, ParentToken); - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { - auto *BB = &F->getEntryBlock(); - auto *token = getConvergenceToken(BB); - if (token) -return token; - - // Adding a convergence token requires the function to be marked as - // convergent. - F->setConvergent(); - - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(&BB->front()); - auto I = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_entry, {}, {}); - assert(isa(I)); - Builder.restoreIP(IP); - - return cast(I); -} - -llvm::IntrinsicInst * -CodeGenFunction::getOrEmitConvergenceLoopToken(const LoopInfo *LI) { - assert(LI != nullptr); - - auto *token = getConvergenceToken(LI->getHeader()); - if (token) -return token; - - llvm::IntrinsicInst *PII = - LI->getParent() - ? emitConvergenceLoopToken( -LI->getHeader(), getOrEmitConvergenceLoopToken(LI->getParent())) - : getOrEmitConvergenceEntryToken(LI->getHeader()->getParent()); - - return emitConvergenceLoopToken(LI->getHeader(), PII); -} - -llvm::CallBase * -CodeGenFunction::addControlledConvergenceToken(llvm::CallBase *Input) { - llvm::Value *ParentToken = - LoopStack.hasInfo() - ? getOrEmitConvergenceLoopToken(&LoopStack.getInfo()) - : getOrEmitConvergenceEntryToken(Input->getFunction()); - return addConvergenceControlToken(Input, ParentToken); -} - BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) { switch (BuiltinID) { // Main portable variants. @@ -18306,12 +18223,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, ArrayRef{Op0}, nullptr, "dx.rsqr
[clang] [flang] [Flang] RFC: Add support for -w option 1/n (PR #90420)
https://github.com/banach-space edited https://github.com/llvm/llvm-project/pull/90420 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [Flang] RFC: Add support for -w option 1/n (PR #90420)
https://github.com/banach-space approved this pull request. LGTM, thanks! https://github.com/llvm/llvm-project/pull/90420 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [Flang] RFC: Add support for -w option 1/n (PR #90420)
banach-space wrote: [nit] Once you have more than one prefix, `CHECK` becomes noise. At least IMHO 😅 (we all know that these are "check" lines). You could use more descriptive prefixes instead, e.g. `CHECK-PORT` -> `PORTABILITY` (it wasn't obvious to me that `PORT` stood for "portability"), `CHECK` -> `DEFAULT`. https://github.com/llvm/llvm-project/pull/90420 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPIR-V] Always add convervence intrinsics (PR #88918)
@@ -3101,3 +3130,68 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) { return F; } + +namespace { +// Returns the first convergence entry/loop/anchor instruction found in |BB|. +// std::nullptr otherwise. +llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) { + for (auto &I : *BB) { +auto *II = dyn_cast(&I); +if (II && llvm::isConvergenceControlIntrinsic(II->getIntrinsicID())) + return II; + } + return nullptr; +} + +} // namespace + +llvm::CallBase * +CodeGenFunction::addConvergenceControlToken(llvm::CallBase *Input, +llvm::Value *ParentToken) { + llvm::Value *bundleArgs[] = {ParentToken}; + llvm::OperandBundleDef OB("convergencectrl", bundleArgs); + auto Output = llvm::CallBase::addOperandBundle( + Input, llvm::LLVMContext::OB_convergencectrl, OB, Input); + Input->replaceAllUsesWith(Output); + Input->eraseFromParent(); + return Output; +} + +llvm::IntrinsicInst * +CodeGenFunction::emitConvergenceLoopToken(llvm::BasicBlock *BB, + llvm::Value *ParentToken) { + CGBuilderTy::InsertPoint IP = Builder.saveIP(); + + if (BB->empty()) +Builder.SetInsertPoint(BB); + else +Builder.SetInsertPoint(&BB->front()); + + auto CB = Builder.CreateIntrinsic( + llvm::Intrinsic::experimental_convergence_loop, {}, {}); + Builder.restoreIP(IP); + + auto I = addConvergenceControlToken(CB, ParentToken); Keenuts wrote: Right, replaced the auto usage https://github.com/llvm/llvm-project/pull/88918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [openmp] [OpenMP] Depobj optimisation (PR #91145)
https://github.com/rpereira-dev edited https://github.com/llvm/llvm-project/pull/91145 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [openmp] [OpenMP] Depobj optimisation (PR #91145)
https://github.com/rpereira-dev edited https://github.com/llvm/llvm-project/pull/91145 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/90894 >From 40365147f7aabeaaefd7e9bf6f2b96d6f7135992 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 3 May 2024 10:53:54 +0200 Subject: [PATCH 1/3] Refactor: Extract the core deduction-guide construction implementation from DeclareImplicitDeductionGuidesForTypeAlias We move the core implementation to a dedicate function, so that it can be reused in other places. --- clang/lib/Sema/SemaTemplate.cpp | 390 +--- 1 file changed, 203 insertions(+), 187 deletions(-) diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 989f3995ca59913..b43c65874b04e5b 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) { return {Template, AliasRhsTemplateArgs}; } -// Build deduction guides for a type alias template. +// Build deduction guides for a type alias template from the given underlying +// deduction guide F. +FunctionTemplateDecl * +BuildDeductionGuideForTypeAlias(Sema &SemaRef, +TypeAliasTemplateDecl *AliasTemplate, +FunctionTemplateDecl *F, SourceLocation Loc) { + LocalInstantiationScope Scope(SemaRef); + Sema::InstantiatingTemplate BuildingDeductionGuides( + SemaRef, AliasTemplate->getLocation(), F, + Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{}); + if (BuildingDeductionGuides.isInvalid()) +return nullptr; + + auto &Context = SemaRef.Context; + auto [Template, AliasRhsTemplateArgs] = + getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate); + + auto RType = F->getTemplatedDecl()->getReturnType(); + // The (trailing) return type of the deduction guide. + const TemplateSpecializationType *FReturnType = + RType->getAs(); + if (const auto *InjectedCNT = RType->getAs()) +// implicitly-generated deduction guide. +FReturnType = InjectedCNT->getInjectedTST(); + else if (const auto *ET = RType->getAs()) +// explicit deduction guide. +FReturnType = ET->getNamedType()->getAs(); + assert(FReturnType && "expected to see a return type"); + // Deduce template arguments of the deduction guide f from the RHS of + // the alias. + // + // C++ [over.match.class.deduct]p3: ...For each function or function + // template f in the guides of the template named by the + // simple-template-id of the defining-type-id, the template arguments + // of the return type of f are deduced from the defining-type-id of A + // according to the process in [temp.deduct.type] with the exception + // that deduction does not fail if not all template arguments are + // deduced. + // + // + // template + // f(X, Y) -> f; + // + // template + // using alias = f; + // + // The RHS of alias is f, we deduced the template arguments of + // the return type of the deduction guide from it: Y->int, X->U + sema::TemplateDeductionInfo TDeduceInfo(Loc); + // Must initialize n elements, this is required by DeduceTemplateArguments. + SmallVector DeduceResults( + F->getTemplateParameters()->size()); + + // FIXME: DeduceTemplateArguments stops immediately at the first + // non-deducible template argument. However, this doesn't seem to casue + // issues for practice cases, we probably need to extend it to continue + // performing deduction for rest of arguments to align with the C++ + // standard. + SemaRef.DeduceTemplateArguments( + F->getTemplateParameters(), FReturnType->template_arguments(), + AliasRhsTemplateArgs, TDeduceInfo, DeduceResults, + /*NumberOfArgumentsMustMatch=*/false); + + SmallVector DeducedArgs; + SmallVector NonDeducedTemplateParamsInFIndex; + // !!NOTE: DeduceResults respects the sequence of template parameters of + // the deduction guide f. + for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) { +if (const auto &D = DeduceResults[Index]; !D.isNull()) // Deduced + DeducedArgs.push_back(D); +else + NonDeducedTemplateParamsInFIndex.push_back(Index); + } + auto DeducedAliasTemplateParams = + TemplateParamsReferencedInTemplateArgumentList( + AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs); + // All template arguments null by default. + SmallVector TemplateArgsForBuildingFPrime( + F->getTemplateParameters()->size()); + + // Create a template parameter list for the synthesized deduction guide f'. + // + // C++ [over.match.class.deduct]p3.2: + // If f is a function template, f' is a function template whose template + // parameter list consists of all the template parameters of A + // (including their default template arguments) that appear in the above + // deductions or (recursively) in their default template arguments + SmallVector FPrimeTemplateParams; + // Store template arguments that refer to the newly-created tem
[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)
@@ -261,6 +261,13 @@ AG ag = {1}; // CHECK: | `-BuiltinType {{.*}} 'int' // CHECK: `-ParmVarDecl {{.*}} 'int' +template +using BG = G; +BG bg(1.0); +// CHECK-LABEL: Dumping +// CHECK: FunctionTemplateDecl {{.*}} implicit +// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G' aggregate hokein wrote: While the test is not matching the AST structure, I think it is better and clearer to keep it, as it explicitly demonstrates the child relationship with the above line (`FunctionTemplateDecl`). https://github.com/llvm/llvm-project/pull/90894 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)
@@ -2803,7 +2803,207 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) { return {Template, AliasRhsTemplateArgs}; } -// Build deduction guides for a type alias template. +// Build deduction guides for a type alias template from the given underlying +// deduction guide F. +FunctionTemplateDecl * +BuildDeductionGuideForTypeAlias(Sema &SemaRef, +TypeAliasTemplateDecl *AliasTemplate, +FunctionTemplateDecl *F, SourceLocation Loc) { + LocalInstantiationScope Scope(SemaRef); + Sema::InstantiatingTemplate BuildingDeductionGuides( + SemaRef, AliasTemplate->getLocation(), F, + Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{}); + if (BuildingDeductionGuides.isInvalid()) +return nullptr; + + auto &Context = SemaRef.Context; + auto [Template, AliasRhsTemplateArgs] = + getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate); + + auto RType = F->getTemplatedDecl()->getReturnType(); + // The (trailing) return type of the deduction guide. + const TemplateSpecializationType *FReturnType = + RType->getAs(); + if (const auto *InjectedCNT = RType->getAs()) +// implicitly-generated deduction guide. +FReturnType = InjectedCNT->getInjectedTST(); + else if (const auto *ET = RType->getAs()) +// explicit deduction guide. +FReturnType = ET->getNamedType()->getAs(); + assert(FReturnType && "expected to see a return type"); + // Deduce template arguments of the deduction guide f from the RHS of + // the alias. + // + // C++ [over.match.class.deduct]p3: ...For each function or function + // template f in the guides of the template named by the + // simple-template-id of the defining-type-id, the template arguments + // of the return type of f are deduced from the defining-type-id of A + // according to the process in [temp.deduct.type] with the exception + // that deduction does not fail if not all template arguments are + // deduced. + // + // + // template + // f(X, Y) -> f; + // + // template + // using alias = f; + // + // The RHS of alias is f, we deduced the template arguments of + // the return type of the deduction guide from it: Y->int, X->U + sema::TemplateDeductionInfo TDeduceInfo(Loc); + // Must initialize n elements, this is required by DeduceTemplateArguments. + SmallVector DeduceResults( + F->getTemplateParameters()->size()); + + // FIXME: DeduceTemplateArguments stops immediately at the first + // non-deducible template argument. However, this doesn't seem to casue + // issues for practice cases, we probably need to extend it to continue + // performing deduction for rest of arguments to align with the C++ + // standard. + SemaRef.DeduceTemplateArguments( + F->getTemplateParameters(), FReturnType->template_arguments(), + AliasRhsTemplateArgs, TDeduceInfo, DeduceResults, + /*NumberOfArgumentsMustMatch=*/false); + + SmallVector DeducedArgs; + SmallVector NonDeducedTemplateParamsInFIndex; + // !!NOTE: DeduceResults respects the sequence of template parameters of + // the deduction guide f. + for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) { +if (const auto &D = DeduceResults[Index]; !D.isNull()) // Deduced + DeducedArgs.push_back(D); +else + NonDeducedTemplateParamsInFIndex.push_back(Index); + } + auto DeducedAliasTemplateParams = + TemplateParamsReferencedInTemplateArgumentList( + AliasTemplate->getTemplateParameters()->asArray(), DeducedArgs); + // All template arguments null by default. + SmallVector TemplateArgsForBuildingFPrime( + F->getTemplateParameters()->size()); + + // Create a template parameter list for the synthesized deduction guide f'. + // + // C++ [over.match.class.deduct]p3.2: + // If f is a function template, f' is a function template whose template + // parameter list consists of all the template parameters of A + // (including their default template arguments) that appear in the above + // deductions or (recursively) in their default template arguments + SmallVector FPrimeTemplateParams; + // Store template arguments that refer to the newly-created template + // parameters, used for building `TemplateArgsForBuildingFPrime`. + SmallVector TransformedDeducedAliasArgs( + AliasTemplate->getTemplateParameters()->size()); + + for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) { +auto *TP = + AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx); +// Rebuild any internal references to earlier parameters and reindex as +// we go. +MultiLevelTemplateArgumentList Args; +Args.setKind(TemplateSubstitutionKind::Rewrite); +Args.addOuterTemplateArguments(TransformedDeducedAliasArgs); +NamedDecl *NewParam = transformTemplateParameter( +SemaRef, AliasTemplate->getDeclContext(), TP, Args, +/*NewIndex=*/FPrimeTemplateParams.size(
[clang] [clang][test] Fix instantiation-depth-default.cpp under ubsan config on Windows (PR #91021)
https://github.com/goussepi approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/91021 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)
@@ -261,6 +261,13 @@ AG ag = {1}; // CHECK: | `-BuiltinType {{.*}} 'int' // CHECK: `-ParmVarDecl {{.*}} 'int' +template +using BG = G; +BG bg(1.0); +// CHECK-LABEL: Dumping +// CHECK: FunctionTemplateDecl {{.*}} implicit +// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G' aggregate mizvekov wrote: The line is a CHECK, not a CHECK-NEXT, so it could appear any number of lines afterwards. So this means it could be a child of something else that appears after it. The CHECK matcher matches any number of characters before the first character specified, So it would match something like `| | |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G' aggregate` Ie, it could be deeply nested into something else. Instead, I think it just demonstrates: * It is a child of something. * It's neither the first nor the last child of that thing. https://github.com/llvm/llvm-project/pull/90894 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Allow raw string literals in C as an extension (PR #88265)
@@ -3850,6 +3850,7 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) { // the sequence "<::" will be unconditionally treated as "[:". // Cf. Lexer::LexTokenInternal. LangOpts.Digraphs = LexingStd >= FormatStyle::LS_Cpp11; + LangOpts.RawStringLiterals = LexingStd >= FormatStyle::LS_Cpp11; Sirraide wrote: That sounds like it might work because it’s overridden by the standard anyway; I’ll try that. https://github.com/llvm/llvm-project/pull/88265 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)
https://github.com/mejedi created https://github.com/llvm/llvm-project/pull/91310 When BPF object files are linked with bpftool, every symbol must be accompanied by BTF info. Ensure that extern functions referenced by global variable initializers are included in BTF. The primary motivation is "static" initialization of PROG maps: extern int elsewhere(struct xdp_md *); struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 1); __type(key, int); __type(value, int); __array(values, int (struct xdp_md *)); } prog_map SEC(".maps") = { .values = { elsewhere } }; >From 6fb034ef2bf370358b1acd1cee30cf2154ef46c3 Mon Sep 17 00:00:00 2001 From: Nick Zavaritsky Date: Sun, 5 May 2024 10:20:52 + Subject: [PATCH] [BPF] Fix linking issues in static map initializers When BPF object files are linked with bpftool, every symbol must be accompanied by BTF info. Ensure that extern functions referenced by global variable initializers are included in BTF. The primary motivation is "static" initialization of PROG maps: extern int elsewhere(struct xdp_md *); struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 1); __type(key, int); __type(value, int); __array(values, int (struct xdp_md *)); } prog_map SEC(".maps") = { .values = { elsewhere } }; --- clang/lib/CodeGen/CGExprConstant.cpp | 18 ++- clang/test/bpf-debug-info-extern-func.c | 9 llvm/lib/Target/BPF/BTFDebug.cpp | 23 llvm/lib/Target/BPF/BTFDebug.h| 4 ++ llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll | 54 +++ 5 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 clang/test/bpf-debug-info-extern-func.c create mode 100644 llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 94962091116af..945f2e222b23f 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1950,8 +1950,22 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) { if (D->hasAttr()) return CGM.GetWeakRefReference(D).getPointer(); -if (auto FD = dyn_cast(D)) - return CGM.GetAddrOfFunction(FD); +if (auto FD = dyn_cast(D)) { + auto *C = CGM.GetAddrOfFunction(FD); + + // we don't normally emit debug info for extern fns referenced via + // variable initialisers; BPF needs it since it generates BTF from + // debug info and bpftool demands BTF for every symbol linked + if (CGM.getTarget().getTriple().isBPF() && FD->getStorageClass() == SC_Extern) { +if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) { + auto *Fn = dyn_cast(C); + if (Fn && !Fn->getSubprogram()) +DI->EmitFunctionDecl(FD, FD->getLocation(), D->getType(), Fn); +} + } + + return C; +} if (auto VD = dyn_cast(D)) { // We can never refer to a variable with local storage. diff --git a/clang/test/bpf-debug-info-extern-func.c b/clang/test/bpf-debug-info-extern-func.c new file mode 100644 index 0..da324630a314d --- /dev/null +++ b/clang/test/bpf-debug-info-extern-func.c @@ -0,0 +1,9 @@ +// RUN: %clang -g -O2 -target bpf -S -emit-llvm %s -o - | FileCheck %s +// +// When linking BPF object files via bpftool, BTF info is required for +// every symbol. BTF is generated from debug info. Ensure that debug info +// is emitted for extern functions referenced via variable initializers. +// +// CHECK: !DISubprogram(name: "fn" +extern void fn(void); +void (*pfn) (void) = &fn; diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp index b6d3b460005c9..7d64f2e04bc26 100644 --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -1494,6 +1494,29 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) { DataSecEntries[std::string(SecName)]->addDataSecEntry(VarId, Asm->getSymbol(&Global), Size); + +if (Global.hasInitializer()) + processGlobalInitializer(Global.getInitializer()); + } +} + +/// Process global variable initializer in pursuit for function +/// pointers. Add discovered (extern) functions to BTF. Some (extern) +/// functions might have been missed otherwise. Every symbol needs BTF +/// info when linking with bpftool. Primary use case: "static" +/// initialization of BPF maps. +/// +/// struct { +/// __uint(type, BPF_MAP_TYPE_PROG_ARRAY); +/// ... +/// } prog_map SEC(".maps") = { .values = { extern_func } }; +/// +void BTFDebug::processGlobalInitializer(const Constant *C) { + if (auto *Fn = dyn_cast(C)) +processFuncPrototypes(Fn); + if (auto *CA = dyn_cast(C)) { +for (unsigned I = 0, N = CA->getNumOperands(); I < N; ++I) + processGlobalInitializer(CA->getOperand(I)); } } diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h index 11a0c59ba6c90..02181d3013be9 100644 --- a/ll
[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/91310 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)
llvmbot wrote: @llvm/pr-subscribers-clang-codegen Author: Nick Zavaritsky (mejedi) Changes When BPF object files are linked with bpftool, every symbol must be accompanied by BTF info. Ensure that extern functions referenced by global variable initializers are included in BTF. The primary motivation is "static" initialization of PROG maps: extern int elsewhere(struct xdp_md *); struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 1); __type(key, int); __type(value, int); __array(values, int (struct xdp_md *)); } prog_map SEC(".maps") = { .values = { elsewhere } }; --- Full diff: https://github.com/llvm/llvm-project/pull/91310.diff 5 Files Affected: - (modified) clang/lib/CodeGen/CGExprConstant.cpp (+16-2) - (added) clang/test/bpf-debug-info-extern-func.c (+9) - (modified) llvm/lib/Target/BPF/BTFDebug.cpp (+23) - (modified) llvm/lib/Target/BPF/BTFDebug.h (+4) - (added) llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll (+54) ``diff diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 94962091116af..945f2e222b23f 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1950,8 +1950,22 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) { if (D->hasAttr()) return CGM.GetWeakRefReference(D).getPointer(); -if (auto FD = dyn_cast(D)) - return CGM.GetAddrOfFunction(FD); +if (auto FD = dyn_cast(D)) { + auto *C = CGM.GetAddrOfFunction(FD); + + // we don't normally emit debug info for extern fns referenced via + // variable initialisers; BPF needs it since it generates BTF from + // debug info and bpftool demands BTF for every symbol linked + if (CGM.getTarget().getTriple().isBPF() && FD->getStorageClass() == SC_Extern) { +if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) { + auto *Fn = dyn_cast(C); + if (Fn && !Fn->getSubprogram()) +DI->EmitFunctionDecl(FD, FD->getLocation(), D->getType(), Fn); +} + } + + return C; +} if (auto VD = dyn_cast(D)) { // We can never refer to a variable with local storage. diff --git a/clang/test/bpf-debug-info-extern-func.c b/clang/test/bpf-debug-info-extern-func.c new file mode 100644 index 0..da324630a314d --- /dev/null +++ b/clang/test/bpf-debug-info-extern-func.c @@ -0,0 +1,9 @@ +// RUN: %clang -g -O2 -target bpf -S -emit-llvm %s -o - | FileCheck %s +// +// When linking BPF object files via bpftool, BTF info is required for +// every symbol. BTF is generated from debug info. Ensure that debug info +// is emitted for extern functions referenced via variable initializers. +// +// CHECK: !DISubprogram(name: "fn" +extern void fn(void); +void (*pfn) (void) = &fn; diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp index b6d3b460005c9..7d64f2e04bc26 100644 --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -1494,6 +1494,29 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) { DataSecEntries[std::string(SecName)]->addDataSecEntry(VarId, Asm->getSymbol(&Global), Size); + +if (Global.hasInitializer()) + processGlobalInitializer(Global.getInitializer()); + } +} + +/// Process global variable initializer in pursuit for function +/// pointers. Add discovered (extern) functions to BTF. Some (extern) +/// functions might have been missed otherwise. Every symbol needs BTF +/// info when linking with bpftool. Primary use case: "static" +/// initialization of BPF maps. +/// +/// struct { +/// __uint(type, BPF_MAP_TYPE_PROG_ARRAY); +/// ... +/// } prog_map SEC(".maps") = { .values = { extern_func } }; +/// +void BTFDebug::processGlobalInitializer(const Constant *C) { + if (auto *Fn = dyn_cast(C)) +processFuncPrototypes(Fn); + if (auto *CA = dyn_cast(C)) { +for (unsigned I = 0, N = CA->getNumOperands(); I < N; ++I) + processGlobalInitializer(CA->getOperand(I)); } } diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h index 11a0c59ba6c90..02181d3013be9 100644 --- a/llvm/lib/Target/BPF/BTFDebug.h +++ b/llvm/lib/Target/BPF/BTFDebug.h @@ -352,6 +352,10 @@ class BTFDebug : public DebugHandlerBase { /// Generate types and variables for globals. void processGlobals(bool ProcessingMapDef); + /// Process global variable initializer in pursuit for function + /// pointers. + void processGlobalInitializer(const Constant *C); + /// Generate types for function prototypes. void processFuncPrototypes(const Function *); diff --git a/llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll b/llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll new file mode 100644 index 0..700486d9f3515 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll @@ -0,0 +1,54 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -m
[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Nick Zavaritsky (mejedi) Changes When BPF object files are linked with bpftool, every symbol must be accompanied by BTF info. Ensure that extern functions referenced by global variable initializers are included in BTF. The primary motivation is "static" initialization of PROG maps: extern int elsewhere(struct xdp_md *); struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 1); __type(key, int); __type(value, int); __array(values, int (struct xdp_md *)); } prog_map SEC(".maps") = { .values = { elsewhere } }; --- Full diff: https://github.com/llvm/llvm-project/pull/91310.diff 5 Files Affected: - (modified) clang/lib/CodeGen/CGExprConstant.cpp (+16-2) - (added) clang/test/bpf-debug-info-extern-func.c (+9) - (modified) llvm/lib/Target/BPF/BTFDebug.cpp (+23) - (modified) llvm/lib/Target/BPF/BTFDebug.h (+4) - (added) llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll (+54) ``diff diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 94962091116a..945f2e222b23 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1950,8 +1950,22 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) { if (D->hasAttr()) return CGM.GetWeakRefReference(D).getPointer(); -if (auto FD = dyn_cast(D)) - return CGM.GetAddrOfFunction(FD); +if (auto FD = dyn_cast(D)) { + auto *C = CGM.GetAddrOfFunction(FD); + + // we don't normally emit debug info for extern fns referenced via + // variable initialisers; BPF needs it since it generates BTF from + // debug info and bpftool demands BTF for every symbol linked + if (CGM.getTarget().getTriple().isBPF() && FD->getStorageClass() == SC_Extern) { +if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) { + auto *Fn = dyn_cast(C); + if (Fn && !Fn->getSubprogram()) +DI->EmitFunctionDecl(FD, FD->getLocation(), D->getType(), Fn); +} + } + + return C; +} if (auto VD = dyn_cast(D)) { // We can never refer to a variable with local storage. diff --git a/clang/test/bpf-debug-info-extern-func.c b/clang/test/bpf-debug-info-extern-func.c new file mode 100644 index ..da324630a314 --- /dev/null +++ b/clang/test/bpf-debug-info-extern-func.c @@ -0,0 +1,9 @@ +// RUN: %clang -g -O2 -target bpf -S -emit-llvm %s -o - | FileCheck %s +// +// When linking BPF object files via bpftool, BTF info is required for +// every symbol. BTF is generated from debug info. Ensure that debug info +// is emitted for extern functions referenced via variable initializers. +// +// CHECK: !DISubprogram(name: "fn" +extern void fn(void); +void (*pfn) (void) = &fn; diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp index b6d3b460005c..7d64f2e04bc2 100644 --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -1494,6 +1494,29 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) { DataSecEntries[std::string(SecName)]->addDataSecEntry(VarId, Asm->getSymbol(&Global), Size); + +if (Global.hasInitializer()) + processGlobalInitializer(Global.getInitializer()); + } +} + +/// Process global variable initializer in pursuit for function +/// pointers. Add discovered (extern) functions to BTF. Some (extern) +/// functions might have been missed otherwise. Every symbol needs BTF +/// info when linking with bpftool. Primary use case: "static" +/// initialization of BPF maps. +/// +/// struct { +/// __uint(type, BPF_MAP_TYPE_PROG_ARRAY); +/// ... +/// } prog_map SEC(".maps") = { .values = { extern_func } }; +/// +void BTFDebug::processGlobalInitializer(const Constant *C) { + if (auto *Fn = dyn_cast(C)) +processFuncPrototypes(Fn); + if (auto *CA = dyn_cast(C)) { +for (unsigned I = 0, N = CA->getNumOperands(); I < N; ++I) + processGlobalInitializer(CA->getOperand(I)); } } diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h index 11a0c59ba6c9..02181d3013be 100644 --- a/llvm/lib/Target/BPF/BTFDebug.h +++ b/llvm/lib/Target/BPF/BTFDebug.h @@ -352,6 +352,10 @@ class BTFDebug : public DebugHandlerBase { /// Generate types and variables for globals. void processGlobals(bool ProcessingMapDef); + /// Process global variable initializer in pursuit for function + /// pointers. + void processGlobalInitializer(const Constant *C); + /// Generate types for function prototypes. void processFuncPrototypes(const Function *); diff --git a/llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll b/llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll new file mode 100644 index ..700486d9f351 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll @@ -0,0 +1,54 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filety
[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)
https://github.com/mejedi updated https://github.com/llvm/llvm-project/pull/91310 >From e518bdfb86b06fa8bc447934293623a803a7f630 Mon Sep 17 00:00:00 2001 From: Nick Zavaritsky Date: Sun, 5 May 2024 10:20:52 + Subject: [PATCH] [BPF] Fix linking issues in static map initializers When BPF object files are linked with bpftool, every symbol must be accompanied by BTF info. Ensure that extern functions referenced by global variable initializers are included in BTF. The primary motivation is "static" initialization of PROG maps: extern int elsewhere(struct xdp_md *); struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 1); __type(key, int); __type(value, int); __array(values, int (struct xdp_md *)); } prog_map SEC(".maps") = { .values = { elsewhere } }; Signed-off-by: Nick Zavaritsky --- clang/lib/CodeGen/CGExprConstant.cpp | 18 ++- clang/test/bpf-debug-info-extern-func.c | 9 llvm/lib/Target/BPF/BTFDebug.cpp | 23 llvm/lib/Target/BPF/BTFDebug.h| 4 ++ llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll | 54 +++ 5 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 clang/test/bpf-debug-info-extern-func.c create mode 100644 llvm/test/CodeGen/BPF/BTF/extern-var-func2.ll diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 94962091116a..945f2e222b23 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1950,8 +1950,22 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) { if (D->hasAttr()) return CGM.GetWeakRefReference(D).getPointer(); -if (auto FD = dyn_cast(D)) - return CGM.GetAddrOfFunction(FD); +if (auto FD = dyn_cast(D)) { + auto *C = CGM.GetAddrOfFunction(FD); + + // we don't normally emit debug info for extern fns referenced via + // variable initialisers; BPF needs it since it generates BTF from + // debug info and bpftool demands BTF for every symbol linked + if (CGM.getTarget().getTriple().isBPF() && FD->getStorageClass() == SC_Extern) { +if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) { + auto *Fn = dyn_cast(C); + if (Fn && !Fn->getSubprogram()) +DI->EmitFunctionDecl(FD, FD->getLocation(), D->getType(), Fn); +} + } + + return C; +} if (auto VD = dyn_cast(D)) { // We can never refer to a variable with local storage. diff --git a/clang/test/bpf-debug-info-extern-func.c b/clang/test/bpf-debug-info-extern-func.c new file mode 100644 index ..da324630a314 --- /dev/null +++ b/clang/test/bpf-debug-info-extern-func.c @@ -0,0 +1,9 @@ +// RUN: %clang -g -O2 -target bpf -S -emit-llvm %s -o - | FileCheck %s +// +// When linking BPF object files via bpftool, BTF info is required for +// every symbol. BTF is generated from debug info. Ensure that debug info +// is emitted for extern functions referenced via variable initializers. +// +// CHECK: !DISubprogram(name: "fn" +extern void fn(void); +void (*pfn) (void) = &fn; diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp index b6d3b460005c..7d64f2e04bc2 100644 --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -1494,6 +1494,29 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) { DataSecEntries[std::string(SecName)]->addDataSecEntry(VarId, Asm->getSymbol(&Global), Size); + +if (Global.hasInitializer()) + processGlobalInitializer(Global.getInitializer()); + } +} + +/// Process global variable initializer in pursuit for function +/// pointers. Add discovered (extern) functions to BTF. Some (extern) +/// functions might have been missed otherwise. Every symbol needs BTF +/// info when linking with bpftool. Primary use case: "static" +/// initialization of BPF maps. +/// +/// struct { +/// __uint(type, BPF_MAP_TYPE_PROG_ARRAY); +/// ... +/// } prog_map SEC(".maps") = { .values = { extern_func } }; +/// +void BTFDebug::processGlobalInitializer(const Constant *C) { + if (auto *Fn = dyn_cast(C)) +processFuncPrototypes(Fn); + if (auto *CA = dyn_cast(C)) { +for (unsigned I = 0, N = CA->getNumOperands(); I < N; ++I) + processGlobalInitializer(CA->getOperand(I)); } } diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h index 11a0c59ba6c9..02181d3013be 100644 --- a/llvm/lib/Target/BPF/BTFDebug.h +++ b/llvm/lib/Target/BPF/BTFDebug.h @@ -352,6 +352,10 @@ class BTFDebug : public DebugHandlerBase { /// Generate types and variables for globals. void processGlobals(bool ProcessingMapDef); + /// Process global variable initializer in pursuit for function + /// pointers. + void processGlobalInitializer(const Constant *C); + /// Generate types for function prototypes. void processFuncPrototypes(const Function *); diff --git a/llvm/test/CodeGen/BPF/B
[clang] [llvm] [DebugInfo] Use DW_op_bit_piece for structured bindings of bitfields (PR #85665)
john-brawn-arm wrote: Ping. https://github.com/llvm/llvm-project/pull/85665 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [BPF] Fix linking issues in static map initializers (PR #91310)
mejedi wrote: CC @yonghong-song https://github.com/llvm/llvm-project/pull/91310 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][SPARC] Treat empty structs as if it's a one-bit type in the CC (PR #90338)
@@ -21,6 +21,12 @@ char f_int_4(char x) { return x; } // CHECK-LABEL: define{{.*}} fp128 @f_ld(fp128 noundef %x) long double f_ld(long double x) { return x; } +// Empty struct is lowered as a placeholder word parameter. +struct empty {}; + +// CHECK-LABEL: define{{.*}} i64 @f_empty(i64 %x.coerce) +struct empty f_empty(struct empty x) { return x; } + s-barannikov wrote: My concern is that gcc might have different rules for passing C++ classes with empty base class compared to empty C structs. Can you check that the clang C++ behavior matches gcc and possibly add a test if it is not there yet? https://github.com/llvm/llvm-project/pull/90338 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)
@@ -7963,6 +7967,148 @@ static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) { llvm_unreachable("unexpected attribute kind!"); } +ExprResult Sema::ActOnEffectExpression(Expr *CondExpr, FunctionEffectMode &Mode, + bool RequireConstexpr) { + // see checkFunctionConditionAttr, Sema::CheckCXXBooleanCondition + if (RequireConstexpr || !CondExpr->isTypeDependent()) { +ExprResult E = PerformContextuallyConvertToBool(CondExpr); +if (E.isInvalid()) + return E; +CondExpr = E.get(); +if (RequireConstexpr || !CondExpr->isValueDependent()) { + llvm::APSInt CondInt; + E = VerifyIntegerConstantExpression( Sirraide wrote: > Is there a way at this time to detect that the expression is not only > dependent but an unexpanded pack? Iirc pack dependence is a thing. You should be able to check for that. > If I add void g() { f(); } there is a second attempt to resolve > the expression but it is still dependent, so clearly there is an error here I’ll have to check how we currently handle these cases because I’m not terribly familiar w/ packs myself. https://github.com/llvm/llvm-project/pull/84983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] nonblocking/nonallocating attributes (was: nolock/noalloc) (PR #84983)
@@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -fcxx-exceptions -verify %s +// RUN: %clang_cc1 -fsyntax-only -fblocks -verify -x c -std=c23 %s Sirraide wrote: Prototypeless functions are the only thing I can think of as well candidly. https://github.com/llvm/llvm-project/pull/84983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AArch64] Fix feature flags dependecies (PR #90612)
@@ -3731,7 +3730,7 @@ static const struct Extension { {"sme-lutv2", {AArch64::FeatureSME_LUTv2}}, {"sme-f8f16", {AArch64::FeatureSMEF8F16}}, {"sme-f8f32", {AArch64::FeatureSMEF8F32}}, -{"sme-fa64", {AArch64::FeatureSMEFA64}}, +{"sme-fa64", {AArch64::FeatureSMEFA64}}, CarolineConcatto wrote: Unrelated change https://github.com/llvm/llvm-project/pull/90612 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AArch64] Fix feature flags dependecies (PR #90612)
@@ -291,15 +290,14 @@ inline constexpr ExtensionInfo Extensions[] = { {"tme", AArch64::AEK_TME, "+tme", "-tme", FEAT_INIT, "", 0}, {"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550}, {"gcs", AArch64::AEK_GCS, "+gcs", "-gcs", FEAT_INIT, "", 0}, -{"fpmr", AArch64::AEK_FPMR, "+fpmr", "-fpmr", FEAT_INIT, "", 0}, -{"fp8", AArch64::AEK_FP8, "+fp8", "-fp8", FEAT_INIT, "+fpmr", 0}, +{"fp8", AArch64::AEK_FP8, "+fp8", "-fp8", FEAT_INIT, "+faminmax, +lut, +bf16", 0}, {"faminmax", AArch64::AEK_FAMINMAX, "+faminmax", "-faminmax", FEAT_INIT, "", 0}, -{"fp8fma", AArch64::AEK_FP8FMA, "+fp8fma", "-fp8fma", FEAT_INIT, "+fpmr", 0}, -{"ssve-fp8fma", AArch64::AEK_SSVE_FP8FMA, "+ssve-fp8fma", "-ssve-fp8fma", FEAT_INIT, "+sme2", 0}, -{"fp8dot2", AArch64::AEK_FP8DOT2, "+fp8dot2", "-fp8dot2", FEAT_INIT, "", 0}, -{"ssve-fp8dot2", AArch64::AEK_SSVE_FP8DOT2, "+ssve-fp8dot2", "-ssve-fp8dot2", FEAT_INIT, "+sme2", 0}, -{"fp8dot4", AArch64::AEK_FP8DOT4, "+fp8dot4", "-fp8dot4", FEAT_INIT, "", 0}, -{"ssve-fp8dot4", AArch64::AEK_SSVE_FP8DOT4, "+ssve-fp8dot4", "-ssve-fp8dot4", FEAT_INIT, "+sme2", 0}, +{"fp8fma", AArch64::AEK_FP8FMA, "+fp8fma", "-fp8fma", FEAT_INIT, "+fp8", 0}, +{"ssve-fp8fma", AArch64::AEK_SSVE_FP8FMA, "+ssve-fp8fma", "-ssve-fp8fma", FEAT_INIT, "+sme2,+fp8", 0}, +{"fp8dot2", AArch64::AEK_FP8DOT2, "+fp8dot2", "-fp8dot2", FEAT_INIT, "+fp8dot4", 0}, +{"ssve-fp8dot2", AArch64::AEK_SSVE_FP8DOT2, "+ssve-fp8dot2", "-ssve-fp8dot2", FEAT_INIT, "+ssve-fp8dot4", 0}, +{"fp8dot4", AArch64::AEK_FP8DOT4, "+fp8dot4", "-fp8dot4", FEAT_INIT, "+fp8fma", 0}, +{"ssve-fp8dot4", AArch64::AEK_SSVE_FP8DOT4, "+ssve-fp8dot4", "-ssve-fp8dot4", FEAT_INIT, "+ssve-fp8fma", 0}, {"lut", AArch64::AEK_LUT, "+lut", "-lut", FEAT_INIT, "", 0}, {"sme-lutv2", AArch64::AEK_SME_LUTv2, "+sme-lutv2", "-sme-lutv2", FEAT_INIT, "", 0}, {"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", FEAT_INIT, "+fp8,+sme2", 0}, CarolineConcatto wrote: I think we should also update : {"sme-f8f16", AArch64::AEK_SMEF8F16, "+sme-f8f16", "-sme-f8f16", FEAT_INIT, "+sme-f8f32", 0}, https://github.com/llvm/llvm-project/pull/90612 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Refactor how NamedDecl are renamed (PR #88735)
https://github.com/revane updated https://github.com/llvm/llvm-project/pull/88735 >From 64c1b5b7d6c29c86e0e7f26f0eff3b7a52f95e7e Mon Sep 17 00:00:00 2001 From: Edwin Vane Date: Thu, 28 Mar 2024 09:30:32 -0400 Subject: [PATCH] [clang-tidy] Refactor how NamedDecl are renamed The handling of renaming failures and multiple usages related to those failures is currently spread over several functions. Identifying the failure NamedDecl for a given usage is also duplicated, once when creating failures and again when identify usages. There are currently two ways to a failed NamedDecl from a usage: use the canonical decl or use the overridden method. With new methods about to be added, a cleanup was in order. The data flow is simplified as follows: * The visitor always forwards NamedDecls to addUsage(NamedDecl). * addUsage(NamedDecl) determines the failed NamedDecl and determines potential new names based on that failure. Usages are registered using addUsage(NamingCheckId). * addUsage(NamingCheckId) is now protected and its single responsibility is maintaining the integrity of the failure/usage map. --- .../bugprone/ReservedIdentifierCheck.cpp | 5 +- .../readability/IdentifierNamingCheck.cpp | 4 + .../utils/RenamerClangTidyCheck.cpp | 196 ++ .../clang-tidy/utils/RenamerClangTidyCheck.h | 14 +- 4 files changed, 121 insertions(+), 98 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp index f6714d056518d..53956661d57d1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ReservedIdentifierCheck.cpp @@ -178,8 +178,11 @@ std::optional ReservedIdentifierCheck::getDeclFailureInfo(const NamedDecl *Decl, const SourceManager &) const { assert(Decl && Decl->getIdentifier() && !Decl->getName().empty() && - !Decl->isImplicit() && "Decl must be an explicit identifier with a name."); + // Implicit identifiers cannot fail. + if (Decl->isImplicit()) +return std::nullopt; + return getFailureInfoImpl( Decl->getName(), isa(Decl->getDeclContext()), /*IsMacro = */ false, getLangOpts(), Invert, AllowedIdentifiers); diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index dc30531ebda0e..27a12bfc58068 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -1374,6 +1374,10 @@ IdentifierNamingCheck::getFailureInfo( std::optional IdentifierNamingCheck::getDeclFailureInfo(const NamedDecl *Decl, const SourceManager &SM) const { + // Implicit identifiers cannot be renamed. + if (Decl->isImplicit()) +return std::nullopt; + SourceLocation Loc = Decl->getLocation(); const FileStyle &FileStyle = getStyleForFile(SM.getFilename(Loc)); if (!FileStyle.isActive()) diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp index 962a243ce94d4..f5ed617365403 100644 --- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp @@ -61,6 +61,7 @@ struct DenseMapInfo { namespace clang::tidy { namespace { + class NameLookup { llvm::PointerIntPair Data; @@ -78,6 +79,7 @@ class NameLookup { operator bool() const { return !hasMultipleResolutions(); } const NamedDecl *operator*() const { return getDecl(); } }; + } // namespace static const NamedDecl *findDecl(const RecordDecl &RecDecl, @@ -91,6 +93,44 @@ static const NamedDecl *findDecl(const RecordDecl &RecDecl, return nullptr; } +/// Returns the function that \p Method is overridding. If There are none or +/// multiple overrides it returns nullptr. If the overridden function itself is +/// overridding then it will recurse up to find the first decl of the function. +static const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) { + if (Method->size_overridden_methods() != 1) +return nullptr; + + while (true) { +Method = *Method->begin_overridden_methods(); +assert(Method && "Overridden method shouldn't be null"); +unsigned NumOverrides = Method->size_overridden_methods(); +if (NumOverrides == 0) + return Method; +if (NumOverrides > 1) + return nullptr; + } +} + +static bool hasNoName(const NamedDecl *Decl) { + return !Decl->getIdentifier() || Decl->getName().empty(); +} + +static const NamedDecl *getFailureForNamedDecl(const NamedDecl *ND) { + const auto *Canonical = cast(ND->getCanonicalDecl()); + if (Canonical != ND) +return Canonical; + + if (const auto *Method = dyn_cast(ND)) { +if (const CXXMethodD
[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)
https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/89358 >From bf6acda6c7cb9a08b82b149c0df38d90e395f9e1 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 19 Apr 2024 10:54:12 +0200 Subject: [PATCH 1/4] [clang] CTAD: implement the missing IsDeducible constraint for alias templates. Fixes https://github.com/llvm/llvm-project/issues/85192 Fixes https://github.com/llvm/llvm-project/issues/84492 --- clang/include/clang/Basic/TokenKinds.def | 1 + clang/include/clang/Sema/Sema.h | 9 ++ clang/lib/Parse/ParseExprCXX.cpp | 16 ++-- clang/lib/Sema/SemaExprCXX.cpp| 11 +++ clang/lib/Sema/SemaTemplate.cpp | 70 --- clang/lib/Sema/SemaTemplateDeduction.cpp | 87 +++ clang/test/SemaCXX/cxx20-ctad-type-alias.cpp | 26 -- .../test/SemaCXX/type-traits-is-deducible.cpp | 47 ++ clang/www/cxx_status.html | 8 +- 9 files changed, 243 insertions(+), 32 deletions(-) create mode 100644 clang/test/SemaCXX/type-traits-is-deducible.cpp diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index a27fbed358a60..74102f4053968 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -537,6 +537,7 @@ TYPE_TRAIT_1(__is_referenceable, IsReferenceable, KEYCXX) TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX) TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) TYPE_TRAIT_2(__reference_constructs_from_temporary, ReferenceConstructsFromTemporary, KEYCXX) +TYPE_TRAIT_2(__is_deducible, IsDeducible, KEYCXX) // Embarcadero Expression Traits EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index a80ac6dbc7613..6f9a31bbbaf60 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9597,6 +9597,15 @@ class Sema final : public SemaBase { ArrayRef TemplateArgs, sema::TemplateDeductionInfo &Info); + /// Deduce the template arguments of the given template from \p FromType. + /// Used to implement the IsDeducible constraint for alias CTAD per C++ + /// [over.match.class.deduct]p4. + /// + /// It only supports class or type alias templates. + TemplateDeductionResult + DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType, + sema::TemplateDeductionInfo &Info); + TemplateDeductionResult DeduceTemplateArguments( TemplateParameterList *TemplateParams, ArrayRef Ps, ArrayRef As, sema::TemplateDeductionInfo &Info, diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 0d2ad980696fc..af4e205eeff80 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -3906,14 +3906,18 @@ ExprResult Parser::ParseTypeTrait() { BalancedDelimiterTracker Parens(*this, tok::l_paren); if (Parens.expectAndConsume()) return ExprError(); - + TypeTrait TTKind = TypeTraitFromTokKind(Kind); SmallVector Args; do { // Parse the next type. -TypeResult Ty = ParseTypeName(/*SourceRange=*/nullptr, - getLangOpts().CPlusPlus - ? DeclaratorContext::TemplateTypeArg - : DeclaratorContext::TypeName); +TypeResult Ty = ParseTypeName( +/*SourceRange=*/nullptr, +getLangOpts().CPlusPlus +// For __is_deducible type trait, the first argument is a template +// specification type without template argument lists. +? (TTKind == BTT_IsDeducible ? DeclaratorContext::TemplateArg + : DeclaratorContext::TemplateTypeArg) +: DeclaratorContext::TypeName); if (Ty.isInvalid()) { Parens.skipToEnd(); return ExprError(); @@ -3937,7 +3941,7 @@ ExprResult Parser::ParseTypeTrait() { SourceLocation EndLoc = Parens.getCloseLocation(); - return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Loc, Args, EndLoc); + return Actions.ActOnTypeTrait(TTKind, Loc, Args, EndLoc); } /// ParseArrayTypeTrait - Parse the built-in array type-trait diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index c1cb03e4ec7ae..222e8babdfaaa 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -6116,6 +6116,17 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceI tok::kw___is_pointer_interconvertible_base_of); return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs); + } + case BTT_IsDeducible: { +if (const auto *TSTToBeDeduced = +LhsT->getAs()) { + sema::TemplateDeductionInfo Info(KeyLoc); + return Self.DeduceTemplateArgumentsFromType(
[clang] [clang] CTAD: implement the missing IsDeducible constraint for alias templates (PR #89358)
hokein wrote: > > I agree with you -- having a well-described diagnostic message is better > > and clearer. I'm happy to improve it once we settle on the final > > implementation approach (the current diagnostic because > > '__is_deducible(AFoo, Foo)' evaluated to false seems okay to me. GCC also > > emits similar diagnostics). > > Well, if we agree on that, the only thing to do for approach 3 is to deal > with "anonymous" traits in ast dump and similar, which seems to be a fairly > bounded effort! I was worried about the potential need to handle these issues in various places. However, thinking more about it today, I think we can address them locally in the `getTraitSpelling`, which seems like a more favorable approach. I've now updated the patch to implement approach 3. Please take a look. Note that I haven't addressed the diagnostic improvement part yet; I plan to handle that in a separate follow-up patch. https://github.com/llvm/llvm-project/pull/89358 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. (PR #91316)
https://github.com/martinboehme created https://github.com/llvm/llvm-project/pull/91316 For some callers (see change in DataflowAnalysis.h), this is more convenient. >From abb7d53778394a220353deeeb86fbd06bf4352c2 Mon Sep 17 00:00:00 2001 From: Martin Braenne Date: Tue, 7 May 2024 10:23:16 + Subject: [PATCH] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. For some callers (see change in DataflowAnalysis.h), this is more convenient. --- .../Analysis/FlowSensitive/DataflowAnalysis.h | 5 ++--- .../FlowSensitive/DataflowAnalysisContext.h | 20 +-- .../FlowSensitive/DataflowAnalysisContext.cpp | 10 +- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h index 67eccdd030dcd..763af24454764 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -283,9 +283,8 @@ llvm::Expected> diagnoseFunction( if (!Context) return Context.takeError(); - auto OwnedSolver = std::make_unique(MaxSATIterations); - const WatchedLiteralsSolver *Solver = OwnedSolver.get(); - DataflowAnalysisContext AnalysisContext(std::move(OwnedSolver)); + auto Solver = std::make_unique(MaxSATIterations); + DataflowAnalysisContext AnalysisContext(*Solver); Environment Env(AnalysisContext, FuncDecl); AnalysisT Analysis = createAnalysis(ASTCtx, Env); llvm::SmallVector Diagnostics; diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h index aa2c366cb164a..13a74281e02b5 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h @@ -67,7 +67,19 @@ class DataflowAnalysisContext { DataflowAnalysisContext(std::unique_ptr S, Options Opts = Options{ /*ContextSensitiveOpts=*/std::nullopt, - /*Logger=*/nullptr}); + /*Logger=*/nullptr}) + : DataflowAnalysisContext(*S, std::move(S), Opts) {} + + /// Constructs a dataflow analysis context. + /// + /// Requirements: + /// + /// `S` must outlive the `DataflowAnalysisContext`. + DataflowAnalysisContext(Solver &S, Options Opts = Options{ + /*ContextSensitiveOpts=*/std::nullopt, + /*Logger=*/nullptr}) + : DataflowAnalysisContext(S, nullptr, Opts) {} + ~DataflowAnalysisContext(); /// Sets a callback that returns the names and types of the synthetic fields @@ -209,6 +221,9 @@ class DataflowAnalysisContext { using DenseMapInfo::isEqual; }; + DataflowAnalysisContext(Solver &S, std::unique_ptr OwnedSolver, + Options Opts); + // Extends the set of modeled field declarations. void addModeledFields(const FieldSet &Fields); @@ -232,7 +247,8 @@ class DataflowAnalysisContext { Solver::Result::Status::Unsatisfiable; } - std::unique_ptr S; + Solver &S; + std::unique_ptr OwnedSolver; std::unique_ptr A; // Maps from program declarations and statements to storage locations that are diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp index e94fd39c45dc1..3041dcf6d500c 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -170,7 +170,7 @@ DataflowAnalysisContext::joinFlowConditions(Atom FirstToken, Solver::Result DataflowAnalysisContext::querySolver( llvm::SetVector Constraints) { - return S->solve(Constraints.getArrayRef()); + return S.solve(Constraints.getArrayRef()); } bool DataflowAnalysisContext::flowConditionImplies(Atom Token, @@ -338,10 +338,10 @@ static std::unique_ptr makeLoggerFromCommandLine() { return Logger::html(std::move(StreamFactory)); } -DataflowAnalysisContext::DataflowAnalysisContext(std::unique_ptr S, - Options Opts) -: S(std::move(S)), A(std::make_unique()), Opts(Opts) { - assert(this->S != nullptr); +DataflowAnalysisContext::DataflowAnalysisContext( +Solver &S, std::unique_ptr OwnedSolver, Options Opts) +: S(S), OwnedSolver(std::move(OwnedSolver)), A(std::make_unique()), + Opts(Opts) { // If the -dataflow-log command-line flag was set, synthesize a logger. // This is ugly but provides a uniform method for ad-hoc debugging dataflow- // based tools. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. (PR #91316)
llvmbot wrote: @llvm/pr-subscribers-clang Author: None (martinboehme) Changes For some callers (see change in DataflowAnalysis.h), this is more convenient. --- Full diff: https://github.com/llvm/llvm-project/pull/91316.diff 3 Files Affected: - (modified) clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h (+2-3) - (modified) clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h (+18-2) - (modified) clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp (+5-5) ``diff diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h index 67eccdd030dcd..763af24454764 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -283,9 +283,8 @@ llvm::Expected> diagnoseFunction( if (!Context) return Context.takeError(); - auto OwnedSolver = std::make_unique(MaxSATIterations); - const WatchedLiteralsSolver *Solver = OwnedSolver.get(); - DataflowAnalysisContext AnalysisContext(std::move(OwnedSolver)); + auto Solver = std::make_unique(MaxSATIterations); + DataflowAnalysisContext AnalysisContext(*Solver); Environment Env(AnalysisContext, FuncDecl); AnalysisT Analysis = createAnalysis(ASTCtx, Env); llvm::SmallVector Diagnostics; diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h index aa2c366cb164a..13a74281e02b5 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h @@ -67,7 +67,19 @@ class DataflowAnalysisContext { DataflowAnalysisContext(std::unique_ptr S, Options Opts = Options{ /*ContextSensitiveOpts=*/std::nullopt, - /*Logger=*/nullptr}); + /*Logger=*/nullptr}) + : DataflowAnalysisContext(*S, std::move(S), Opts) {} + + /// Constructs a dataflow analysis context. + /// + /// Requirements: + /// + /// `S` must outlive the `DataflowAnalysisContext`. + DataflowAnalysisContext(Solver &S, Options Opts = Options{ + /*ContextSensitiveOpts=*/std::nullopt, + /*Logger=*/nullptr}) + : DataflowAnalysisContext(S, nullptr, Opts) {} + ~DataflowAnalysisContext(); /// Sets a callback that returns the names and types of the synthetic fields @@ -209,6 +221,9 @@ class DataflowAnalysisContext { using DenseMapInfo::isEqual; }; + DataflowAnalysisContext(Solver &S, std::unique_ptr OwnedSolver, + Options Opts); + // Extends the set of modeled field declarations. void addModeledFields(const FieldSet &Fields); @@ -232,7 +247,8 @@ class DataflowAnalysisContext { Solver::Result::Status::Unsatisfiable; } - std::unique_ptr S; + Solver &S; + std::unique_ptr OwnedSolver; std::unique_ptr A; // Maps from program declarations and statements to storage locations that are diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp index e94fd39c45dc1..3041dcf6d500c 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -170,7 +170,7 @@ DataflowAnalysisContext::joinFlowConditions(Atom FirstToken, Solver::Result DataflowAnalysisContext::querySolver( llvm::SetVector Constraints) { - return S->solve(Constraints.getArrayRef()); + return S.solve(Constraints.getArrayRef()); } bool DataflowAnalysisContext::flowConditionImplies(Atom Token, @@ -338,10 +338,10 @@ static std::unique_ptr makeLoggerFromCommandLine() { return Logger::html(std::move(StreamFactory)); } -DataflowAnalysisContext::DataflowAnalysisContext(std::unique_ptr S, - Options Opts) -: S(std::move(S)), A(std::make_unique()), Opts(Opts) { - assert(this->S != nullptr); +DataflowAnalysisContext::DataflowAnalysisContext( +Solver &S, std::unique_ptr OwnedSolver, Options Opts) +: S(S), OwnedSolver(std::move(OwnedSolver)), A(std::make_unique()), + Opts(Opts) { // If the -dataflow-log command-line flag was set, synthesize a logger. // This is ugly but provides a uniform method for ad-hoc debugging dataflow- // based tools. `` https://github.com/llvm/llvm-project/pull/91316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ClangFormat] Add DiagHandler for getStyle function (PR #91317)
https://github.com/pointhex created https://github.com/llvm/llvm-project/pull/91317 It allows to control of error output for the function. >From 74a0053509564a10faf335c32211cf3dddef4e98 Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Tue, 7 May 2024 12:27:29 +0200 Subject: [PATCH] [ClangFormat] Add DiagHandler for getStyle function It allows to control of error output for the function. --- clang/include/clang/Format/Format.h | 3 ++- clang/lib/Format/Format.cpp | 19 +++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 74893f23210cd0..aa6a2a16fa8ecc 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -5385,7 +5385,8 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, StringRef FallbackStyle, StringRef Code = "", llvm::vfs::FileSystem *FS = nullptr, - bool AllowUnknownOptions = false); + bool AllowUnknownOptions = false, + llvm::SourceMgr::DiagHandlerTy DiagHandler = nullptr); // Guesses the language from the ``FileName`` and ``Code`` to be formatted. // Defaults to FormatStyle::LK_Cpp. diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index c4eac1c99a663f..cf8a2a050a83c5 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3947,12 +3947,13 @@ const char *DefaultFallbackStyle = "LLVM"; llvm::ErrorOr> loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS, - FormatStyle *Style, bool AllowUnknownOptions) { + FormatStyle *Style, bool AllowUnknownOptions, + llvm::SourceMgr::DiagHandlerTy DiagHandler = nullptr) { llvm::ErrorOr> Text = FS->getBufferForFile(ConfigFile.str()); if (auto EC = Text.getError()) return EC; - if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions)) + if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions, DiagHandler)) return EC; return Text; } @@ -3960,7 +3961,8 @@ loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS, llvm::Expected getStyle(StringRef StyleName, StringRef FileName, StringRef FallbackStyleName, StringRef Code, llvm::vfs::FileSystem *FS, - bool AllowUnknownOptions) { + bool AllowUnknownOptions, + llvm::SourceMgr::DiagHandlerTy DiagHandler) { FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code)); FormatStyle FallbackStyle = getNoStyle(); if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle)) @@ -3974,7 +3976,7 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, StringRef Source = ""; if (std::error_code ec = parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style, - AllowUnknownOptions)) { + AllowUnknownOptions, DiagHandler)) { return make_string_error("Error parsing -style: " + ec.message()); } @@ -3994,7 +3996,7 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, StyleName.starts_with_insensitive("file:")) { auto ConfigFile = StyleName.substr(5); llvm::ErrorOr> Text = -loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions); +loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions, DiagHandler); if (auto EC = Text.getError()) { return make_string_error("Error reading " + ConfigFile + ": " + EC.message()); @@ -4029,12 +4031,13 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, // Reset possible inheritance Style.InheritsParentConfig = false; - auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {}; + auto diagHandlerOrDropHandling = + DiagHandler ? DiagHandler : [](llvm::SMDiagnostic const &, void *) {}; auto applyChildFormatTexts = [&](FormatStyle *Style) { for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) { auto EC = parseConfiguration(*MemBuf, Style, AllowUnknownOptions, - dropDiagnosticHandler); + diagHandlerOrDropHandling); // It was already correctly parsed. assert(!EC); static_cast(EC); @@ -4068,7 +4071,7 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, } llvm::ErrorOr> Text = - loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions); + loadAnd
[clang] [ClangFormat] Add DiagHandler for getStyle function (PR #91317)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/91317 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ClangFormat] Add DiagHandler for getStyle function (PR #91317)
llvmbot wrote: @llvm/pr-subscribers-clang-format Author: None (pointhex) Changes It allows to control of error output for the function. --- Full diff: https://github.com/llvm/llvm-project/pull/91317.diff 2 Files Affected: - (modified) clang/include/clang/Format/Format.h (+2-1) - (modified) clang/lib/Format/Format.cpp (+11-8) ``diff diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index 74893f23210cd..aa6a2a16fa8ec 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -5385,7 +5385,8 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, StringRef FallbackStyle, StringRef Code = "", llvm::vfs::FileSystem *FS = nullptr, - bool AllowUnknownOptions = false); + bool AllowUnknownOptions = false, + llvm::SourceMgr::DiagHandlerTy DiagHandler = nullptr); // Guesses the language from the ``FileName`` and ``Code`` to be formatted. // Defaults to FormatStyle::LK_Cpp. diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index c4eac1c99a663..cf8a2a050a83c 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3947,12 +3947,13 @@ const char *DefaultFallbackStyle = "LLVM"; llvm::ErrorOr> loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS, - FormatStyle *Style, bool AllowUnknownOptions) { + FormatStyle *Style, bool AllowUnknownOptions, + llvm::SourceMgr::DiagHandlerTy DiagHandler = nullptr) { llvm::ErrorOr> Text = FS->getBufferForFile(ConfigFile.str()); if (auto EC = Text.getError()) return EC; - if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions)) + if (auto EC = parseConfiguration(*Text.get(), Style, AllowUnknownOptions, DiagHandler)) return EC; return Text; } @@ -3960,7 +3961,8 @@ loadAndParseConfigFile(StringRef ConfigFile, llvm::vfs::FileSystem *FS, llvm::Expected getStyle(StringRef StyleName, StringRef FileName, StringRef FallbackStyleName, StringRef Code, llvm::vfs::FileSystem *FS, - bool AllowUnknownOptions) { + bool AllowUnknownOptions, + llvm::SourceMgr::DiagHandlerTy DiagHandler) { FormatStyle Style = getLLVMStyle(guessLanguage(FileName, Code)); FormatStyle FallbackStyle = getNoStyle(); if (!getPredefinedStyle(FallbackStyleName, Style.Language, &FallbackStyle)) @@ -3974,7 +3976,7 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, StringRef Source = ""; if (std::error_code ec = parseConfiguration(llvm::MemoryBufferRef(StyleName, Source), &Style, - AllowUnknownOptions)) { + AllowUnknownOptions, DiagHandler)) { return make_string_error("Error parsing -style: " + ec.message()); } @@ -3994,7 +3996,7 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, StyleName.starts_with_insensitive("file:")) { auto ConfigFile = StyleName.substr(5); llvm::ErrorOr> Text = -loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions); +loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions, DiagHandler); if (auto EC = Text.getError()) { return make_string_error("Error reading " + ConfigFile + ": " + EC.message()); @@ -4029,12 +4031,13 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, // Reset possible inheritance Style.InheritsParentConfig = false; - auto dropDiagnosticHandler = [](const llvm::SMDiagnostic &, void *) {}; + auto diagHandlerOrDropHandling = + DiagHandler ? DiagHandler : [](llvm::SMDiagnostic const &, void *) {}; auto applyChildFormatTexts = [&](FormatStyle *Style) { for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) { auto EC = parseConfiguration(*MemBuf, Style, AllowUnknownOptions, - dropDiagnosticHandler); + diagHandlerOrDropHandling); // It was already correctly parsed. assert(!EC); static_cast(EC); @@ -4068,7 +4071,7 @@ llvm::Expected getStyle(StringRef StyleName, StringRef FileName, } llvm::ErrorOr> Text = - loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions); + loadAndParseConfigFile(ConfigFile, FS, &Style, AllowUnknownOptions, DiagHandler); if (auto EC = Text.getError()) { if (EC != ParseError::Unsuitable) { return make_string_error("Error reading
[clang] [clang] CTAD: fix the aggregate deduction guide for alias templates. (PR #90894)
@@ -261,6 +261,13 @@ AG ag = {1}; // CHECK: | `-BuiltinType {{.*}} 'int' // CHECK: `-ParmVarDecl {{.*}} 'int' +template +using BG = G; +BG bg(1.0); +// CHECK-LABEL: Dumping +// CHECK: FunctionTemplateDecl {{.*}} implicit +// CHECK: |-CXXDeductionGuideDecl {{.*}} 'auto (int) -> G' aggregate hokein wrote: > The line is a CHECK, not a CHECK-NEXT, so it could appear any number of lines > afterwards. Yeah, ideally it should be `CHECK-NEXT`, but we can't use it because of the ambiguity in the content of the above line (there are two other deduction guides emitting the same content), so I end up using the `CHECK: |-...`, it at least demonstrates that it is a child of something. https://github.com/llvm/llvm-project/pull/90894 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 651bdb9 - [ARM] Armv8-R does not require fp64 or neon. (#88287)
Author: Chris Copeland Date: 2024-05-07T11:48:30+01:00 New Revision: 651bdb96b16d4e522f4611b60103234b1f890b24 URL: https://github.com/llvm/llvm-project/commit/651bdb96b16d4e522f4611b60103234b1f890b24 DIFF: https://github.com/llvm/llvm-project/commit/651bdb96b16d4e522f4611b60103234b1f890b24.diff LOG: [ARM] Armv8-R does not require fp64 or neon. (#88287) This was [addressed for AArch64 here](https://github.com/llvm/llvm-project/pull/79004), but the same applies to ARM. Move the enablement of neon+fp64 to `-mcpu=cortex-r52`, which optionally supports these features. Added: Modified: clang/test/Driver/arm-cortex-cpus-1.c clang/test/Driver/arm-features.c clang/test/Preprocessor/arm-target-features.c llvm/docs/ReleaseNotes.rst llvm/include/llvm/TargetParser/ARMTargetParser.def llvm/lib/Target/ARM/ARMArchitectures.td llvm/lib/Target/ARM/ARMProcessors.td llvm/test/Analysis/CostModel/ARM/arith.ll llvm/test/Analysis/CostModel/ARM/cast.ll llvm/test/Analysis/CostModel/ARM/cast_ldst.ll llvm/test/Analysis/CostModel/ARM/cmps.ll llvm/test/Analysis/CostModel/ARM/divrem.ll llvm/test/CodeGen/ARM/cortex-a57-misched-basic.ll llvm/test/CodeGen/ARM/fpconv.ll llvm/test/CodeGen/ARM/half.ll llvm/test/CodeGen/ARM/useaa.ll llvm/unittests/TargetParser/TargetParserTest.cpp Removed: diff --git a/clang/test/Driver/arm-cortex-cpus-1.c b/clang/test/Driver/arm-cortex-cpus-1.c index 25abbe1e3a8ad..6f0b64910f9b0 100644 --- a/clang/test/Driver/arm-cortex-cpus-1.c +++ b/clang/test/Driver/arm-cortex-cpus-1.c @@ -153,23 +153,23 @@ // RUN: %clang -target armv8r-linux-gnueabi -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8R %s // RUN: %clang -target arm -march=armv8r -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8R %s // RUN: %clang -target arm -march=armv8-r -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8R %s -// CHECK-V8R: "-cc1"{{.*}} "-triple" "armv8r-{{.*}} "-target-cpu" "cortex-r52" +// CHECK-V8R: "-cc1"{{.*}} "-triple" "armv8r-{{.*}} "-target-cpu" "generic" // RUN: %clang -target armv8r-linux-gnueabi -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8R-BIG %s // RUN: %clang -target arm -march=armv8r -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8R-BIG %s // RUN: %clang -target arm -march=armv8-r -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8R-BIG %s -// CHECK-V8R-BIG: "-cc1"{{.*}} "-triple" "armebv8r-{{.*}} "-target-cpu" "cortex-r52" +// CHECK-V8R-BIG: "-cc1"{{.*}} "-triple" "armebv8r-{{.*}} "-target-cpu" "generic" // RUN: %clang -target armv8r-linux-gnueabi -mthumb -### -c %s 2>&1 | \ // RUN: FileCheck -check-prefix=CHECK-V8R-THUMB %s // RUN: %clang -target arm -march=armv8r -mthumb -### -c %s 2>&1 | \ // RUN: FileCheck -check-prefix=CHECK-V8R-THUMB %s -// CHECK-V8R-THUMB: "-cc1"{{.*}} "-triple" "thumbv8r-{{.*}} "-target-cpu" "cortex-r52" +// CHECK-V8R-THUMB: "-cc1"{{.*}} "-triple" "thumbv8r-{{.*}} "-target-cpu" "generic" // RUN: %clang -target armv8r-linux-gnueabi -mthumb -mbig-endian -### -c %s 2>&1 | \ // RUN: FileCheck -check-prefix=CHECK-V8R-THUMB-BIG %s // RUN: %clang -target arm -march=armv8r -mthumb -mbig-endian -### -c %s 2>&1 | \ // RUN: FileCheck -check-prefix=CHECK-V8R-THUMB-BIG %s -// CHECK-V8R-THUMB-BIG: "-cc1"{{.*}} "-triple" "thumbebv8r-{{.*}} "-target-cpu" "cortex-r52" +// CHECK-V8R-THUMB-BIG: "-cc1"{{.*}} "-triple" "thumbebv8r-{{.*}} "-target-cpu" "generic" // RUN: %clang -mcpu=generic -target armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-GENERIC %s // RUN: %clang -mcpu=generic -target arm -march=armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-GENERIC %s diff --git a/clang/test/Driver/arm-features.c b/clang/test/Driver/arm-features.c index e043244f18a61..eb424f5f61116 100644 --- a/clang/test/Driver/arm-features.c +++ b/clang/test/Driver/arm-features.c @@ -74,7 +74,7 @@ // Check +crypto for M and R profiles: // // RUN: %clang -target arm-arm-none-eabi -march=armv8-r+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CRYPTO-R %s -// CHECK-CRYPTO-R: "-cc1"{{.*}} "-target-cpu" "cortex-r52"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes" +// CHECK-CRYPTO-R: "-cc1"{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+sha2" "-target-feature" "+aes" // RUN: %clang -target arm-arm-none-eabi -march=armv8-m.base+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO5 %s // RUN: %clang -target arm-arm-none-eabi -march=armv8-m.main+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO5 %s // RUN: %clang -target arm-arm-none-eabi -mcpu=cortex-m23+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRYPTO5 %s diff --git a/clang/test/Preprocessor/arm-target-features.c b/clang/test/Preprocessor/arm-target-features.c index 236c9f2479b70..2d65bfd4f4399 100644 --- a/clang/test/Prepro
[clang] [llvm] [ARM] Armv8-R does not require fp64 or neon. (PR #88287)
https://github.com/ostannard closed https://github.com/llvm/llvm-project/pull/88287 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [ARM] Armv8-R does not require fp64 or neon. (PR #88287)
github-actions[bot] wrote: @chrisnc 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 receive 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/88287 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Catch missing format attributes (PR #70024)
https://github.com/budimirarandjelovicsyrmia updated https://github.com/llvm/llvm-project/pull/70024 From 75ec541cdf717931afe70abc412cb1747f84e0d7 Mon Sep 17 00:00:00 2001 From: budimirarandjelovicsyrmia Date: Fri, 5 Apr 2024 15:20:37 +0200 Subject: [PATCH] [clang] Catch missing format attributes --- clang/docs/ReleaseNotes.rst | 3 + clang/include/clang/Basic/DiagnosticGroups.td | 1 - .../clang/Basic/DiagnosticSemaKinds.td| 3 + clang/include/clang/Sema/Sema.h | 4 + clang/lib/Sema/SemaChecking.cpp | 4 +- clang/lib/Sema/SemaDeclAttr.cpp | 119 ++- clang/test/Sema/attr-format-missing.c | 277 clang/test/Sema/attr-format-missing.cpp | 303 ++ 8 files changed, 709 insertions(+), 5 deletions(-) create mode 100644 clang/test/Sema/attr-format-missing.c create mode 100644 clang/test/Sema/attr-format-missing.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a85095e424b64..a07b223b48509 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -473,6 +473,9 @@ Improvements to Clang's diagnostics } }; +- Clang now diagnoses missing format attributes for non-template functions and + class/struct/union members. Fixes #GH70024 + Improvements to Clang's time-trace -- diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 60f87da2a7387..5fa2f6e7db4fa 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -505,7 +505,6 @@ def MainReturnType : DiagGroup<"main-return-type">; def MaxUnsignedZero : DiagGroup<"max-unsigned-zero">; def MissingBraces : DiagGroup<"missing-braces">; def MissingDeclarations: DiagGroup<"missing-declarations">; -def : DiagGroup<"missing-format-attribute">; def : DiagGroup<"missing-include-dirs">; def MissingNoreturn : DiagGroup<"missing-noreturn">; def MultiChar : DiagGroup<"multichar">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 9a0bae9c216de..1fbe379d9af0b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1010,6 +1010,9 @@ def err_opencl_invalid_param : Error< def err_opencl_invalid_return : Error< "declaring function return value of type %0 is not allowed %select{; did you forget * ?|}1">; def warn_enum_value_overflow : Warning<"overflow in enumeration value">; +def warn_missing_format_attribute : Warning< + "diagnostic behavior may be improved by adding the %0 format attribute to the declaration of %1">, + InGroup>, DefaultIgnore; def warn_pragma_options_align_reset_failed : Warning< "#pragma options align=reset failed: %0">, InGroup; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index a80ac6dbc7613..5552a48456cde 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3725,6 +3725,10 @@ class Sema final : public SemaBase { bool DiagnoseSwiftName(Decl *D, StringRef Name, SourceLocation Loc, const ParsedAttr &AL, bool IsAsync); + void DiagnoseMissingFormatAttributes(const FunctionDecl *FDecl, + ArrayRef Args, + SourceLocation Loc); + UuidAttr *mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI, StringRef UuidAsWritten, MSGuidDecl *GuidDecl); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 3179d542b1f92..fd5de633be318 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -8085,8 +8085,10 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, } } - if (FD) + if (FD) { diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc); +DiagnoseMissingFormatAttributes(FD, Args, Range.getBegin()); + } } /// CheckConstructorCall - Check a constructor call for correctness and safety diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 363ae93cb62df..5f5403d303a90 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -163,6 +163,13 @@ static bool isInstanceMethod(const Decl *D) { return false; } +static bool checkIfMethodHasImplicitObjectParameter(const Decl *D) { + if (const auto *MethodDecl = dyn_cast(D)) +return MethodDecl->isInstance() && + !MethodDecl->hasCXXExplicitFunctionObjectParameter(); + return false; +} + static inline bool isNSStringType(QualType T, ASTContext &Ctx, bool AllowNSAttributedString = false) { const auto *PT = T->getAs(); @@ -312,7 +319,7 @@ static bool checkFunctionOrMethodParameterIndex( // In C++ the implicit 'this' fun
[clang] 97dd8e3 - [analyzer] Clean up apiModeling.llvm.ReturnValue (#91231)
Author: Donát Nagy Date: 2024-05-07T13:06:11+02:00 New Revision: 97dd8e3c4f38ef345b01fbbf0a2052c7875ff7e0 URL: https://github.com/llvm/llvm-project/commit/97dd8e3c4f38ef345b01fbbf0a2052c7875ff7e0 DIFF: https://github.com/llvm/llvm-project/commit/97dd8e3c4f38ef345b01fbbf0a2052c7875ff7e0.diff LOG: [analyzer] Clean up apiModeling.llvm.ReturnValue (#91231) This commit heavily refactors and simplifies the small and trivial checker `apiModeling.llvm.ReturnValue`, which is responsible for modeling the peculiar coding convention that in the LLVM/Clang codebase certain Error() methods always return true. Changes included in this commit: - The call description mode is now specified explicitly (this is not the most significant change, but it was the original reason for touching this checker). - Previously the code provided support for modeling functions that always return `false`; but there was no need for that, so this commit hardcodes that the return value is `true`. - The overcomplicated constraint/state handling logic was simplified. - The separate `checkEndFunction` callback was removed to simplify the code. Admittedly this means that the note tag for the " returns false, breaking the convention" case is placed on the method call instead of the `return` statement; but that case will _never_ appear in practice, so this difference is mostly academical. - The text of the note tags was clarified. - The descriptions in the header comment and Checkers.td were clarified. - Some minor cleanup was applied in the associated test file. This change is very close to NFC because it only affects a hidden `apiModeling.llvm` checker that's only relevant during the analysis of the LLVM/Clang codebase, and even there it doesn't affect the normal behavior of the checker. Added: Modified: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp clang/test/Analysis/return-value-guaranteed.cpp Removed: diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 520286b57c9fd..64414e3d37f75 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1397,7 +1397,7 @@ def CastValueChecker : Checker<"CastValue">, Documentation; def ReturnValueChecker : Checker<"ReturnValue">, - HelpText<"Model the guaranteed boolean return value of function calls">, + HelpText<"Model certain Error() methods that always return true by convention">, Documentation; } // end "apiModeling.llvm" diff --git a/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp index c3112ebe4e794..3da571adfa44c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp @@ -1,4 +1,4 @@ -//===- ReturnValueChecker - Applies guaranteed return values *- C++ -*-===// +//===- ReturnValueChecker - Check methods always returning true -*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,13 @@ // //===--===// // -// This defines ReturnValueChecker, which checks for calls with guaranteed -// boolean return value. It ensures the return value of each function call. +// This defines ReturnValueChecker, which models a very specific coding +// convention within the LLVM/Clang codebase: there several classes that have +// Error() methods which always return true. +// This checker was introduced to eliminate false positives caused by this +// peculiar "always returns true" invariant. (Normally, the analyzer assumes +// that a function returning `bool` can return both `true` and `false`, because +// otherwise it could've been a `void` function.) // //===--===// @@ -18,43 +23,40 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/FormatVariadic.h" #include using namespace clang; using namespace ento; +using llvm::formatv; namespace { -class ReturnValueChecker : public Checker { +class ReturnValueChecker : public Checker { public: - // It sets the predefined invariant ('CDM') if the current call not break it. void checkPostCall(const CallEvent &Call, CheckerContext &C) const; - // It reports whether a predefined invariant ('CDM') is broken. - void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const; - private: - // The pairs are in the following form: {{{class, call}}, return value} -
[clang] [analyzer] Clean up apiModeling.llvm.ReturnValue (PR #91231)
https://github.com/NagyDonat closed https://github.com/llvm/llvm-project/pull/91231 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [FMV][AArch64] Don't optimize backward compatible features in resolver. (PR #90928)
ilinpv wrote: Apologies for quick merge and , thanks for comments. I agree with all of them. I would prefer to keep the patch and provide fixes on top of it. Let me know if you want it reverted. https://github.com/llvm/llvm-project/pull/90928 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Use explicit call description mode in more checkers (PR #90974)
https://github.com/NagyDonat updated https://github.com/llvm/llvm-project/pull/90974 From 9ed06c41127c88b3e2e8596ddd83b42ab2856f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= Date: Fri, 3 May 2024 16:13:19 +0200 Subject: [PATCH 1/2] [analyzer] Use explicit call description mode in more checkers This commit explicitly specifies the matching mode (C library function, any non-method function, or C++ method) for the `CallDescription`s constructed in various checkers. Some code was simplified to use `CallDescriptionSet`s instead of individual `CallDescription`s. This change won't cause major functional changes, but isn't NFC because it ensures that e.g. call descriptions for a non-method function won't accidentally match a method that has the same name. Separate commits have already performed this change in other checkers: - easy chases: e2f1cbae45f81f3cd9a4d3c2bcf69a094eb060fa - MallocChecker: d6d84b5d1448e4f2e24b467a0abcf42fe9d543e9 - iterator checkers: 06eedffe0d2782922e63cc25cb927f4acdaf7b30 - InvalidPtr checker: 024281d4d26344f9613b9115ea1fcbdbdba23235 ... and follow-up commits will handle the remaining checkers. My goal is to ensure that the call description mode is always explicitly specified and eliminate (or strongly restrict) the vague "may be either a method or a simple function" mode that's the current default. --- .../BlockInCriticalSectionChecker.cpp | 38 +++- .../Checkers/CStringChecker.cpp | 4 +- .../Checkers/InnerPointerChecker.cpp | 58 --- .../Checkers/SmartPtrModeling.cpp | 18 +++--- .../StaticAnalyzer/Checkers/StreamChecker.cpp | 8 ++- 5 files changed, 64 insertions(+), 62 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index e4373915410fb2..9b612d03e93c31 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -149,26 +149,34 @@ class BlockInCriticalSectionChecker : public Checker { private: const std::array MutexDescriptors{ MemberMutexDescriptor( - CallDescription(/*QualifiedName=*/{"std", "mutex", "lock"}, + CallDescription(/*MatchAs=*/CDM::CXXMethod, + /*QualifiedName=*/{"std", "mutex", "lock"}, /*RequiredArgs=*/0), - CallDescription({"std", "mutex", "unlock"}, 0)), - FirstArgMutexDescriptor(CallDescription({"pthread_mutex_lock"}, 1), - CallDescription({"pthread_mutex_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_lock"}, 1), - CallDescription({"mtx_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"pthread_mutex_trylock"}, 1), - CallDescription({"pthread_mutex_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_trylock"}, 1), - CallDescription({"mtx_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_timedlock"}, 1), - CallDescription({"mtx_unlock"}, 1)), + CallDescription(CDM::CXXMethod, {"std", "mutex", "unlock"}, 0)), + FirstArgMutexDescriptor( + CallDescription(CDM::CLibrary, {"pthread_mutex_lock"}, 1), + CallDescription(CDM::CLibrary, {"pthread_mutex_unlock"}, 1)), + FirstArgMutexDescriptor( + CallDescription(CDM::CLibrary, {"mtx_lock"}, 1), + CallDescription(CDM::CLibrary, {"mtx_unlock"}, 1)), + FirstArgMutexDescriptor( + CallDescription(CDM::CLibrary, {"pthread_mutex_trylock"}, 1), + CallDescription(CDM::CLibrary, {"pthread_mutex_unlock"}, 1)), + FirstArgMutexDescriptor( + CallDescription(CDM::CLibrary, {"mtx_trylock"}, 1), + CallDescription(CDM::CLibrary, {"mtx_unlock"}, 1)), + FirstArgMutexDescriptor( + CallDescription(CDM::CLibrary, {"mtx_timedlock"}, 1), + CallDescription(CDM::CLibrary, {"mtx_unlock"}, 1)), RAIIMutexDescriptor("lock_guard"), RAIIMutexDescriptor("unique_lock")}; const std::array BlockingFunctions{ - ArrayRef{StringRef{"sleep"}}, ArrayRef{StringRef{"getc"}}, - ArrayRef{StringRef{"fgets"}}, ArrayRef{StringRef{"read"}}, - ArrayRef{StringRef{"recv"}}}; + CallDescription(CDM::CLibrary, {"sleep"}), + CallDescription(CDM::CLibrary, {"getc"}), + CallDescription(CDM::CLibrary, {"fgets"}), + CallDescription(CDM::CLibrary, {"read"}), + CallDescription(CDM::CLibrary, {"recv"})}; const BugType BlockInCritSectionBugType{ this, "Call to blocking function in critical section", "Blocking Error"}; diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index f9548b5c3010bf..238e87a712a43a 100644 --- a/c
[clang] [analyzer] Use explicit call description mode in more checkers (PR #90974)
=?utf-8?q?Donát?= Nagy Message-ID: In-Reply-To: llvmbot wrote: @llvm/pr-subscribers-clang Author: Donát Nagy (NagyDonat) Changes This commit explicitly specifies the matching mode (C library function, any non-method function, or C++ method) for the `CallDescription`s constructed in various checkers. Some code was simplified to use `CallDescriptionSet`s instead of individual `CallDescription`s. This change won't cause major functional changes, but isn't NFC because it ensures that e.g. call descriptions for a non-method function won't accidentally match a method that has the same name. Separate commits have already performed this change in other checkers: - easy cases: e2f1cbae45f81f3cd9a4d3c2bcf69a094eb060fa - MallocChecker: d6d84b5d1448e4f2e24b467a0abcf42fe9d543e9 - iterator checkers: 06eedffe0d2782922e63cc25cb927f4acdaf7b30 - InvalidPtr checker: 024281d4d26344f9613b9115ea1fcbdbdba23235 ... and follow-up commits will handle the remaining checkers. My goal is to ensure that the call description mode is always explicitly specified and eliminate (or strongly restrict) the vague "may be either a method or a simple function" mode that's the current default. --- Full diff: https://github.com/llvm/llvm-project/pull/90974.diff 5 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp (+26-19) - (modified) clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (+2-2) - (modified) clang/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp (+25-33) - (modified) clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp (+9-9) - (modified) clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp (+5-3) ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index e4373915410fb..290916c3c1413 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -149,26 +149,34 @@ class BlockInCriticalSectionChecker : public Checker { private: const std::array MutexDescriptors{ MemberMutexDescriptor( - CallDescription(/*QualifiedName=*/{"std", "mutex", "lock"}, - /*RequiredArgs=*/0), - CallDescription({"std", "mutex", "unlock"}, 0)), - FirstArgMutexDescriptor(CallDescription({"pthread_mutex_lock"}, 1), - CallDescription({"pthread_mutex_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_lock"}, 1), - CallDescription({"mtx_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"pthread_mutex_trylock"}, 1), - CallDescription({"pthread_mutex_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_trylock"}, 1), - CallDescription({"mtx_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_timedlock"}, 1), - CallDescription({"mtx_unlock"}, 1)), + {/*MatchAs=*/CDM::CXXMethod, + /*QualifiedName=*/{"std", "mutex", "lock"}, + /*RequiredArgs=*/0}, + {CDM::CXXMethod, {"std", "mutex", "unlock"}, 0}), + FirstArgMutexDescriptor( + {CDM::CLibrary, {"pthread_mutex_lock"}, 1}, + {CDM::CLibrary, {"pthread_mutex_unlock"}, 1}), + FirstArgMutexDescriptor( + {CDM::CLibrary, {"mtx_lock"}, 1}, + {CDM::CLibrary, {"mtx_unlock"}, 1}), + FirstArgMutexDescriptor( + {CDM::CLibrary, {"pthread_mutex_trylock"}, 1}, + {CDM::CLibrary, {"pthread_mutex_unlock"}, 1}), + FirstArgMutexDescriptor( + {CDM::CLibrary, {"mtx_trylock"}, 1}, + {CDM::CLibrary, {"mtx_unlock"}, 1}), + FirstArgMutexDescriptor( + {CDM::CLibrary, {"mtx_timedlock"}, 1}, + {CDM::CLibrary, {"mtx_unlock"}, 1}), RAIIMutexDescriptor("lock_guard"), RAIIMutexDescriptor("unique_lock")}; - const std::array BlockingFunctions{ - ArrayRef{StringRef{"sleep"}}, ArrayRef{StringRef{"getc"}}, - ArrayRef{StringRef{"fgets"}}, ArrayRef{StringRef{"read"}}, - ArrayRef{StringRef{"recv"}}}; + const CallDescriptionSet BlockingFunctions{ + {CDM::CLibrary, {"sleep"}}, + {CDM::CLibrary, {"getc"}}, + {CDM::CLibrary, {"fgets"}}, + {CDM::CLibrary, {"read"}}, + {CDM::CLibrary, {"recv"}}}; const BugType BlockInCritSectionBugType{ this, "Call to blocking function in critical section", "Blocking Error"}; @@ -291,8 +299,7 @@ void BlockInCriticalSectionChecker::handleUnlock( bool BlockInCriticalSectionChecker::isBlockingInCritSection( const CallEvent &Call, CheckerContext &C) const { - return llvm::any_of(BlockingFunctions, - [&Call](auto &&Fn) { return Fn.matches(Call); }) && + return BlockingFunctions.contains(Call) && !C.getState()->get().isEmpty(); }
[clang] [analyzer] Use explicit call description mode in more checkers (PR #90974)
=?utf-8?q?Donát?= Nagy Message-ID: In-Reply-To: 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 fc7e74e879f37301edd9450d3bbf0fec620338a6 4d3dae37544097d3000f22ecc03f63b0c182dd56 -- clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp clang/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index 290916c3c1..e138debd13 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -148,35 +148,28 @@ using MutexDescriptor = class BlockInCriticalSectionChecker : public Checker { private: const std::array MutexDescriptors{ - MemberMutexDescriptor( - {/*MatchAs=*/CDM::CXXMethod, - /*QualifiedName=*/{"std", "mutex", "lock"}, - /*RequiredArgs=*/0}, - {CDM::CXXMethod, {"std", "mutex", "unlock"}, 0}), - FirstArgMutexDescriptor( - {CDM::CLibrary, {"pthread_mutex_lock"}, 1}, - {CDM::CLibrary, {"pthread_mutex_unlock"}, 1}), - FirstArgMutexDescriptor( - {CDM::CLibrary, {"mtx_lock"}, 1}, - {CDM::CLibrary, {"mtx_unlock"}, 1}), - FirstArgMutexDescriptor( - {CDM::CLibrary, {"pthread_mutex_trylock"}, 1}, - {CDM::CLibrary, {"pthread_mutex_unlock"}, 1}), - FirstArgMutexDescriptor( - {CDM::CLibrary, {"mtx_trylock"}, 1}, - {CDM::CLibrary, {"mtx_unlock"}, 1}), - FirstArgMutexDescriptor( - {CDM::CLibrary, {"mtx_timedlock"}, 1}, - {CDM::CLibrary, {"mtx_unlock"}, 1}), + MemberMutexDescriptor({/*MatchAs=*/CDM::CXXMethod, + /*QualifiedName=*/{"std", "mutex", "lock"}, + /*RequiredArgs=*/0}, +{CDM::CXXMethod, {"std", "mutex", "unlock"}, 0}), + FirstArgMutexDescriptor({CDM::CLibrary, {"pthread_mutex_lock"}, 1}, + {CDM::CLibrary, {"pthread_mutex_unlock"}, 1}), + FirstArgMutexDescriptor({CDM::CLibrary, {"mtx_lock"}, 1}, + {CDM::CLibrary, {"mtx_unlock"}, 1}), + FirstArgMutexDescriptor({CDM::CLibrary, {"pthread_mutex_trylock"}, 1}, + {CDM::CLibrary, {"pthread_mutex_unlock"}, 1}), + FirstArgMutexDescriptor({CDM::CLibrary, {"mtx_trylock"}, 1}, + {CDM::CLibrary, {"mtx_unlock"}, 1}), + FirstArgMutexDescriptor({CDM::CLibrary, {"mtx_timedlock"}, 1}, + {CDM::CLibrary, {"mtx_unlock"}, 1}), RAIIMutexDescriptor("lock_guard"), RAIIMutexDescriptor("unique_lock")}; - const CallDescriptionSet BlockingFunctions{ - {CDM::CLibrary, {"sleep"}}, - {CDM::CLibrary, {"getc"}}, - {CDM::CLibrary, {"fgets"}}, - {CDM::CLibrary, {"read"}}, - {CDM::CLibrary, {"recv"}}}; + const CallDescriptionSet BlockingFunctions{{CDM::CLibrary, {"sleep"}}, + {CDM::CLibrary, {"getc"}}, + {CDM::CLibrary, {"fgets"}}, + {CDM::CLibrary, {"read"}}, + {CDM::CLibrary, {"recv"}}}; const BugType BlockInCritSectionBugType{ this, "Call to blocking function in critical section", "Blocking Error"}; `` https://github.com/llvm/llvm-project/pull/90974 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Use explicit call description mode in more checkers (PR #90974)
@@ -149,26 +149,34 @@ class BlockInCriticalSectionChecker : public Checker { private: const std::array MutexDescriptors{ MemberMutexDescriptor( - CallDescription(/*QualifiedName=*/{"std", "mutex", "lock"}, + CallDescription(/*MatchAs=*/CDM::CXXMethod, + /*QualifiedName=*/{"std", "mutex", "lock"}, /*RequiredArgs=*/0), NagyDonat wrote: I uploaded a commit that switches to `{...}`. Interestingly the initializer of `std::array<...> BlockingFunctions` did not work with `{...}` instead of `CallDescription(...)` -- but now that I looked at it I realized that it should be a `CallDescriptionSet` instead of a generic STL array. https://github.com/llvm/llvm-project/pull/90974 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [analyzer] Use explicit call description mode in more checkers (PR #90974)
https://github.com/NagyDonat updated https://github.com/llvm/llvm-project/pull/90974 From 9ed06c41127c88b3e2e8596ddd83b42ab2856f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Don=C3=A1t=20Nagy?= Date: Fri, 3 May 2024 16:13:19 +0200 Subject: [PATCH 1/3] [analyzer] Use explicit call description mode in more checkers This commit explicitly specifies the matching mode (C library function, any non-method function, or C++ method) for the `CallDescription`s constructed in various checkers. Some code was simplified to use `CallDescriptionSet`s instead of individual `CallDescription`s. This change won't cause major functional changes, but isn't NFC because it ensures that e.g. call descriptions for a non-method function won't accidentally match a method that has the same name. Separate commits have already performed this change in other checkers: - easy chases: e2f1cbae45f81f3cd9a4d3c2bcf69a094eb060fa - MallocChecker: d6d84b5d1448e4f2e24b467a0abcf42fe9d543e9 - iterator checkers: 06eedffe0d2782922e63cc25cb927f4acdaf7b30 - InvalidPtr checker: 024281d4d26344f9613b9115ea1fcbdbdba23235 ... and follow-up commits will handle the remaining checkers. My goal is to ensure that the call description mode is always explicitly specified and eliminate (or strongly restrict) the vague "may be either a method or a simple function" mode that's the current default. --- .../BlockInCriticalSectionChecker.cpp | 38 +++- .../Checkers/CStringChecker.cpp | 4 +- .../Checkers/InnerPointerChecker.cpp | 58 --- .../Checkers/SmartPtrModeling.cpp | 18 +++--- .../StaticAnalyzer/Checkers/StreamChecker.cpp | 8 ++- 5 files changed, 64 insertions(+), 62 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index e4373915410fb..9b612d03e93c3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -149,26 +149,34 @@ class BlockInCriticalSectionChecker : public Checker { private: const std::array MutexDescriptors{ MemberMutexDescriptor( - CallDescription(/*QualifiedName=*/{"std", "mutex", "lock"}, + CallDescription(/*MatchAs=*/CDM::CXXMethod, + /*QualifiedName=*/{"std", "mutex", "lock"}, /*RequiredArgs=*/0), - CallDescription({"std", "mutex", "unlock"}, 0)), - FirstArgMutexDescriptor(CallDescription({"pthread_mutex_lock"}, 1), - CallDescription({"pthread_mutex_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_lock"}, 1), - CallDescription({"mtx_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"pthread_mutex_trylock"}, 1), - CallDescription({"pthread_mutex_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_trylock"}, 1), - CallDescription({"mtx_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_timedlock"}, 1), - CallDescription({"mtx_unlock"}, 1)), + CallDescription(CDM::CXXMethod, {"std", "mutex", "unlock"}, 0)), + FirstArgMutexDescriptor( + CallDescription(CDM::CLibrary, {"pthread_mutex_lock"}, 1), + CallDescription(CDM::CLibrary, {"pthread_mutex_unlock"}, 1)), + FirstArgMutexDescriptor( + CallDescription(CDM::CLibrary, {"mtx_lock"}, 1), + CallDescription(CDM::CLibrary, {"mtx_unlock"}, 1)), + FirstArgMutexDescriptor( + CallDescription(CDM::CLibrary, {"pthread_mutex_trylock"}, 1), + CallDescription(CDM::CLibrary, {"pthread_mutex_unlock"}, 1)), + FirstArgMutexDescriptor( + CallDescription(CDM::CLibrary, {"mtx_trylock"}, 1), + CallDescription(CDM::CLibrary, {"mtx_unlock"}, 1)), + FirstArgMutexDescriptor( + CallDescription(CDM::CLibrary, {"mtx_timedlock"}, 1), + CallDescription(CDM::CLibrary, {"mtx_unlock"}, 1)), RAIIMutexDescriptor("lock_guard"), RAIIMutexDescriptor("unique_lock")}; const std::array BlockingFunctions{ - ArrayRef{StringRef{"sleep"}}, ArrayRef{StringRef{"getc"}}, - ArrayRef{StringRef{"fgets"}}, ArrayRef{StringRef{"read"}}, - ArrayRef{StringRef{"recv"}}}; + CallDescription(CDM::CLibrary, {"sleep"}), + CallDescription(CDM::CLibrary, {"getc"}), + CallDescription(CDM::CLibrary, {"fgets"}), + CallDescription(CDM::CLibrary, {"read"}), + CallDescription(CDM::CLibrary, {"recv"})}; const BugType BlockInCritSectionBugType{ this, "Call to blocking function in critical section", "Blocking Error"}; diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index f9548b5c3010b..238e87a712a43 100644 --- a/clang
[clang] 6d64f8e - [analyzer] Use explicit call description mode in more checkers (#90974)
Author: Donát Nagy Date: 2024-05-07T13:48:02+02:00 New Revision: 6d64f8e1feee014e72730a78b62d9d415df112ff URL: https://github.com/llvm/llvm-project/commit/6d64f8e1feee014e72730a78b62d9d415df112ff DIFF: https://github.com/llvm/llvm-project/commit/6d64f8e1feee014e72730a78b62d9d415df112ff.diff LOG: [analyzer] Use explicit call description mode in more checkers (#90974) This commit explicitly specifies the matching mode (C library function, any non-method function, or C++ method) for the `CallDescription`s constructed in various checkers. Some code was simplified to use `CallDescriptionSet`s instead of individual `CallDescription`s. This change won't cause major functional changes, but isn't NFC because it ensures that e.g. call descriptions for a non-method function won't accidentally match a method that has the same name. Separate commits have already performed this change in other checkers: - easy cases: e2f1cbae45f81f3cd9a4d3c2bcf69a094eb060fa - MallocChecker: d6d84b5d1448e4f2e24b467a0abcf42fe9d543e9 - iterator checkers: 06eedffe0d2782922e63cc25cb927f4acdaf7b30 - InvalidPtr checker: 024281d4d26344f9613b9115ea1fcbdbdba23235 ... and follow-up commits will handle the remaining checkers. My goal is to ensure that the call description mode is always explicitly specified and eliminate (or strongly restrict) the vague "may be either a method or a simple function" mode that's the current default. Added: Modified: clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp clang/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp Removed: diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index e4373915410fb2..e138debd1361ca 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -148,27 +148,28 @@ using MutexDescriptor = class BlockInCriticalSectionChecker : public Checker { private: const std::array MutexDescriptors{ - MemberMutexDescriptor( - CallDescription(/*QualifiedName=*/{"std", "mutex", "lock"}, - /*RequiredArgs=*/0), - CallDescription({"std", "mutex", "unlock"}, 0)), - FirstArgMutexDescriptor(CallDescription({"pthread_mutex_lock"}, 1), - CallDescription({"pthread_mutex_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_lock"}, 1), - CallDescription({"mtx_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"pthread_mutex_trylock"}, 1), - CallDescription({"pthread_mutex_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_trylock"}, 1), - CallDescription({"mtx_unlock"}, 1)), - FirstArgMutexDescriptor(CallDescription({"mtx_timedlock"}, 1), - CallDescription({"mtx_unlock"}, 1)), + MemberMutexDescriptor({/*MatchAs=*/CDM::CXXMethod, + /*QualifiedName=*/{"std", "mutex", "lock"}, + /*RequiredArgs=*/0}, +{CDM::CXXMethod, {"std", "mutex", "unlock"}, 0}), + FirstArgMutexDescriptor({CDM::CLibrary, {"pthread_mutex_lock"}, 1}, + {CDM::CLibrary, {"pthread_mutex_unlock"}, 1}), + FirstArgMutexDescriptor({CDM::CLibrary, {"mtx_lock"}, 1}, + {CDM::CLibrary, {"mtx_unlock"}, 1}), + FirstArgMutexDescriptor({CDM::CLibrary, {"pthread_mutex_trylock"}, 1}, + {CDM::CLibrary, {"pthread_mutex_unlock"}, 1}), + FirstArgMutexDescriptor({CDM::CLibrary, {"mtx_trylock"}, 1}, + {CDM::CLibrary, {"mtx_unlock"}, 1}), + FirstArgMutexDescriptor({CDM::CLibrary, {"mtx_timedlock"}, 1}, + {CDM::CLibrary, {"mtx_unlock"}, 1}), RAIIMutexDescriptor("lock_guard"), RAIIMutexDescriptor("unique_lock")}; - const std::array BlockingFunctions{ - ArrayRef{StringRef{"sleep"}}, ArrayRef{StringRef{"getc"}}, - ArrayRef{StringRef{"fgets"}}, ArrayRef{StringRef{"read"}}, - ArrayRef{StringRef{"recv"}}}; + const CallDescriptionSet BlockingFunctions{{CDM::CLibrary, {"sleep"}}, + {CDM::CLibrary, {"getc"}}, + {CDM::CLibrary, {"fgets"}}, + {CDM::CLibrary, {"read"}}, + {CDM::CLibrary, {"recv"}}}; const BugType BlockInCritSectionBugType{ this, "Call to blocking funct
[clang] [analyzer] Use explicit call description mode in more checkers (PR #90974)
https://github.com/NagyDonat closed https://github.com/llvm/llvm-project/pull/90974 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Add `reachedLimit()` to the `Solver` interface. (PR #91320)
https://github.com/martinboehme created https://github.com/llvm/llvm-project/pull/91320 We may want code to call this that doesn't know which specific solver implementation it is dealing with. >From bdd1d2698f3e592bf4ec33a6ff56be661ff4afb9 Mon Sep 17 00:00:00 2001 From: Martin Braenne Date: Tue, 7 May 2024 11:50:41 + Subject: [PATCH] [clang][dataflow] Add `reachedLimit()` to the `Solver` interface. We may want code to call this that doesn't know which specific solver implementation it is dealing with. --- clang/include/clang/Analysis/FlowSensitive/Solver.h| 3 +++ .../clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Analysis/FlowSensitive/Solver.h b/clang/include/clang/Analysis/FlowSensitive/Solver.h index 079f6802f241ee..6166a503ab413a 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Solver.h +++ b/clang/include/clang/Analysis/FlowSensitive/Solver.h @@ -87,6 +87,9 @@ class Solver { /// /// All elements in `Vals` must not be null. virtual Result solve(llvm::ArrayRef Vals) = 0; + + // Did the solver reach its resource limit? + virtual bool reachedLimit() const = 0; }; llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Solver::Result &); diff --git a/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h b/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h index 5448eecf6d41a2..b5cd7aa10fd7d2 100644 --- a/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h +++ b/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h @@ -48,8 +48,7 @@ class WatchedLiteralsSolver : public Solver { Result solve(llvm::ArrayRef Vals) override; - // The solver reached its maximum number of iterations. - bool reachedLimit() const { return MaxIterations == 0; } + bool reachedLimit() const override { return MaxIterations == 0; } }; } // namespace dataflow ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Add `reachedLimit()` to the `Solver` interface. (PR #91320)
llvmbot wrote: @llvm/pr-subscribers-clang-analysis Author: None (martinboehme) Changes We may want code to call this that doesn't know which specific solver implementation it is dealing with. --- Full diff: https://github.com/llvm/llvm-project/pull/91320.diff 2 Files Affected: - (modified) clang/include/clang/Analysis/FlowSensitive/Solver.h (+3) - (modified) clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h (+1-2) ``diff diff --git a/clang/include/clang/Analysis/FlowSensitive/Solver.h b/clang/include/clang/Analysis/FlowSensitive/Solver.h index 079f6802f241e..6166a503ab413 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Solver.h +++ b/clang/include/clang/Analysis/FlowSensitive/Solver.h @@ -87,6 +87,9 @@ class Solver { /// /// All elements in `Vals` must not be null. virtual Result solve(llvm::ArrayRef Vals) = 0; + + // Did the solver reach its resource limit? + virtual bool reachedLimit() const = 0; }; llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Solver::Result &); diff --git a/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h b/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h index 5448eecf6d41a..b5cd7aa10fd7d 100644 --- a/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h +++ b/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h @@ -48,8 +48,7 @@ class WatchedLiteralsSolver : public Solver { Result solve(llvm::ArrayRef Vals) override; - // The solver reached its maximum number of iterations. - bool reachedLimit() const { return MaxIterations == 0; } + bool reachedLimit() const override { return MaxIterations == 0; } }; } // namespace dataflow `` https://github.com/llvm/llvm-project/pull/91320 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Serialization] Fix instantiated default arguments (PR #76473)
https://github.com/hahnjo closed https://github.com/llvm/llvm-project/pull/76473 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [arm] Support reserving r4 and r5 alongside r9 (PR #89849)
https://github.com/smithp35 commented: There was a previous attempt at doing something similar with more global registers r6-r11 in https://reviews.llvm.org/D68862 based on http://lists.llvm.org/pipermail/llvm-dev/2018-December/128706.html This got reverted, and unfortunately didn't get picked back up. One of the comments in the description of the patch is: ``` Additionally this patch now only supports r6-r11. r4 and r5 are excluded from this patch as r4 is used as hard-coded scratch register in various parts of the ARM backend. r4 also appears to be used as an input register for a Windows asm routine (__chkstk). Similarly, the ABI of the segmented stack prologue for Android and Linux seems to use r4 and r5 as input registers. A separate patch could follow to add the support for r4 and/or r5, such that the whole range of allocatable registers (r4-r11) is available. ``` My suggestions: * Describe why R4 and R5 specifically and not R6 - R11? * If R4 and R5 are required then show that the hard-coded use in the backend is no longer there. If R4 and R5 are not required I suggest picking up the changes in https://reviews.llvm.org/D68862 * Add tests, especially if registers that have other uses in procedure call standards, or frame chains are used. * Given that the original was reverted due to interactions with r6, explain what further tests that you've made such as compiling large bodies of code or fuzz tested against programs. https://github.com/llvm/llvm-project/pull/89849 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Improve support for explicit specializations of constrained member functions & member function templates (PR #88963)
https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/88963 >From bcffb80bba2a6f9ce9eddad61b99a3e59a58f8a0 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Tue, 16 Apr 2024 13:36:11 -0400 Subject: [PATCH 1/7] [Clang][Sema] Improve support for explicit specializations of constrained member functions & member function templates --- clang/lib/Sema/SemaConcept.cpp| 2 +- clang/lib/Sema/SemaOverload.cpp | 11 ++- clang/lib/Sema/SemaTemplate.cpp | 44 +-- clang/lib/Sema/SemaTemplateInstantiate.cpp| 4 + .../CXX/temp/temp.spec/temp.expl.spec/p8.cpp | 74 +++ 5 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p8.cpp diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index e00c972602829..7bfec4e11f7aa 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -811,7 +811,7 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction( // this may happen while we're comparing two templates' constraint // equivalence. LocalInstantiationScope ScopeForParameters(S); - if (auto *FD = llvm::dyn_cast(DeclInfo.getDecl())) + if (auto *FD = DeclInfo.getDecl()->getAsFunction()) for (auto *PVD : FD->parameters()) ScopeForParameters.InstantiatedLocal(PVD, PVD); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index a416df2e97c43..5c70588bd28b8 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1303,6 +1303,8 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, if (New->isMSVCRTEntryPoint()) return false; + NamedDecl *OldDecl = Old; + NamedDecl *NewDecl = New; FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate(); FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate(); @@ -1347,6 +1349,8 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, // references to non-instantiated entities during constraint substitution. // GH78101. if (NewTemplate) { +OldDecl = OldTemplate; +NewDecl = NewTemplate; // C++ [temp.over.link]p4: // The signature of a function template consists of its function // signature, its return type and its template parameter list. The names @@ -1506,13 +1510,14 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, } } - if (!UseOverrideRules) { + if (!UseOverrideRules && + New->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) { Expr *NewRC = New->getTrailingRequiresClause(), *OldRC = Old->getTrailingRequiresClause(); if ((NewRC != nullptr) != (OldRC != nullptr)) return true; - -if (NewRC && !SemaRef.AreConstraintExpressionsEqual(Old, OldRC, New, NewRC)) +if (NewRC && +!SemaRef.AreConstraintExpressionsEqual(OldDecl, OldRC, NewDecl, NewRC)) return true; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index e647ac267ab39..eeadc47e99069 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -10354,6 +10354,25 @@ bool Sema::CheckFunctionTemplateSpecialization( return false; } +static bool IsMoreConstrainedFunction(Sema &S, FunctionDecl *FD1, + FunctionDecl *FD2) { + if (FunctionDecl *MF = FD1->getInstantiatedFromMemberFunction()) +FD1 = MF; + if (FunctionDecl *MF = FD2->getInstantiatedFromMemberFunction()) +FD2 = MF; + llvm::SmallVector AC1, AC2; + FD1->getAssociatedConstraints(AC1); + FD2->getAssociatedConstraints(AC2); + bool AtLeastAsConstrained1, AtLeastAsConstrained2; + if (S.IsAtLeastAsConstrained(FD1, AC1, FD2, AC2, AtLeastAsConstrained1)) +return false; + if (S.IsAtLeastAsConstrained(FD2, AC2, FD1, AC1, AtLeastAsConstrained2)) +return false; + if (AtLeastAsConstrained1 == AtLeastAsConstrained2) +return false; + return AtLeastAsConstrained1; +} + /// Perform semantic analysis for the given non-template member /// specialization. /// @@ -10388,15 +10407,26 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { QualType Adjusted = Function->getType(); if (!hasExplicitCallingConv(Adjusted)) Adjusted = adjustCCAndNoReturn(Adjusted, Method->getType()); +if (!Context.hasSameType(Adjusted, Method->getType())) + continue; +if (Method->getTrailingRequiresClause()) { + ConstraintSatisfaction Satisfaction; + if (CheckFunctionConstraints(Method, Satisfaction, + /*UsageLoc=*/Member->getLocation(), + /*ForOverloadResolution=*/true) || + !Satisfaction.IsSatisfied) +continue; + if (Instantiation && + !IsMoreC
[clang] [Clang][Sema] Improve support for explicit specializations of constrained member functions & member function templates (PR #88963)
https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/88963 >From 01db101ca28f26181dfedeaef1ec49a5ae42ee99 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Tue, 16 Apr 2024 13:36:11 -0400 Subject: [PATCH 1/7] [Clang][Sema] Improve support for explicit specializations of constrained member functions & member function templates --- clang/lib/Sema/SemaConcept.cpp| 2 +- clang/lib/Sema/SemaOverload.cpp | 11 ++- clang/lib/Sema/SemaTemplate.cpp | 44 +-- clang/lib/Sema/SemaTemplateInstantiate.cpp| 4 + .../CXX/temp/temp.spec/temp.expl.spec/p8.cpp | 74 +++ 5 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 clang/test/CXX/temp/temp.spec/temp.expl.spec/p8.cpp diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index e00c972602829e..7bfec4e11f7aab 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -811,7 +811,7 @@ static const Expr *SubstituteConstraintExpressionWithoutSatisfaction( // this may happen while we're comparing two templates' constraint // equivalence. LocalInstantiationScope ScopeForParameters(S); - if (auto *FD = llvm::dyn_cast(DeclInfo.getDecl())) + if (auto *FD = DeclInfo.getDecl()->getAsFunction()) for (auto *PVD : FD->parameters()) ScopeForParameters.InstantiatedLocal(PVD, PVD); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index a416df2e97c439..5c70588bd28b84 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1303,6 +1303,8 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, if (New->isMSVCRTEntryPoint()) return false; + NamedDecl *OldDecl = Old; + NamedDecl *NewDecl = New; FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate(); FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate(); @@ -1347,6 +1349,8 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, // references to non-instantiated entities during constraint substitution. // GH78101. if (NewTemplate) { +OldDecl = OldTemplate; +NewDecl = NewTemplate; // C++ [temp.over.link]p4: // The signature of a function template consists of its function // signature, its return type and its template parameter list. The names @@ -1506,13 +1510,14 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New, } } - if (!UseOverrideRules) { + if (!UseOverrideRules && + New->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) { Expr *NewRC = New->getTrailingRequiresClause(), *OldRC = Old->getTrailingRequiresClause(); if ((NewRC != nullptr) != (OldRC != nullptr)) return true; - -if (NewRC && !SemaRef.AreConstraintExpressionsEqual(Old, OldRC, New, NewRC)) +if (NewRC && +!SemaRef.AreConstraintExpressionsEqual(OldDecl, OldRC, NewDecl, NewRC)) return true; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index e647ac267ab395..eeadc47e99069c 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -10354,6 +10354,25 @@ bool Sema::CheckFunctionTemplateSpecialization( return false; } +static bool IsMoreConstrainedFunction(Sema &S, FunctionDecl *FD1, + FunctionDecl *FD2) { + if (FunctionDecl *MF = FD1->getInstantiatedFromMemberFunction()) +FD1 = MF; + if (FunctionDecl *MF = FD2->getInstantiatedFromMemberFunction()) +FD2 = MF; + llvm::SmallVector AC1, AC2; + FD1->getAssociatedConstraints(AC1); + FD2->getAssociatedConstraints(AC2); + bool AtLeastAsConstrained1, AtLeastAsConstrained2; + if (S.IsAtLeastAsConstrained(FD1, AC1, FD2, AC2, AtLeastAsConstrained1)) +return false; + if (S.IsAtLeastAsConstrained(FD2, AC2, FD1, AC1, AtLeastAsConstrained2)) +return false; + if (AtLeastAsConstrained1 == AtLeastAsConstrained2) +return false; + return AtLeastAsConstrained1; +} + /// Perform semantic analysis for the given non-template member /// specialization. /// @@ -10388,15 +10407,26 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { QualType Adjusted = Function->getType(); if (!hasExplicitCallingConv(Adjusted)) Adjusted = adjustCCAndNoReturn(Adjusted, Method->getType()); +if (!Context.hasSameType(Adjusted, Method->getType())) + continue; +if (Method->getTrailingRequiresClause()) { + ConstraintSatisfaction Satisfaction; + if (CheckFunctionConstraints(Method, Satisfaction, + /*UsageLoc=*/Member->getLocation(), + /*ForOverloadResolution=*/true) || + !Satisfaction.IsSatisfied) +continue; + if (Instantiation && + !I
[clang] [clang][dataflow] Add `reachedLimit()` to the `Solver` interface. (PR #91320)
https://github.com/ymand approved this pull request. https://github.com/llvm/llvm-project/pull/91320 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Teach .option arch to support experimental extensions. (PR #89727)
yetingk wrote: @zmodem very thank you for the help. https://github.com/llvm/llvm-project/pull/89727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. (PR #91316)
https://github.com/ymand edited https://github.com/llvm/llvm-project/pull/91316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. (PR #91316)
https://github.com/ymand approved this pull request. https://github.com/llvm/llvm-project/pull/91316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. (PR #91316)
@@ -209,6 +221,9 @@ class DataflowAnalysisContext { using DenseMapInfo::isEqual; }; + DataflowAnalysisContext(Solver &S, std::unique_ptr OwnedSolver, ymand wrote: Please add comments either here or on the fields relating S and OwnedSolver. https://github.com/llvm/llvm-project/pull/91316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. (PR #91316)
https://github.com/martinboehme updated https://github.com/llvm/llvm-project/pull/91316 >From abb7d53778394a220353deeeb86fbd06bf4352c2 Mon Sep 17 00:00:00 2001 From: Martin Braenne Date: Tue, 7 May 2024 10:23:16 + Subject: [PATCH 1/2] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. For some callers (see change in DataflowAnalysis.h), this is more convenient. --- .../Analysis/FlowSensitive/DataflowAnalysis.h | 5 ++--- .../FlowSensitive/DataflowAnalysisContext.h | 20 +-- .../FlowSensitive/DataflowAnalysisContext.cpp | 10 +- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h index 67eccdd030dcdd..763af244547647 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -283,9 +283,8 @@ llvm::Expected> diagnoseFunction( if (!Context) return Context.takeError(); - auto OwnedSolver = std::make_unique(MaxSATIterations); - const WatchedLiteralsSolver *Solver = OwnedSolver.get(); - DataflowAnalysisContext AnalysisContext(std::move(OwnedSolver)); + auto Solver = std::make_unique(MaxSATIterations); + DataflowAnalysisContext AnalysisContext(*Solver); Environment Env(AnalysisContext, FuncDecl); AnalysisT Analysis = createAnalysis(ASTCtx, Env); llvm::SmallVector Diagnostics; diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h index aa2c366cb164a9..13a74281e02b5d 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h @@ -67,7 +67,19 @@ class DataflowAnalysisContext { DataflowAnalysisContext(std::unique_ptr S, Options Opts = Options{ /*ContextSensitiveOpts=*/std::nullopt, - /*Logger=*/nullptr}); + /*Logger=*/nullptr}) + : DataflowAnalysisContext(*S, std::move(S), Opts) {} + + /// Constructs a dataflow analysis context. + /// + /// Requirements: + /// + /// `S` must outlive the `DataflowAnalysisContext`. + DataflowAnalysisContext(Solver &S, Options Opts = Options{ + /*ContextSensitiveOpts=*/std::nullopt, + /*Logger=*/nullptr}) + : DataflowAnalysisContext(S, nullptr, Opts) {} + ~DataflowAnalysisContext(); /// Sets a callback that returns the names and types of the synthetic fields @@ -209,6 +221,9 @@ class DataflowAnalysisContext { using DenseMapInfo::isEqual; }; + DataflowAnalysisContext(Solver &S, std::unique_ptr OwnedSolver, + Options Opts); + // Extends the set of modeled field declarations. void addModeledFields(const FieldSet &Fields); @@ -232,7 +247,8 @@ class DataflowAnalysisContext { Solver::Result::Status::Unsatisfiable; } - std::unique_ptr S; + Solver &S; + std::unique_ptr OwnedSolver; std::unique_ptr A; // Maps from program declarations and statements to storage locations that are diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp index e94fd39c45dc15..3041dcf6d500c5 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -170,7 +170,7 @@ DataflowAnalysisContext::joinFlowConditions(Atom FirstToken, Solver::Result DataflowAnalysisContext::querySolver( llvm::SetVector Constraints) { - return S->solve(Constraints.getArrayRef()); + return S.solve(Constraints.getArrayRef()); } bool DataflowAnalysisContext::flowConditionImplies(Atom Token, @@ -338,10 +338,10 @@ static std::unique_ptr makeLoggerFromCommandLine() { return Logger::html(std::move(StreamFactory)); } -DataflowAnalysisContext::DataflowAnalysisContext(std::unique_ptr S, - Options Opts) -: S(std::move(S)), A(std::make_unique()), Opts(Opts) { - assert(this->S != nullptr); +DataflowAnalysisContext::DataflowAnalysisContext( +Solver &S, std::unique_ptr OwnedSolver, Options Opts) +: S(S), OwnedSolver(std::move(OwnedSolver)), A(std::make_unique()), + Opts(Opts) { // If the -dataflow-log command-line flag was set, synthesize a logger. // This is ugly but provides a uniform method for ad-hoc debugging dataflow- // based tools. >From 6112536c0f400c10b919532d2b171c37d0d435ac Mon Sep 17 00:00:00 2001 From: Martin Braenne Date: Tue, 7 May 2024 12:53:16 + Subject: [PATCH 2/2] fixup! [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. --- .../clang/Analysis/Flow
[clang] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. (PR #91316)
@@ -209,6 +221,9 @@ class DataflowAnalysisContext { using DenseMapInfo::isEqual; }; + DataflowAnalysisContext(Solver &S, std::unique_ptr OwnedSolver, martinboehme wrote: Done. https://github.com/llvm/llvm-project/pull/91316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Teach .option arch to support experimental extensions. (PR #89727)
yetingk wrote: @pogo59 Thank you for the advise. I will update the test cases. https://github.com/llvm/llvm-project/pull/89727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. (PR #91316)
https://github.com/ymand approved this pull request. https://github.com/llvm/llvm-project/pull/91316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Allow `DataflowAnalysisContext` to use a non-owned `Solver`. (PR #91316)
martinboehme wrote: @ymand PTAL -- I noticed that my initial version had a use-after-move on this line: ```cxx DataflowAnalysisContext(std::unique_ptr S, Options Opts = Options{ /*ContextSensitiveOpts=*/std::nullopt, /*Logger=*/nullptr}) : DataflowAnalysisContext(*S, std::move(S), Opts) {} ``` This was because the private constructor to which this constructor delegates originally took the `std::unique_ptr` by value, and the order in which the arguments are evaluated is indeterminate. I've now changed the parameter of the private constructor to be an rvalue reference (`std::unique_ptr &&`), which resolves this issue as the move only happens inside the constructor. https://github.com/llvm/llvm-project/pull/91316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Add `reachedLimit()` to the `Solver` interface. (PR #91320)
martinboehme wrote: CI failure (DataFlowSanitizer-x86_64 :: release_shadow_space.c) looks unrelated. https://github.com/llvm/llvm-project/pull/91320 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 66364e6 - [clang][dataflow] Add `reachedLimit()` to the `Solver` interface. (#91320)
Author: martinboehme Date: 2024-05-07T14:58:57+02:00 New Revision: 66364e65405d4964709e67574abf1b519a55296c URL: https://github.com/llvm/llvm-project/commit/66364e65405d4964709e67574abf1b519a55296c DIFF: https://github.com/llvm/llvm-project/commit/66364e65405d4964709e67574abf1b519a55296c.diff LOG: [clang][dataflow] Add `reachedLimit()` to the `Solver` interface. (#91320) We may want code to call this that doesn't know which specific solver implementation it is dealing with. Added: Modified: clang/include/clang/Analysis/FlowSensitive/Solver.h clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h Removed: diff --git a/clang/include/clang/Analysis/FlowSensitive/Solver.h b/clang/include/clang/Analysis/FlowSensitive/Solver.h index 079f6802f241e..6166a503ab413 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Solver.h +++ b/clang/include/clang/Analysis/FlowSensitive/Solver.h @@ -87,6 +87,9 @@ class Solver { /// /// All elements in `Vals` must not be null. virtual Result solve(llvm::ArrayRef Vals) = 0; + + // Did the solver reach its resource limit? + virtual bool reachedLimit() const = 0; }; llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Solver::Result &); diff --git a/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h b/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h index 5448eecf6d41a..b5cd7aa10fd7d 100644 --- a/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h +++ b/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h @@ -48,8 +48,7 @@ class WatchedLiteralsSolver : public Solver { Result solve(llvm::ArrayRef Vals) override; - // The solver reached its maximum number of iterations. - bool reachedLimit() const { return MaxIterations == 0; } + bool reachedLimit() const override { return MaxIterations == 0; } }; } // namespace dataflow ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits