[clang] [llvm] [RISCV] Add riscv_atomics.h and Zawrs/Zalrsc builtins (PR #94578)

2024-06-06 Thread Pengcheng Wang via cfe-commits

https://github.com/wangpc-pp updated 
https://github.com/llvm/llvm-project/pull/94578

>From 57c914eaefa7e59aa51a2b1e730fe1b7d6d10e57 Mon Sep 17 00:00:00 2001
From: Wang Pengcheng 
Date: Thu, 6 Jun 2024 13:48:34 +0800
Subject: [PATCH 1/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.6-beta.1
---
 clang/include/clang/Basic/BuiltinsRISCV.td|  18 ++
 clang/lib/CodeGen/CGBuiltin.cpp   |  22 ++
 clang/lib/Headers/CMakeLists.txt  |   1 +
 clang/lib/Headers/riscv_atomics.h |  36 +++
 clang/lib/Sema/SemaRISCV.cpp  |  10 +-
 .../RISCV/atomics-intrinsics/zalrsc-error.c   |  13 +
 .../CodeGen/RISCV/atomics-intrinsics/zalrsc.c | 222 ++
 .../CodeGen/RISCV/atomics-intrinsics/zawrs.c  |  42 
 llvm/include/llvm/IR/IntrinsicsRISCV.td   |  32 +++
 llvm/lib/Target/RISCV/RISCVInstrInfoA.td  |  25 ++
 llvm/lib/Target/RISCV/RISCVInstrInfoZa.td |   5 +-
 llvm/test/CodeGen/RISCV/zalrsc-rv32.ll|  74 ++
 llvm/test/CodeGen/RISCV/zalrsc-rv64.ll|  74 ++
 llvm/test/CodeGen/RISCV/zawrs.ll  |  33 +++
 14 files changed, 605 insertions(+), 2 deletions(-)
 create mode 100644 clang/lib/Headers/riscv_atomics.h
 create mode 100644 clang/test/CodeGen/RISCV/atomics-intrinsics/zalrsc-error.c
 create mode 100644 clang/test/CodeGen/RISCV/atomics-intrinsics/zalrsc.c
 create mode 100644 clang/test/CodeGen/RISCV/atomics-intrinsics/zawrs.c
 create mode 100644 llvm/test/CodeGen/RISCV/zalrsc-rv32.ll
 create mode 100644 llvm/test/CodeGen/RISCV/zalrsc-rv64.ll
 create mode 100644 llvm/test/CodeGen/RISCV/zawrs.ll

diff --git a/clang/include/clang/Basic/BuiltinsRISCV.td 
b/clang/include/clang/Basic/BuiltinsRISCV.td
index 4cc89a8a9d8af..458c755179417 100644
--- a/clang/include/clang/Basic/BuiltinsRISCV.td
+++ b/clang/include/clang/Basic/BuiltinsRISCV.td
@@ -146,3 +146,21 @@ let Features = "zihintntl", Attributes = 
[CustomTypeChecking] in {
 def ntl_load : RISCVBuiltin<"void(...)">;
 def ntl_store : RISCVBuiltin<"void(...)">;
 } // Features = "zihintntl", Attributes = [CustomTypeChecking]
+
+//===--===//
+// Zawrs extension.
+//===--===//
+let Features = "zawrs" in {
+def wrs_nto : RISCVBuiltin<"void()">;
+def wrs_sto : RISCVBuiltin<"void()">;
+} // Features = "zawrs"
+
+//===--===//
+// Zalrsc extension.
+//===--===//
+let Features = "zalrsc" in {
+def lr_w : RISCVBuiltin<"int(int *, _Constant unsigned int)">;
+def lr_d : RISCVBuiltin<"int64_t(int64_t *, _Constant unsigned int)">;
+def sc_w : RISCVBuiltin<"int(int, int *, _Constant unsigned int)">;
+def sc_d : RISCVBuiltin<"int64_t(int64_t, int64_t *, _Constant unsigned int)">;
+} // Features = "zalrsc"
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 37d0c478e0330..db48c69e10c86 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -21769,6 +21769,28 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned 
BuiltinID,
 ID = Intrinsic::riscv_sm3p1;
 break;
 
+  // Zawrs
+  case RISCV::BI__builtin_riscv_wrs_nto:
+ID = Intrinsic::riscv_wrs_nto;
+break;
+  case RISCV::BI__builtin_riscv_wrs_sto:
+ID = Intrinsic::riscv_wrs_sto;
+break;
+
+  // Zalrsc
+  case RISCV::BI__builtin_riscv_lr_w:
+ID = Intrinsic::riscv_lr_w;
+break;
+  case RISCV::BI__builtin_riscv_lr_d:
+ID = Intrinsic::riscv_lr_d;
+break;
+  case RISCV::BI__builtin_riscv_sc_w:
+ID = Intrinsic::riscv_sc_w;
+break;
+  case RISCV::BI__builtin_riscv_sc_d:
+ID = Intrinsic::riscv_sc_d;
+break;
+
   // Zihintntl
   case RISCV::BI__builtin_riscv_ntl_load: {
 llvm::Type *ResTy = ConvertType(E->getType());
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index d3090e488306f..cf2fbf1893772 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -118,6 +118,7 @@ set(ppc_htm_files
   )
 
 set(riscv_files
+  riscv_atomics.h
   riscv_bitmanip.h
   riscv_crypto.h
   riscv_ntlh.h
diff --git a/clang/lib/Headers/riscv_atomics.h 
b/clang/lib/Headers/riscv_atomics.h
new file mode 100644
index 0..35db57fe36131
--- /dev/null
+++ b/clang/lib/Headers/riscv_atomics.h
@@ -0,0 +1,36 @@
+/*=== riscv_atomics.h - RISC-V atomics intrinsics --===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===--

[clang] [llvm] [clang] Reland Add tanf16 builtin and support for tan constrained intrinsic (PR #94559)

2024-06-06 Thread Farzon Lotfi via cfe-commits

https://github.com/farzonl edited 
https://github.com/llvm/llvm-project/pull/94559
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] NFCI: Make ASTContext optional in the AST text dumper again (PR #94522)

2024-06-06 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr approved this pull request.

Can't say much about this functionally, but it fixes my problems, so LGTM from 
that side.

https://github.com/llvm/llvm-project/pull/94522
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] CWG2749: relational operators involving pointers to void (PR #93046)

2024-06-06 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr approved this pull request.

LGTM.

I guess we should close https://github.com/llvm/llvm-project/pull/89449 after 
merging this.

https://github.com/llvm/llvm-project/pull/93046
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] fb0c705 - [clang] NFCI: Make ASTContext optional in the AST text dumper again (#94522)

2024-06-06 Thread via cfe-commits

Author: Matheus Izvekov
Date: 2024-06-06T04:14:10-03:00
New Revision: fb0c705dbf27e3ab84d726ad30e172806a530c21

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

LOG: [clang] NFCI: Make ASTContext optional in the AST text dumper again 
(#94522)

Added: 


Modified: 
clang/lib/AST/TextNodeDumper.cpp
clang/lib/AST/Type.cpp

Removed: 




diff  --git a/clang/lib/AST/TextNodeDumper.cpp 
b/clang/lib/AST/TextNodeDumper.cpp
index 8bacceea0f22b..1076dcd40a694 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -958,6 +958,9 @@ void TextNodeDumper::dumpTemplateArgument(const 
TemplateArgument &TA) {
   }
   OS << " '" << Str << "'";
 
+  if (!Context)
+return;
+
   if (TemplateArgument CanonTA = Context->getCanonicalTemplateArgument(TA);
   !CanonTA.structurallyEquals(TA)) {
 llvm::SmallString<128> CanonStr;
@@ -1139,15 +1142,17 @@ void TextNodeDumper::dumpTemplateName(TemplateName TN, 
StringRef Label) {
   }
   OS << " '" << Str << "'";
 
-  if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN);
-  CanonTN != TN) {
-llvm::SmallString<128> CanonStr;
-{
-  llvm::raw_svector_ostream SS(CanonStr);
-  CanonTN.print(SS, PrintPolicy);
+  if (Context) {
+if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN);
+CanonTN != TN) {
+  llvm::SmallString<128> CanonStr;
+  {
+llvm::raw_svector_ostream SS(CanonStr);
+CanonTN.print(SS, PrintPolicy);
+  }
+  if (CanonStr != Str)
+OS << ":'" << CanonStr << "'";
 }
-if (CanonStr != Str)
-  OS << ":'" << CanonStr << "'";
   }
 }
 dumpBareTemplateName(TN);

diff  --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 3f88c3441eaf6..33acae2cbafac 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -4481,7 +4481,6 @@ static CachedProperties computeCachedProperties(const 
Type *T) {
 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class,Base) case Type::Class:
 #include "clang/AST/TypeNodes.inc"
 // Treat instantiation-dependent types as external.
-if (!T->isInstantiationDependentType()) T->dump();
 assert(T->isInstantiationDependentType());
 return CachedProperties(Linkage::External, false);
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] NFCI: Make ASTContext optional in the AST text dumper again (PR #94522)

2024-06-06 Thread Matheus Izvekov via cfe-commits

https://github.com/mizvekov closed 
https://github.com/llvm/llvm-project/pull/94522
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [PowerPC] Support -mno-red-zone option (PR #94581)

2024-06-06 Thread Chen Zheng via cfe-commits

https://github.com/chenzheng1030 commented:

Are there backend cases that shows with -disable-red-zone, the final assembly 
is still correct?

https://github.com/llvm/llvm-project/pull/94581
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [PowerPC] Support -mno-red-zone option (PR #94581)

2024-06-06 Thread Chen Zheng via cfe-commits

https://github.com/chenzheng1030 edited 
https://github.com/llvm/llvm-project/pull/94581
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [AArch64] Decouple feature dependency expansion. (PR #94279)

2024-06-06 Thread Alexandros Lamprineas via cfe-commits

labrinea wrote:

> Not supporting "neon" as a name would seem like a mistake if it was removed, 
> but I don't believe this patch does that.

It does 

https://github.com/llvm/llvm-project/pull/94279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Refine invalidation caused by `fread` (PR #93408)

2024-06-06 Thread Balazs Benics via cfe-commits


@@ -907,6 +945,73 @@ void StreamChecker::preWrite(const FnDescription *Desc, 
const CallEvent &Call,
   C.addTransition(State);
 }
 
+static std::optional getPointeeType(const MemRegion *R) {
+  if (!R)
+return std::nullopt;
+  if (const auto *ER = dyn_cast(R))
+return ER->getElementType();
+  if (const auto *TR = dyn_cast(R))
+return TR->getValueType();
+  if (const auto *SR = dyn_cast(R))
+return SR->getPointeeStaticType();
+  return std::nullopt;
+}
+
+static std::optional getStartIndex(SValBuilder &SVB,
+   const MemRegion *R) {
+  if (!R)
+return std::nullopt;
+
+  auto Zero = [&SVB] {
+BasicValueFactory &BVF = SVB.getBasicValueFactory();
+return nonloc::ConcreteInt(BVF.getIntValue(0, /*isUnsigned=*/false));
+  };

steakhal wrote:

This way it's lazily evaluated.

https://github.com/llvm/llvm-project/pull/93408
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Refine invalidation caused by `fread` (PR #93408)

2024-06-06 Thread Balazs Benics via cfe-commits


@@ -0,0 +1,412 @@
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -triple x86_64-linux-gnu  \
+// RUN:   -analyzer-checker=core,unix.Stream,alpha.security.taint \
+// RUN:   -analyzer-checker=debug.ExprInspection
+
+#include "Inputs/system-header-simulator-for-simple-stream.h"
+
+#define EOF (-1)
+
+void clang_analyzer_dump(int);
+void clang_analyzer_isTainted(int);
+void clang_analyzer_warnIfReached(void);
+
+// A stream is only tracked by StreamChecker if it results from a call to 
"fopen".
+// Otherwise, there is no specific modelling of "fread".
+void untracked_stream(FILE *fp) {
+  char c;
+  if (1 == fread(&c, 1, 1, fp)) {
+char p = c; // Unknown value but not garbage and not modeled by checker.
+  } else {
+char p = c; // Possibly indeterminate value but not modeled by checker.
+  }
+}
+
+void fgetc_props_taint(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+int c = fgetc(fp); // c is tainted.
+if (c != EOF) {
+  clang_analyzer_isTainted(c); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void fread_props_taint(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+char buffer[10];
+int c = fread(buffer, 1, 10, fp); // c is tainted.
+if (c != 10) {
+  // If the read failed, then the number of bytes successfully read should 
be tainted.
+  clang_analyzer_isTainted(c); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte1(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+char c;
+if (1 == fread(&c, 1, 1, fp)) {
+  char p = c; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = c; // Possibly indeterminate value but not modeled by checker.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte2(char *buffer) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+if (1 == fread(buffer, 1, 1, fp)) {
+  char p = buffer[0]; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = buffer[0]; // Possibly indeterminate value but not modeled by 
checker.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte3(char *buffer) {
+  buffer[1] = 10;
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+// buffer[1] is not mutated by fread and remains not tainted.
+fread(buffer, 1, 1, fp);
+char p = buffer[1];
+clang_analyzer_isTainted(p); // expected-warning{{NO}}
+clang_analyzer_dump(buffer[1]); // expected-warning{{10 S32b}}
+fclose(fp);
+  }
+}
+
+void read_many_bytes(char *buffer) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+if (42 == fread(buffer, 1, 42, fp)) {
+  char p = buffer[0]; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = buffer[0]; // Possibly indeterminate value but not modeled.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void random_access_write1(int index) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+long c[4];
+int success = 2 == fread(c + 1, sizeof(long), 2, fp);
+
+switch (index) {
+case 0:
+  // c[0] is not mutated by fread.
+  if (success) {
+char p = c[0]; // expected-warning {{Assigned value is garbage or 
undefined}} We kept the first byte intact.
+  } else {
+char p = c[0]; // expected-warning {{Assigned value is garbage or 
undefined}} We kept the first byte intact.
+  }
+  break;
+
+case 1:
+  if (success) {
+// Unknown value but not garbage.
+clang_analyzer_isTainted(c[1]); // expected-warning {{YES}}
+clang_analyzer_dump(c[1]); // expected-warning {{conj_}}
+  } else {
+// Possibly indeterminate value but not modeled.
+clang_analyzer_isTainted(c[1]); // expected-warning {{YES}}
+clang_analyzer_dump(c[1]); // expected-warning {{conj_}}
+  }
+  break;
+
+case 2:
+  if (success) {
+long p = c[2]; // Unknown value but not garbage.
+// FIXME: Taint analysis only marks the first byte of a memory region. 
See getPointeeOf in GenericTaintChecker.cpp.
+clang_analyzer_isTainted(c[2]); // expected-warning {{NO}}
+clang_analyzer_dump(c[2]); // expected-warning {{conj_}}
+  } else {
+// Possibly indeterminate value but not modeled.
+clang_analyzer_isTainted(c[2]); // expected-warning {{NO}} // FIXME: 
See above.
+clang_analyzer_dump(c[2]); // expected-warning {{conj_}}
+  }
+  break;
+
+case 3:
+  // c[3] is not mutated by fread.
+  if (success) {
+long p = c[3]; // expected-warning {{Assigned value is garbage or 
undefined}}
+  } else {
+long p = c[3]; // ex

[clang] [PowerPC] Support -mno-red-zone option (PR #94581)

2024-06-06 Thread Qiu Chaofan via cfe-commits

ecnelises wrote:

No. `-disable-red-zone` does nothing but add `noredzone` IR attribute to 
functions. We need to add cases to test for `noredzone` behavior on PPC (arm 
and x86 have).

https://github.com/llvm/llvm-project/pull/94581
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Refine invalidation caused by `fread` (PR #93408)

2024-06-06 Thread Balazs Benics via cfe-commits

https://github.com/steakhal edited 
https://github.com/llvm/llvm-project/pull/93408
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Support [[guarded_by(mutex)]] attribute inside C struct (PR #94216)

2024-06-06 Thread Pierre d'Herbemont via cfe-commits

pdherbemont wrote:

> LGTM assuming you will be fixing the buildkite failures.
> 
> You may still need to wait on @AaronBallman's approval.

Fixed the buildkite issue – they were regression from the latest changes about 
acquired_{before,after} handling. Also pinged @AaronBallman. Thank you all for 
the feedback!

https://github.com/llvm/llvm-project/pull/94216
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-format] add an option to insert a space only for non-code block empty braces, not for empty parentheses (PR #93634)

2024-06-06 Thread Kohei Asano via cfe-commits

https://github.com/khei4 updated https://github.com/llvm/llvm-project/pull/93634

>From 4cdd7bd2a916740f886939d1ec0395b5915eb3c2 Mon Sep 17 00:00:00 2001
From: Kohei Asano 
Date: Mon, 3 Jun 2024 09:15:44 +0900
Subject: [PATCH 1/2] [clang-format] add an option to insert a space only for
 empty braces

---
 clang/docs/ClangFormatStyleOptions.rst  |  97 -
 clang/include/clang/Format/Format.h | 112 ++--
 clang/lib/Format/Format.cpp |  40 ++-
 clang/lib/Format/TokenAnnotator.cpp |  18 +++-
 clang/lib/Format/UnwrappedLineFormatter.cpp |  13 ++-
 clang/unittests/Format/ConfigParseTest.cpp  |   9 +-
 clang/unittests/Format/FormatTest.cpp   |  99 -
 7 files changed, 368 insertions(+), 20 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index bb00c20922d36..9879d122f8d57 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -6036,12 +6036,103 @@ the configuration (without a prefix: ``Auto``).
 
 **SpaceInEmptyBlock** (``Boolean``) :versionbadge:`clang-format 10` :ref:`¶ 
`
   If ``true``, spaces will be inserted into ``{}``.
+  This option is **deprecated**. The previous behavior is preserved by using
+  ``SpaceInEmptyBraces`` with ``Custom`` and by setting ``Block`` in
+  ``SpaceInEmptyBracesOptions`` to ``true``.
+
+.. _SpaceInEmptyBraces:
+
+**SpaceInEmptyBraces** (``SpaceInEmptyBracesStyle``) 
:versionbadge:`clang-format 19` :ref:`¶ `
+  Defines in which cases spaces will be inserted in empty braces.
+
+  Possible values:
+
+  * ``SIEBO_Never`` (in configuration: ``Never``)
+Never put a space in empty braces.
+
+.. code-block:: c++
+
+   void f() {}
+   T x{};
+   while (true) {}
+   struct U1 {};
+   union U2 {};
+   class U3 {};
+   enum U4 {};
+
+  * ``SIEBO_Custom`` (in configuration: ``Custom``)
+Configure each individual space in empty braces in
+`SpacesInEmptyBracesOptions`.
+
+
+
+.. _SpaceInEmptyBracesOptions:
+
+**SpaceInEmptyBracesOptions** (``SpaceInEmptyBracesCustom``) 
:versionbadge:`clang-format 19` :ref:`¶ `
+  Control of individual spaces in empty braces.
+
+  If ``SpaceInEmptyBraces`` is set to ``Custom``, use this to specify
+  how each individual space in empty braces case should be handled.
+  Otherwise, this is ignored.
+
+  .. code-block:: yaml
+
+# Example of usage:
+SpaceInEmptyBraces: Custom
+SpaceInEmptyBracesOptions:
+  Function: true
+  Record: false
+  InitList: true
+  Block: false
+
+  Nested configuration flags:
+
+  Precise control over the spacing in empty braces.
 
   .. code-block:: c++
 
- true:false:
- void f() { }   vs.   void f() {}
- while (true) { } while (true) {}
+# Should be declared this way:
+SpaceInEmptyBraces: Custom
+SpaceInEmptyBracesOptions:
+  Function: true
+  Record: false
+  InitList: true
+  Block: false
+
+  * ``bool Function`` Put a space in empty braces of function definition.
+
+.. code-block:: c++
+
+   true:  false:
+   void f() { }   vs. void f() {}
+
+  * ``bool Record`` Put a space in empty braces of record/struct definition.
+
+.. code-block:: c++
+
+   true:  false:
+   struct U1 { }; vs. struct U1 {};
+   union U2 { };  union U2 {};
+   class U3 { };  class U3 {};
+   enum U4 { };   enum U4 {};
+
+  * ``bool InitList`` Put a space in empty braces of initializer list.
+
+.. code-block:: c++
+
+   true:  false:
+   T x{ };vs. T x{};
+
+  * ``bool Block`` Put a space in empty braces of other blocks, including 
functions and
+record, compatible with ``SpaceInEmptyBlock``.
+
+.. code-block:: c++
+
+   true:  false:
+   void f() { }   vs. void f() {}
+   enum Unit { }; enum Unit {};
+   while (true) { }   while (true) {}
+
 
 .. _SpaceInEmptyParentheses:
 
diff --git a/clang/include/clang/Format/Format.h 
b/clang/include/clang/Format/Format.h
index 4fd6e013df25b..a6d8700ad9aa3 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -4493,13 +4493,11 @@ struct FormatStyle {
   bool SpaceBeforeRangeBasedForLoopColon;
 
   /// If ``true``, spaces will be inserted into ``{}``.
-  /// \code
-  ///true:false:
-  ///void f() { }   vs.   void f() {}
-  ///while (true) { } while (true) {}
-  /// \endcode
+  /// This option is **deprecated**. The previous behavior is preserved

[clang] [analyzer] Refine invalidation caused by `fread` (PR #93408)

2024-06-06 Thread Balazs Benics via cfe-commits


@@ -0,0 +1,412 @@
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -triple x86_64-linux-gnu  \
+// RUN:   -analyzer-checker=core,unix.Stream,alpha.security.taint \
+// RUN:   -analyzer-checker=debug.ExprInspection
+
+#include "Inputs/system-header-simulator-for-simple-stream.h"
+
+#define EOF (-1)
+
+void clang_analyzer_dump(int);
+void clang_analyzer_isTainted(int);
+void clang_analyzer_warnIfReached(void);
+
+// A stream is only tracked by StreamChecker if it results from a call to 
"fopen".
+// Otherwise, there is no specific modelling of "fread".
+void untracked_stream(FILE *fp) {
+  char c;
+  if (1 == fread(&c, 1, 1, fp)) {
+char p = c; // Unknown value but not garbage and not modeled by checker.
+  } else {
+char p = c; // Possibly indeterminate value but not modeled by checker.
+  }
+}
+
+void fgetc_props_taint(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+int c = fgetc(fp); // c is tainted.
+if (c != EOF) {
+  clang_analyzer_isTainted(c); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void fread_props_taint(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+char buffer[10];
+int c = fread(buffer, 1, 10, fp); // c is tainted.
+if (c != 10) {
+  // If the read failed, then the number of bytes successfully read should 
be tainted.
+  clang_analyzer_isTainted(c); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte1(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+char c;
+if (1 == fread(&c, 1, 1, fp)) {
+  char p = c; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = c; // Possibly indeterminate value but not modeled by checker.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte2(char *buffer) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+if (1 == fread(buffer, 1, 1, fp)) {
+  char p = buffer[0]; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = buffer[0]; // Possibly indeterminate value but not modeled by 
checker.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte3(char *buffer) {
+  buffer[1] = 10;
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+// buffer[1] is not mutated by fread and remains not tainted.
+fread(buffer, 1, 1, fp);
+char p = buffer[1];
+clang_analyzer_isTainted(p); // expected-warning{{NO}}
+clang_analyzer_dump(buffer[1]); // expected-warning{{10 S32b}}
+fclose(fp);
+  }
+}
+
+void read_many_bytes(char *buffer) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+if (42 == fread(buffer, 1, 42, fp)) {
+  char p = buffer[0]; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = buffer[0]; // Possibly indeterminate value but not modeled.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void random_access_write1(int index) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+long c[4];
+int success = 2 == fread(c + 1, sizeof(long), 2, fp);
+
+switch (index) {
+case 0:
+  // c[0] is not mutated by fread.
+  if (success) {
+char p = c[0]; // expected-warning {{Assigned value is garbage or 
undefined}} We kept the first byte intact.
+  } else {
+char p = c[0]; // expected-warning {{Assigned value is garbage or 
undefined}} We kept the first byte intact.
+  }
+  break;
+
+case 1:
+  if (success) {
+// Unknown value but not garbage.
+clang_analyzer_isTainted(c[1]); // expected-warning {{YES}}
+clang_analyzer_dump(c[1]); // expected-warning {{conj_}}
+  } else {
+// Possibly indeterminate value but not modeled.
+clang_analyzer_isTainted(c[1]); // expected-warning {{YES}}
+clang_analyzer_dump(c[1]); // expected-warning {{conj_}}
+  }
+  break;
+
+case 2:
+  if (success) {
+long p = c[2]; // Unknown value but not garbage.
+// FIXME: Taint analysis only marks the first byte of a memory region. 
See getPointeeOf in GenericTaintChecker.cpp.
+clang_analyzer_isTainted(c[2]); // expected-warning {{NO}}
+clang_analyzer_dump(c[2]); // expected-warning {{conj_}}
+  } else {
+// Possibly indeterminate value but not modeled.
+clang_analyzer_isTainted(c[2]); // expected-warning {{NO}} // FIXME: 
See above.
+clang_analyzer_dump(c[2]); // expected-warning {{conj_}}
+  }
+  break;
+
+case 3:
+  // c[3] is not mutated by fread.
+  if (success) {
+long p = c[3]; // expected-warning {{Assigned value is garbage or 
undefined}}
+  } else {
+long p = c[3]; // ex

[clang] [analyzer] Factor out NoOwnershipChangeVisitor (PR #94357)

2024-06-06 Thread Kristóf Umann via cfe-commits

Szelethus wrote:

Yes, it is, sorry about that :) 

https://github.com/llvm/llvm-project/pull/94357
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer][NFC] Factor out NoOwnershipChangeVisitor (PR #94357)

2024-06-06 Thread Kristóf Umann via cfe-commits

https://github.com/Szelethus edited 
https://github.com/llvm/llvm-project/pull/94357
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Refine invalidation caused by `fread` (PR #93408)

2024-06-06 Thread Balazs Benics via cfe-commits


@@ -0,0 +1,412 @@
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -triple x86_64-linux-gnu  \
+// RUN:   -analyzer-checker=core,unix.Stream,alpha.security.taint \
+// RUN:   -analyzer-checker=debug.ExprInspection
+
+#include "Inputs/system-header-simulator-for-simple-stream.h"
+
+#define EOF (-1)
+
+void clang_analyzer_dump(int);
+void clang_analyzer_isTainted(int);
+void clang_analyzer_warnIfReached(void);
+
+// A stream is only tracked by StreamChecker if it results from a call to 
"fopen".
+// Otherwise, there is no specific modelling of "fread".
+void untracked_stream(FILE *fp) {
+  char c;
+  if (1 == fread(&c, 1, 1, fp)) {
+char p = c; // Unknown value but not garbage and not modeled by checker.
+  } else {
+char p = c; // Possibly indeterminate value but not modeled by checker.
+  }
+}
+
+void fgetc_props_taint(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+int c = fgetc(fp); // c is tainted.
+if (c != EOF) {
+  clang_analyzer_isTainted(c); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void fread_props_taint(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+char buffer[10];
+int c = fread(buffer, 1, 10, fp); // c is tainted.
+if (c != 10) {
+  // If the read failed, then the number of bytes successfully read should 
be tainted.
+  clang_analyzer_isTainted(c); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte1(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+char c;
+if (1 == fread(&c, 1, 1, fp)) {
+  char p = c; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = c; // Possibly indeterminate value but not modeled by checker.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte2(char *buffer) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+if (1 == fread(buffer, 1, 1, fp)) {
+  char p = buffer[0]; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = buffer[0]; // Possibly indeterminate value but not modeled by 
checker.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte3(char *buffer) {
+  buffer[1] = 10;
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+// buffer[1] is not mutated by fread and remains not tainted.
+fread(buffer, 1, 1, fp);
+char p = buffer[1];
+clang_analyzer_isTainted(p); // expected-warning{{NO}}
+clang_analyzer_dump(buffer[1]); // expected-warning{{10 S32b}}
+fclose(fp);
+  }
+}
+
+void read_many_bytes(char *buffer) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+if (42 == fread(buffer, 1, 42, fp)) {
+  char p = buffer[0]; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = buffer[0]; // Possibly indeterminate value but not modeled.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void random_access_write1(int index) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+long c[4];
+int success = 2 == fread(c + 1, sizeof(long), 2, fp);
+
+switch (index) {
+case 0:
+  // c[0] is not mutated by fread.
+  if (success) {
+char p = c[0]; // expected-warning {{Assigned value is garbage or 
undefined}} We kept the first byte intact.
+  } else {
+char p = c[0]; // expected-warning {{Assigned value is garbage or 
undefined}} We kept the first byte intact.
+  }
+  break;
+
+case 1:
+  if (success) {
+// Unknown value but not garbage.
+clang_analyzer_isTainted(c[1]); // expected-warning {{YES}}
+clang_analyzer_dump(c[1]); // expected-warning {{conj_}}
+  } else {
+// Possibly indeterminate value but not modeled.
+clang_analyzer_isTainted(c[1]); // expected-warning {{YES}}
+clang_analyzer_dump(c[1]); // expected-warning {{conj_}}
+  }
+  break;
+
+case 2:
+  if (success) {
+long p = c[2]; // Unknown value but not garbage.
+// FIXME: Taint analysis only marks the first byte of a memory region. 
See getPointeeOf in GenericTaintChecker.cpp.
+clang_analyzer_isTainted(c[2]); // expected-warning {{NO}}
+clang_analyzer_dump(c[2]); // expected-warning {{conj_}}
+  } else {
+// Possibly indeterminate value but not modeled.
+clang_analyzer_isTainted(c[2]); // expected-warning {{NO}} // FIXME: 
See above.
+clang_analyzer_dump(c[2]); // expected-warning {{conj_}}
+  }
+  break;
+
+case 3:
+  // c[3] is not mutated by fread.
+  if (success) {
+long p = c[3]; // expected-warning {{Assigned value is garbage or 
undefined}}
+  } else {
+long p = c[3]; // ex

[clang] [llvm] [clang][SPIR-V] Add support for AMDGCN flavoured SPIRV (PR #89796)

2024-06-06 Thread Vyacheslav Levytskyy via cfe-commits


@@ -114,15 +118,17 @@ Example:
 
 ``-target spirv64v1.0`` can be used to compile for SPIR-V version 1.0 with 
64-bit pointer width.
 
+``-target spirv64-amd-amdhsa`` can be used to compile for AMDGCN flavoured 
SPIR-V version 1.6 with 64-bit pointer width

VyacheslavLevytskyy wrote:

I'm not sure how the number of the version 1.6 will be deducted from just 
`spirv64-amd-amdhsa`.

https://github.com/llvm/llvm-project/pull/89796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] `doesNotMutateObject`: Handle calls to member functions … (PR #94362)

2024-06-06 Thread Clement Courbet via cfe-commits


@@ -36,6 +36,111 @@ void extractNodesByIdTo(ArrayRef Matches, 
StringRef ID,
 Nodes.insert(Match.getNodeAs(ID));
 }
 
+// If `D` has a const-qualified overload with otherwise identical
+// ref-qualifiers, returns that overload.
+const CXXMethodDecl *findConstOverload(const CXXMethodDecl &D) {
+  assert(!D.isConst());
+
+  DeclContext::lookup_result lookup_result =
+  D.getParent()->lookup(D.getNameInfo().getName());
+  if (lookup_result.isSingleResult()) {
+// No overload.
+return nullptr;
+  }
+  for (const Decl *overload : lookup_result) {
+const CXXMethodDecl *candidate = dyn_cast(overload);
+if (candidate && !candidate->isDeleted() && candidate->isConst() &&
+candidate->getRefQualifier() == D.getRefQualifier()) {
+  return candidate;
+}
+  }
+  return nullptr;
+}
+
+// Returns true if both types refer to the same to the same type,
+// ignoring the const-qualifier.
+bool isSameTypeIgnoringConst(QualType A, QualType B) {
+  A = A.getCanonicalType();
+  B = B.getCanonicalType();
+  A.addConst();
+  B.addConst();
+  return A == B;
+}
+
+// Returns true if both types are pointers or reference to the same type,
+// ignoring the const-qualifier.
+bool pointsToSameTypeIgnoringConst(QualType A, QualType B) {
+  assert(A->isPointerType() || A->isReferenceType());
+  assert(B->isPointerType() || B->isReferenceType());
+  return isSameTypeIgnoringConst(A->getPointeeType(), B->getPointeeType());
+}
+
+// Return true if non-const member function `M` likely does not mutate `*this`.
+//
+// Note that if the member call selects a method/operator `f` that
+// is not const-qualified, then we also consider that the object is
+// not mutated if:
+//  - (A) there is a const-qualified overload `cf` of `f` that has
+//  the
+//same ref-qualifiers;
+//  - (B) * `f` returns a value, or
+//* if `f` returns a `T&`, `cf` returns a `const T&` (up to
+//  possible aliases such as `reference` and
+//  `const_reference`), or
+//* if `f` returns a `T*`, `cf` returns a `const T*` (up to
+//  possible aliases).
+//  - (C) the result of the call is not mutated.
+//
+// The assumption that `cf` has the same semantics as `f`.
+// For example:
+//   - In `std::vector v; const T t = v[...];`, we consider that
+// expression `v[...]` does not mutate `v` as
+//`T& std::vector::operator[]` has a const overload
+// `const T& std::vector::operator[] const`, and the
+// result expression of type `T&` is only used as a `const T&`;
+//   - In `std::map m; V v = m.at(...);`, we consider
+// `m.at(...)` to be an immutable access for the same reason.
+// However:
+//   - In `std::map m; const V v = m[...];`, We consider that
+// `m[...]` mutates `m` as `V& std::map::operator[]` does
+// not have a const overload.
+//   - In `std::vector v; T& t = v[...];`, we consider that
+// expression `v[...]` mutates `v` as the result is kept as a
+// mutable reference.
+//
+// This function checks (A) ad (B), but the caller should make sure that the
+// object is not mutated through the return value.
+bool isLikelyShallowConst(const CXXMethodDecl &M) {
+  assert(!M.isConst());
+  // The method can mutate our variable.
+
+  // (A)
+  const CXXMethodDecl *ConstOverload = findConstOverload(M);
+  if (ConstOverload == nullptr) {
+return false;
+  }
+
+  // (B)
+  const QualType CallTy = M.getReturnType().getCanonicalType();
+  const QualType OverloadTy = 
ConstOverload->getReturnType().getCanonicalType();
+  if (CallTy->isReferenceType()) {
+if (!(OverloadTy->isReferenceType() &&
+  pointsToSameTypeIgnoringConst(CallTy, OverloadTy))) {
+  return false;
+}

legrosbuffle wrote:

Much clearer, thanks.

https://github.com/llvm/llvm-project/pull/94362
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang][SPIR-V] Add support for AMDGCN flavoured SPIRV (PR #89796)

2024-06-06 Thread Vyacheslav Levytskyy via cfe-commits


@@ -0,0 +1,35 @@
+; RUN: llc -O0 -mtriple=spirv64-amd-amdhsa 
--spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s
+; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-amd-amdhsa %s -o - 
-filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpCapability Int8
+; CHECK-DAG: OpCapability GenericPointer
+; CHECK-DAG: OpCapability FunctionPointersINTEL
+; CHECK-DAG: OpCapability Int64
+; CHECK: OpExtension "SPV_INTEL_function_pointers"
+; CHECK-DAG: %[[TyInt8:.*]] = OpTypeInt 8 0
+; CHECK-DAG: %[[TyVoid:.*]] = OpTypeVoid
+; CHECK-DAG: %[[TyInt64:.*]] = OpTypeInt 64 0
+; CHECK-DAG: %[[TyFunFp:.*]] = OpTypeFunction %[[TyVoid]] %[[TyInt64]]
+; CHECK-DAG: %[[ConstInt64:.*]] = OpConstant %[[TyInt64]] 42
+; CHECK-DAG: %[[TyPtrFunFp:.*]] = OpTypePointer Generic %[[TyFunFp]]
+; CHECK-DAG: %[[ConstFunFp:.*]] = OpConstantFunctionPointerINTEL 
%[[TyPtrFunFp]] %[[DefFunFp:.*]]
+; CHECK: %[[FunPtr1:.*]] = OpBitcast %[[#]] %[[ConstFunFp]]
+; CHECK: %[[FunPtr2:.*]] = OpLoad %[[#]] %[[FunPtr1]]
+; CHECK: OpFunctionPointerCallINTEL %[[TyInt64]] %[[FunPtr2]] %[[ConstInt64]]
+; CHECK: OpReturn
+; CHECK: OpFunctionEnd
+; CHECK: %[[DefFunFp]] = OpFunction %[[TyVoid]] None %[[TyFunFp]]
+
+target triple = "spir64-unknown-unknown"

VyacheslavLevytskyy wrote:

Probably this line is not needed here?

https://github.com/llvm/llvm-project/pull/89796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [clang][SPIR-V] Add support for AMDGCN flavoured SPIRV (PR #89796)

2024-06-06 Thread Vyacheslav Levytskyy via cfe-commits


@@ -0,0 +1,35 @@
+; RUN: llc -O0 -mtriple=spirv64-amd-amdhsa 
--spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s
+; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-amd-amdhsa %s -o - 
-filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpCapability Int8
+; CHECK-DAG: OpCapability GenericPointer
+; CHECK-DAG: OpCapability FunctionPointersINTEL
+; CHECK-DAG: OpCapability Int64
+; CHECK: OpExtension "SPV_INTEL_function_pointers"
+; CHECK-DAG: %[[TyInt8:.*]] = OpTypeInt 8 0
+; CHECK-DAG: %[[TyVoid:.*]] = OpTypeVoid
+; CHECK-DAG: %[[TyFloat32:.*]] = OpTypeFloat 32
+; CHECK-DAG: %[[TyInt64:.*]] = OpTypeInt 64 0
+; CHECK-DAG: %[[TyPtrInt8:.*]] = OpTypePointer Generic %[[TyInt8]]
+; CHECK-DAG: %[[TyFunFp:.*]] = OpTypeFunction %[[TyFloat32]] %[[TyPtrInt8]]
+; CHECK-DAG: %[[TyFunBar:.*]] = OpTypeFunction %[[TyInt64]] %[[TyPtrInt8]] 
%[[TyPtrInt8]]
+; CHECK-DAG: %[[TyPtrFunFp:.*]] = OpTypePointer Function %[[TyFunFp]]
+; CHECK-DAG: %[[TyPtrFunBar:.*]] = OpTypePointer Function %[[TyFunBar]]
+; CHECK-DAG: %[[TyFunTest:.*]] = OpTypeFunction %[[TyVoid]] %[[TyPtrInt8]] 
%[[TyPtrInt8]] %[[TyPtrInt8]]
+; CHECK: %[[FunTest:.*]] = OpFunction %[[TyVoid]] None %[[TyFunTest]]
+; CHECK: %[[ArgFp:.*]] = OpFunctionParameter %[[TyPtrInt8]]
+; CHECK: %[[ArgData:.*]] = OpFunctionParameter %[[TyPtrInt8]]
+; CHECK: %[[ArgBar:.*]] = OpFunctionParameter %[[TyPtrInt8]]
+; CHECK: OpFunctionPointerCallINTEL %[[TyFloat32]] %[[ArgFp]] %[[ArgBar]]
+; CHECK: OpFunctionPointerCallINTEL %[[TyInt64]] %[[ArgBar]] %[[ArgFp]] 
%[[ArgData]]
+; CHECK: OpReturn
+; CHECK: OpFunctionEnd
+
+target triple = "spir64-unknown-unknown"

VyacheslavLevytskyy wrote:

The same as above, I guess we don't need this line.

https://github.com/llvm/llvm-project/pull/89796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Refine invalidation caused by `fread` (PR #93408)

2024-06-06 Thread Balazs Benics via cfe-commits


@@ -0,0 +1,412 @@
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -triple x86_64-linux-gnu  \
+// RUN:   -analyzer-checker=core,unix.Stream,alpha.security.taint \
+// RUN:   -analyzer-checker=debug.ExprInspection
+
+#include "Inputs/system-header-simulator-for-simple-stream.h"
+
+#define EOF (-1)
+
+void clang_analyzer_dump(int);
+void clang_analyzer_isTainted(int);
+void clang_analyzer_warnIfReached(void);
+
+// A stream is only tracked by StreamChecker if it results from a call to 
"fopen".
+// Otherwise, there is no specific modelling of "fread".
+void untracked_stream(FILE *fp) {
+  char c;
+  if (1 == fread(&c, 1, 1, fp)) {
+char p = c; // Unknown value but not garbage and not modeled by checker.
+  } else {
+char p = c; // Possibly indeterminate value but not modeled by checker.
+  }
+}
+
+void fgetc_props_taint(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+int c = fgetc(fp); // c is tainted.
+if (c != EOF) {
+  clang_analyzer_isTainted(c); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void fread_props_taint(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+char buffer[10];
+int c = fread(buffer, 1, 10, fp); // c is tainted.
+if (c != 10) {
+  // If the read failed, then the number of bytes successfully read should 
be tainted.
+  clang_analyzer_isTainted(c); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte1(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+char c;
+if (1 == fread(&c, 1, 1, fp)) {
+  char p = c; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = c; // Possibly indeterminate value but not modeled by checker.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte2(char *buffer) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+if (1 == fread(buffer, 1, 1, fp)) {
+  char p = buffer[0]; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = buffer[0]; // Possibly indeterminate value but not modeled by 
checker.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte3(char *buffer) {
+  buffer[1] = 10;
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+// buffer[1] is not mutated by fread and remains not tainted.
+fread(buffer, 1, 1, fp);
+char p = buffer[1];
+clang_analyzer_isTainted(p); // expected-warning{{NO}}
+clang_analyzer_dump(buffer[1]); // expected-warning{{10 S32b}}
+fclose(fp);
+  }
+}
+
+void read_many_bytes(char *buffer) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+if (42 == fread(buffer, 1, 42, fp)) {
+  char p = buffer[0]; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = buffer[0]; // Possibly indeterminate value but not modeled.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void random_access_write1(int index) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+long c[4];
+int success = 2 == fread(c + 1, sizeof(long), 2, fp);
+
+switch (index) {
+case 0:
+  // c[0] is not mutated by fread.
+  if (success) {
+char p = c[0]; // expected-warning {{Assigned value is garbage or 
undefined}} We kept the first byte intact.
+  } else {
+char p = c[0]; // expected-warning {{Assigned value is garbage or 
undefined}} We kept the first byte intact.
+  }
+  break;
+
+case 1:
+  if (success) {
+// Unknown value but not garbage.
+clang_analyzer_isTainted(c[1]); // expected-warning {{YES}}
+clang_analyzer_dump(c[1]); // expected-warning {{conj_}}
+  } else {
+// Possibly indeterminate value but not modeled.
+clang_analyzer_isTainted(c[1]); // expected-warning {{YES}}
+clang_analyzer_dump(c[1]); // expected-warning {{conj_}}
+  }
+  break;
+
+case 2:
+  if (success) {
+long p = c[2]; // Unknown value but not garbage.
+// FIXME: Taint analysis only marks the first byte of a memory region. 
See getPointeeOf in GenericTaintChecker.cpp.
+clang_analyzer_isTainted(c[2]); // expected-warning {{NO}}
+clang_analyzer_dump(c[2]); // expected-warning {{conj_}}
+  } else {
+// Possibly indeterminate value but not modeled.
+clang_analyzer_isTainted(c[2]); // expected-warning {{NO}} // FIXME: 
See above.
+clang_analyzer_dump(c[2]); // expected-warning {{conj_}}
+  }
+  break;
+
+case 3:
+  // c[3] is not mutated by fread.
+  if (success) {
+long p = c[3]; // expected-warning {{Assigned value is garbage or 
undefined}}
+  } else {
+long p = c[3]; // ex

[clang] [llvm] [clang][SPIR-V] Add support for AMDGCN flavoured SPIRV (PR #89796)

2024-06-06 Thread Vyacheslav Levytskyy via cfe-commits


@@ -0,0 +1,35 @@
+; RUN: llc -O0 -mtriple=spirv64-amd-amdhsa 
--spirv-ext=+SPV_INTEL_function_pointers %s -o - | FileCheck %s
+; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-amd-amdhsa %s -o - 
-filetype=obj | spirv-val %}
+
+; CHECK-DAG: OpCapability Int8
+; CHECK-DAG: OpCapability GenericPointer
+; CHECK-DAG: OpCapability FunctionPointersINTEL
+; CHECK-DAG: OpCapability Int64
+; CHECK: OpExtension "SPV_INTEL_function_pointers"
+; CHECK-DAG: %[[TyInt8:.*]] = OpTypeInt 8 0
+; CHECK-DAG: %[[TyVoid:.*]] = OpTypeVoid
+; CHECK-DAG: %[[TyFloat32:.*]] = OpTypeFloat 32
+; CHECK-DAG: %[[TyInt64:.*]] = OpTypeInt 64 0
+; CHECK-DAG: %[[TyPtrInt8:.*]] = OpTypePointer Generic %[[TyInt8]]
+; CHECK-DAG: %[[TyFunFp:.*]] = OpTypeFunction %[[TyFloat32]] %[[TyPtrInt8]]
+; CHECK-DAG: %[[TyFunBar:.*]] = OpTypeFunction %[[TyInt64]] %[[TyPtrInt8]] 
%[[TyPtrInt8]]
+; CHECK-DAG: %[[TyPtrFunFp:.*]] = OpTypePointer Function %[[TyFunFp]]
+; CHECK-DAG: %[[TyPtrFunBar:.*]] = OpTypePointer Function %[[TyFunBar]]
+; CHECK-DAG: %[[TyFunTest:.*]] = OpTypeFunction %[[TyVoid]] %[[TyPtrInt8]] 
%[[TyPtrInt8]] %[[TyPtrInt8]]
+; CHECK: %[[FunTest:.*]] = OpFunction %[[TyVoid]] None %[[TyFunTest]]
+; CHECK: %[[ArgFp:.*]] = OpFunctionParameter %[[TyPtrInt8]]
+; CHECK: %[[ArgData:.*]] = OpFunctionParameter %[[TyPtrInt8]]
+; CHECK: %[[ArgBar:.*]] = OpFunctionParameter %[[TyPtrInt8]]
+; CHECK: OpFunctionPointerCallINTEL %[[TyFloat32]] %[[ArgFp]] %[[ArgBar]]
+; CHECK: OpFunctionPointerCallINTEL %[[TyInt64]] %[[ArgBar]] %[[ArgFp]] 
%[[ArgData]]
+; CHECK: OpReturn
+; CHECK: OpFunctionEnd
+
+target triple = "spir64-unknown-unknown"
+
+define spir_kernel void @test(ptr addrspace(4) %fp, ptr addrspace(4) %data, 
ptr addrspace(4) %bar) {
+entry:
+  %0 = call spir_func addrspace(4) float %fp(ptr addrspace(4) %bar)
+  %1 = call spir_func addrspace(4) i64 %bar(ptr addrspace(4) %fp, ptr 
addrspace(4) %data)
+  ret void
+}

VyacheslavLevytskyy wrote:

I have a general suggestion, if I may, about those two function pointers tests. 
Neither the extension itself is perfect, nor its current implementation in 
SPIR-V Backend. About a half of Khronos Translator test cases for the function 
pointers extension crash when running with our SPIR-V Backend implementation, 
and this is a near to-do item in our development plans.
Giving all these, probably it's better to freeze in tests as little of function 
pointers implementation logics as it's possible -- until the implementation is 
completed in full and all Khronos Translator test cases are successful. In 
terms of this PR this means that probably it's better to strip those 2 tests of 
details whenever this is possible, unless you consider each existing CHECK in 
those tests important.

https://github.com/llvm/llvm-project/pull/89796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [PowerPC] Support -mno-red-zone option (PR #94581)

2024-06-06 Thread Chen Zheng via cfe-commits

chenzheng1030 wrote:

> No. `-disable-red-zone` does nothing but add `noredzone` IR attribute to 
> functions. We need to add cases to test for `noredzone` behavior on PPC (arm 
> and x86 have).

Yeah, go ahead to add some backend tests first to make sure we have good 
functionality for `noredzone` attribute. Thanks.

https://github.com/llvm/llvm-project/pull/94581
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [AArch64] Decouple feature dependency expansion. (PR #94279)

2024-06-06 Thread David Green via cfe-commits

davemgreen wrote:

Yeah I had just seen that error message before you edited your comment. There 
are some examples of neon I found in a quick search, which were presumably 
added for AArch32:
https://github.com/aaru-dps/Aaru.Checksums.Native/blob/bd5051ce181b225a7662bfb764ebcc5cbe7542b2/simd.h#L112
https://github.com/mooch443/commons/blob/30dc797430968831959d77d7f2503cec3518a13a/common/misc/PVBlob.cpp#L385
I'm not sure if that is reason enough to still support it.

But like I said, if I try this patch locally then `target("neon")` seems to be 
accepted fine (no errors). It is the same for other features like 
`target("fullfp16")`, which seem to enable `+fullfp16` in the backend. 
`"noneon"` is no longer accepted, which might be fine as I don't believe 
negative features are commonly used. (For aarch64 from a baseline of armv8 they 
are mostly additive. They are likely to become more common going forward but 
new users can use the "right" attribute names).

https://github.com/llvm/llvm-project/pull/94279
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] f1e78f7 - [clang][Interp] Handle lvalue APValues in visitAPValueInitializer()

2024-06-06 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-06-06T10:24:26+02:00
New Revision: f1e78f776908f2bc1759eae25381f576f62728a2

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

LOG: [clang][Interp] Handle lvalue APValues in visitAPValueInitializer()

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/CodeGenCXX/template-param-objects-linkage.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 3671c41ae7039..ea259639dace7 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3188,7 +3188,7 @@ bool 
ByteCodeExprGen::visitAPValueInitializer(const APValue &Val,
   const APValue &F = Val.getStructField(I);
   const Record::Field *RF = R->getField(I);
 
-  if (F.isInt()) {
+  if (F.isInt() || F.isLValue()) {
 PrimType T = classifyPrim(RF->Decl->getType());
 if (!this->visitAPValue(F, T, E))
   return false;

diff  --git a/clang/test/CodeGenCXX/template-param-objects-linkage.cpp 
b/clang/test/CodeGenCXX/template-param-objects-linkage.cpp
index 63e7d8c646869..9c148ed83753d 100644
--- a/clang/test/CodeGenCXX/template-param-objects-linkage.cpp
+++ b/clang/test/CodeGenCXX/template-param-objects-linkage.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 %s -emit-llvm -o - | 
FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 %s -emit-llvm -o - 
-fexperimental-new-constant-interpreter | FileCheck %s
 
 struct S { char buf[32]; };
 template constexpr const char* f() { return s.buf; }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libclc] [llvm] [AMDGPU] Add a new target gfx1152 (PR #94534)

2024-06-06 Thread Jay Foad via cfe-commits


@@ -1534,6 +1534,12 @@ def FeatureISAVersion11_5_1 : FeatureSet<
  FeatureVGPRSingleUseHintInsts,
  Feature1_5xVGPRs])>;
 
+def FeatureISAVersion11_5_2 : FeatureSet<

jayfoad wrote:

I don't have a good answer to this except "it's what we normally do". Other 
parts of the software stack (kernel drivers etc) need to distinguish gfx1150 
from gfx1152, and I guess they don't want to map "gfx1152" -> "gfx1150" before 
invoking the compiler. Also, it will make it easier for us to implement 
gfx1152-specific optimizations and workarounds in future if there are any.

https://github.com/llvm/llvm-project/pull/94534
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Refine invalidation caused by `fread` (PR #93408)

2024-06-06 Thread Balazs Benics via cfe-commits


@@ -0,0 +1,412 @@
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -triple x86_64-linux-gnu  \
+// RUN:   -analyzer-checker=core,unix.Stream,alpha.security.taint \
+// RUN:   -analyzer-checker=debug.ExprInspection
+
+#include "Inputs/system-header-simulator-for-simple-stream.h"
+
+#define EOF (-1)
+
+void clang_analyzer_dump(int);
+void clang_analyzer_isTainted(int);
+void clang_analyzer_warnIfReached(void);
+
+// A stream is only tracked by StreamChecker if it results from a call to 
"fopen".
+// Otherwise, there is no specific modelling of "fread".
+void untracked_stream(FILE *fp) {
+  char c;
+  if (1 == fread(&c, 1, 1, fp)) {
+char p = c; // Unknown value but not garbage and not modeled by checker.
+  } else {
+char p = c; // Possibly indeterminate value but not modeled by checker.
+  }
+}
+
+void fgetc_props_taint(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+int c = fgetc(fp); // c is tainted.
+if (c != EOF) {
+  clang_analyzer_isTainted(c); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void fread_props_taint(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+char buffer[10];
+int c = fread(buffer, 1, 10, fp); // c is tainted.
+if (c != 10) {
+  // If the read failed, then the number of bytes successfully read should 
be tainted.
+  clang_analyzer_isTainted(c); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte1(void) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+char c;
+if (1 == fread(&c, 1, 1, fp)) {
+  char p = c; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = c; // Possibly indeterminate value but not modeled by checker.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte2(char *buffer) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+if (1 == fread(buffer, 1, 1, fp)) {
+  char p = buffer[0]; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = buffer[0]; // Possibly indeterminate value but not modeled by 
checker.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void read_one_byte3(char *buffer) {
+  buffer[1] = 10;
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+// buffer[1] is not mutated by fread and remains not tainted.
+fread(buffer, 1, 1, fp);
+char p = buffer[1];
+clang_analyzer_isTainted(p); // expected-warning{{NO}}
+clang_analyzer_dump(buffer[1]); // expected-warning{{10 S32b}}
+fclose(fp);
+  }
+}
+
+void read_many_bytes(char *buffer) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+if (42 == fread(buffer, 1, 42, fp)) {
+  char p = buffer[0]; // Unknown value but not garbage.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+} else {
+  char p = buffer[0]; // Possibly indeterminate value but not modeled.
+  clang_analyzer_isTainted(p); // expected-warning{{YES}}
+}
+fclose(fp);
+  }
+}
+
+void random_access_write1(int index) {
+  FILE *fp = fopen("/home/test", "rb+");
+  if (fp) {
+long c[4];
+int success = 2 == fread(c + 1, sizeof(long), 2, fp);
+
+switch (index) {
+case 0:
+  // c[0] is not mutated by fread.
+  if (success) {
+char p = c[0]; // expected-warning {{Assigned value is garbage or 
undefined}} We kept the first byte intact.
+  } else {
+char p = c[0]; // expected-warning {{Assigned value is garbage or 
undefined}} We kept the first byte intact.
+  }
+  break;
+
+case 1:
+  if (success) {
+// Unknown value but not garbage.
+clang_analyzer_isTainted(c[1]); // expected-warning {{YES}}
+clang_analyzer_dump(c[1]); // expected-warning {{conj_}}
+  } else {
+// Possibly indeterminate value but not modeled.
+clang_analyzer_isTainted(c[1]); // expected-warning {{YES}}
+clang_analyzer_dump(c[1]); // expected-warning {{conj_}}
+  }
+  break;
+
+case 2:
+  if (success) {
+long p = c[2]; // Unknown value but not garbage.
+// FIXME: Taint analysis only marks the first byte of a memory region. 
See getPointeeOf in GenericTaintChecker.cpp.
+clang_analyzer_isTainted(c[2]); // expected-warning {{NO}}
+clang_analyzer_dump(c[2]); // expected-warning {{conj_}}
+  } else {
+// Possibly indeterminate value but not modeled.
+clang_analyzer_isTainted(c[2]); // expected-warning {{NO}} // FIXME: 
See above.
+clang_analyzer_dump(c[2]); // expected-warning {{conj_}}
+  }
+  break;
+
+case 3:
+  // c[3] is not mutated by fread.
+  if (success) {
+long p = c[3]; // expected-warning {{Assigned value is garbage or 
undefined}}
+  } else {
+long p = c[3]; // ex

[clang] [libclc] [llvm] [AMDGPU] Add a new target gfx1152 (PR #94534)

2024-06-06 Thread Jay Foad via cfe-commits

https://github.com/jayfoad approved this pull request.

LGTM.

Could also update `flang/cmake/modules/AddFlangOffloadRuntime.cmake` but I 
don't really know if it's our responsibility to update Flang.

https://github.com/llvm/llvm-project/pull/94534
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Remove redundant LINK_LIBS (PR #94588)

2024-06-06 Thread Nikita Popov via cfe-commits

https://github.com/nikic created https://github.com/llvm/llvm-project/pull/94588

clangAnalysis is already being pulled in via clang_target_link_libraries(). 
Also listing it in LINK_LIBS means that we'll link both against the static 
libraries and the shared libclang-cpp.so library if CLANG_LINK_CLANG_DYLIB is 
enabled, and waste time on unnecessary LTO.

>From b4dda7214c4c6431c9f978296f68b494c4fc7b68 Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Thu, 6 Jun 2024 10:25:25 +0200
Subject: [PATCH] [clang-tidy] Remove redundant LINK_LIBS

clangAnalysis is already being pulled in via
clang_target_link_libraries(). Also listing it in LINK_LIBS means
that we'll link both against the static libraries and the shared
libclang-cpp.so library if CLANG_LINK_CLANG_DYLIB is enabled, and
waste time on unnecessary LTO.
---
 clang-tools-extra/clang-tidy/misc/CMakeLists.txt | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
index 35e29b9a7d13..36fcd8fc1b27 100644
--- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -43,7 +43,6 @@ add_clang_library(clangTidyMiscModule
   UseAnonymousNamespaceCheck.cpp
 
   LINK_LIBS
-  clangAnalysis
   clangTidy
   clangTidyUtils
 

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] Remove redundant LINK_LIBS (PR #94588)

2024-06-06 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-tidy

Author: Nikita Popov (nikic)


Changes

clangAnalysis is already being pulled in via clang_target_link_libraries(). 
Also listing it in LINK_LIBS means that we'll link both against the static 
libraries and the shared libclang-cpp.so library if CLANG_LINK_CLANG_DYLIB is 
enabled, and waste time on unnecessary LTO.

---
Full diff: https://github.com/llvm/llvm-project/pull/94588.diff


1 Files Affected:

- (modified) clang-tools-extra/clang-tidy/misc/CMakeLists.txt (-1) 


``diff
diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
index 35e29b9a7d136..36fcd8fc1b277 100644
--- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -43,7 +43,6 @@ add_clang_library(clangTidyMiscModule
   UseAnonymousNamespaceCheck.cpp
 
   LINK_LIBS
-  clangAnalysis
   clangTidy
   clangTidyUtils
 

``




https://github.com/llvm/llvm-project/pull/94588
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [cmake] Respect CLANG_LINK_CLANG_DYLIB for objlibs (PR #93454)

2024-06-06 Thread Nikita Popov via cfe-commits

https://github.com/nikic updated https://github.com/llvm/llvm-project/pull/93454

>From b0bcd36b62a93e7d8bd0f7f01e857ce9aa7544c2 Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Mon, 27 May 2024 11:56:41 +0200
Subject: [PATCH 1/2] [cmake] Respect CLANG_LINK_CLANG_DYLIB for objlibs

add_clang_library() will create a library clangFoo that depends
on objlib obj.clangFoo. Then clang_target_link_libraries() will
add a clang-cpp dependency to clangFoo, but obj.clangFoo will
instead get dependencies on the individual clangXYZ libraries,
instead of the shared object. The final outcome is that we will
link both the static libraries and the shared object, leading to
an increase in binary size and link times (when using LTO).

Make sure we use the same logic for the obj and non-obj libs.
---
 clang/cmake/modules/AddClang.cmake | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/cmake/modules/AddClang.cmake 
b/clang/cmake/modules/AddClang.cmake
index a5ef639187d9..534c7b84ecfb 100644
--- a/clang/cmake/modules/AddClang.cmake
+++ b/clang/cmake/modules/AddClang.cmake
@@ -194,10 +194,6 @@ macro(add_clang_symlink name dest)
 endmacro()
 
 function(clang_target_link_libraries target type)
-  if (TARGET obj.${target})
-target_link_libraries(obj.${target} ${ARGN})
-  endif()
-
   get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS)
   if(LLVM_TOOL_LLVM_DRIVER_BUILD AND ${target} IN_LIST LLVM_DRIVER_TOOLS)
 set(target llvm-driver)
@@ -205,7 +201,13 @@ function(clang_target_link_libraries target type)
 
   if (CLANG_LINK_CLANG_DYLIB)
 target_link_libraries(${target} ${type} clang-cpp)
+if (TARGET obj.${target})
+  target_link_libraries(obj.${target} clang-cpp)
+endif()
   else()
 target_link_libraries(${target} ${type} ${ARGN})
+if (TARGET obj.${target})
+  target_link_libraries(obj.${target} ${ARGN})
+endif()
   endif()
 endfunction()

>From 1cc7f9a4dc8d406886188797858e314f2d7634c6 Mon Sep 17 00:00:00 2001
From: Nikita Popov 
Date: Thu, 6 Jun 2024 10:05:35 +0200
Subject: [PATCH 2/2] Use INTERFACE dep

---
 clang/cmake/modules/AddClang.cmake | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/cmake/modules/AddClang.cmake 
b/clang/cmake/modules/AddClang.cmake
index 534c7b84ecfb..2528c16a09e5 100644
--- a/clang/cmake/modules/AddClang.cmake
+++ b/clang/cmake/modules/AddClang.cmake
@@ -202,12 +202,12 @@ function(clang_target_link_libraries target type)
   if (CLANG_LINK_CLANG_DYLIB)
 target_link_libraries(${target} ${type} clang-cpp)
 if (TARGET obj.${target})
-  target_link_libraries(obj.${target} clang-cpp)
+  target_link_libraries(obj.${target} INTERFACE clang-cpp)
 endif()
   else()
 target_link_libraries(${target} ${type} ${ARGN})
 if (TARGET obj.${target})
-  target_link_libraries(obj.${target} ${ARGN})
+  target_link_libraries(obj.${target} INTERFACE ${ARGN})
 endif()
   endif()
 endfunction()

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 7091dfc - [clang-repl] Lay the foundation of pretty printing for C. (#89811)

2024-06-06 Thread via cfe-commits

Author: Vassil Vassilev
Date: 2024-06-06T11:49:10+03:00
New Revision: 7091dfc0e49b8c79f9e1daf6ab0ca0e65f30f347

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

LOG: [clang-repl] Lay the foundation of pretty printing for C. (#89811)

Added: 
clang/test/Interpreter/pretty-print.c

Modified: 
clang/lib/Interpreter/Interpreter.cpp
clang/lib/Parse/ParseStmt.cpp

Removed: 




diff  --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index 683f87e8c8c7..7a9527891427 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -42,6 +42,9 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Host.h"
+
+#include 
+
 using namespace clang;
 
 // FIXME: Figure out how to unify with namespace init_convenience from
@@ -270,14 +273,10 @@ Interpreter::~Interpreter() {
 // can't find the precise resource directory in unittests so we have to hard
 // code them.
 const char *const Runtimes = R"(
+#define __CLANG_REPL__ 1
 #ifdef __cplusplus
+#define EXTERN_C extern "C"
 void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
-void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*);
-void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*);
-void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float);
-void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double);
-void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double);
-void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long 
long);
 struct __clang_Interpreter_NewTag{} __ci_newtag;
 void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) 
noexcept;
 template 
@@ -289,7 +288,11 @@ const char *const Runtimes = R"(
 void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* 
Placement, unsigned long Size) {
   __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
 }
+#else
+#define EXTERN_C extern
 #endif // __cplusplus
+
+  EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, 
void *OpaqueType, ...);
 )";
 
 llvm::Expected>
@@ -588,15 +591,17 @@ std::unique_ptr 
Interpreter::FindRuntimeInterface() {
   if (!LookupInterface(ValuePrintingInfo[NoAlloc],
MagicRuntimeInterface[NoAlloc]))
 return nullptr;
-  if (!LookupInterface(ValuePrintingInfo[WithAlloc],
-   MagicRuntimeInterface[WithAlloc]))
-return nullptr;
-  if (!LookupInterface(ValuePrintingInfo[CopyArray],
-   MagicRuntimeInterface[CopyArray]))
-return nullptr;
-  if (!LookupInterface(ValuePrintingInfo[NewTag],
-   MagicRuntimeInterface[NewTag]))
-return nullptr;
+  if (Ctx.getLangOpts().CPlusPlus) {
+if (!LookupInterface(ValuePrintingInfo[WithAlloc],
+ MagicRuntimeInterface[WithAlloc]))
+  return nullptr;
+if (!LookupInterface(ValuePrintingInfo[CopyArray],
+ MagicRuntimeInterface[CopyArray]))
+  return nullptr;
+if (!LookupInterface(ValuePrintingInfo[NewTag],
+ MagicRuntimeInterface[NewTag]))
+  return nullptr;
+  }
 
   return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S);
 }
@@ -855,69 +860,81 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void 
*OutVal,
   return VRef.getPtr();
 }
 
-// Pointers, lvalue struct that can take as a reference.
-REPL_EXTERNAL_VISIBILITY void
-__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType,
-void *Val) {
+extern "C" void REPL_EXTERNAL_VISIBILITY __clang_Interpreter_SetValueNoAlloc(
+void *This, void *OutVal, void *OpaqueType, ...) {
   Value &VRef = *(Value *)OutVal;
-  VRef = Value(static_cast(This), OpaqueType);
-  VRef.setPtr(Val);
-}
+  Interpreter *I = static_cast(This);
+  VRef = Value(I, OpaqueType);
+  if (VRef.isVoid())
+return;
 
-REPL_EXTERNAL_VISIBILITY void
-__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal,
-void *OpaqueType) {
-  Value &VRef = *(Value *)OutVal;
-  VRef = Value(static_cast(This), OpaqueType);
-}
+  va_list args;
+  va_start(args, /*last named param*/ OpaqueType);
 
-static void SetValueDataBasedOnQualType(Value &V, unsigned long long Data) {
-  QualType QT = V.getType();
-  if (const auto *ET = QT->getAs())
-QT = ET->getDecl()->getIntegerType();
-
-  switch (QT->castAs()->getKind()) {
-  default:
-llvm_unreachable("unknown type kind!");
-#define X(type, name)  
\
-  case BuiltinType::name:   

[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)

2024-06-06 Thread Vassil Vassilev via cfe-commits

https://github.com/vgvassilev closed 
https://github.com/llvm/llvm-project/pull/89811
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AMDGPU] Add builtins for instrinsic `llvm.amdgcn.raw.buffer.store` (PR #94576)

2024-06-06 Thread Jay Foad via cfe-commits

jayfoad wrote:

Is there really a good use case for this? Can you use regular stores to 
addrspace(7) instead? @krzysz00

Also, do you really need a separate builtin for every legal type, or is there 
some way they can be type-overloaded?

https://github.com/llvm/llvm-project/pull/94576
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [RISCV] Add processor definition for SpacemiT-X60 (PR #94564)

2024-06-06 Thread Mark Zhuang via cfe-commits

zqb-all wrote:

Need to add zicond, which is not in RVA22S64Features

https://github.com/llvm/llvm-project/pull/94564
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AMDGPU] Add builtins for instrinsic `llvm.amdgcn.raw.buffer.store` (PR #94576)

2024-06-06 Thread Matt Arsenault via cfe-commits

arsenm wrote:

> Is there really a good use case for this? Can you use regular stores to 
> addrspace(7) instead? @krzysz00

I see these regularly used via inline asm in various ML code. We need to expose 
these in some way to stop people from doing that 

> 
> Also, do you really need a separate builtin for every legal type, or is there 
> some way they can be type-overloaded?

Yes, I imagined we would handle images similar to the elementwise intrinsics. 
However, I don't think that approach works for loads. If we have to have 
overloads for loads, we probably should mirror it for stores.

I think it makes more sense to solve the issue for the load case before the 
stores. They're a bit more complicated because you have the sign vs. zero 
extended cases to consider, and the overload would be on the return type 

https://github.com/llvm/llvm-project/pull/94576
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix spurious availability warning (PR #94377)

2024-06-06 Thread Gábor Horváth via cfe-commits

https://github.com/Xazax-hun ready_for_review 
https://github.com/llvm/llvm-project/pull/94377
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][AMDGPU] Add builtins for instrinsic `llvm.amdgcn.raw.buffer.store` (PR #94576)

2024-06-06 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,264 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: amdgpu-registered-target
+// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu verde -emit-llvm 
-o - %s | FileCheck %s --check-prefixes=VERDE
+// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu tonga -emit-llvm 
-o - %s | FileCheck %s --check-prefixes=GFX8
+// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1100 
-emit-llvm -o - %s | FileCheck %s --check-prefixes=GFX11
+
+#pragma OPENCL EXTENSION cl_khr_fp16 : enable
+
+typedef short v2i16 __attribute__((ext_vector_type(2)));
+typedef int v2i32 __attribute__((ext_vector_type(2)));
+typedef half v2f16 __attribute__((ext_vector_type(2)));
+typedef float v2f32 __attribute__((ext_vector_type(2)));
+typedef short v4i16 __attribute__((ext_vector_type(4)));
+typedef int v4i32 __attribute__((ext_vector_type(4)));
+typedef half v4f16 __attribute__((ext_vector_type(4)));
+typedef float v4f32 __attribute__((ext_vector_type(4)));
+
+// VERDE-LABEL: @test_amdgcn_raw_buffer_store_i8(
+// VERDE-NEXT:  entry:
+// VERDE-NEXT:tail call void @llvm.amdgcn.raw.buffer.store.i8(i8 
[[VDATA:%.*]], <4 x i32> [[RSRC:%.*]], i32 0, i32 0, i32 0)
+// VERDE-NEXT:ret void
+//
+// GFX8-LABEL: @test_amdgcn_raw_buffer_store_i8(
+// GFX8-NEXT:  entry:
+// GFX8-NEXT:tail call void @llvm.amdgcn.raw.buffer.store.i8(i8 
[[VDATA:%.*]], <4 x i32> [[RSRC:%.*]], i32 0, i32 0, i32 0)
+// GFX8-NEXT:ret void
+//
+// GFX11-LABEL: @test_amdgcn_raw_buffer_store_i8(
+// GFX11-NEXT:  entry:
+// GFX11-NEXT:tail call void @llvm.amdgcn.raw.buffer.store.i8(i8 
[[VDATA:%.*]], <4 x i32> [[RSRC:%.*]], i32 0, i32 0, i32 0)
+// GFX11-NEXT:ret void
+//
+void test_amdgcn_raw_buffer_store_i8(char vdata, v4i32 rsrc) {

arsenm wrote:

We are trying to move to using real pointers (i.e. use 
llvm.amdgcn.raw.ptr.buffer.store instead of llvm.amdgcn.raw.buffer.store) 

https://github.com/llvm/llvm-project/pull/94576
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix spurious availability warning (PR #94377)

2024-06-06 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Gábor Horváth (Xazax-hun)


Changes

The availability attributes are stored on the function declarations. The code 
was looking for them in the function template declarations. This resulted in 
spuriously diagnosing availablity issues in contexts that are not available.

---
Full diff: https://github.com/llvm/llvm-project/pull/94377.diff


3 Files Affected:

- (modified) clang/include/clang/Sema/Initialization.h (+1-1) 
- (modified) clang/lib/Sema/SemaAvailability.cpp (+5) 
- (added) clang/test/Sema/attr-availability-macosx.cpp (+17) 


``diff
diff --git a/clang/include/clang/Sema/Initialization.h 
b/clang/include/clang/Sema/Initialization.h
index 2072cd8d1c3ef..f443e327eaf32 100644
--- a/clang/include/clang/Sema/Initialization.h
+++ b/clang/include/clang/Sema/Initialization.h
@@ -212,7 +212,7 @@ class alignas(8) InitializedEntity {
 struct C Capture;
   };
 
-  InitializedEntity() {};
+  InitializedEntity() {}
 
   /// Create the initialization entity for a variable.
   InitializedEntity(VarDecl *Var, EntityKind EK = EK_Variable)
diff --git a/clang/lib/Sema/SemaAvailability.cpp 
b/clang/lib/Sema/SemaAvailability.cpp
index 330cd602297d4..3e5f90b450367 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -12,6 +12,7 @@
 
 #include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/IdentifierTable.h"
@@ -46,6 +47,10 @@ static const AvailabilityAttr *getAttrForPlatform(ASTContext 
&Context,
   // Check each AvailabilityAttr to find the one for this platform.
   // For multiple attributes with the same platform try to find one for this
   // environment.
+  // The attribute is always on the FunctionDecl, not on the
+  // FunctionTemplateDecl.
+  if (const auto *FTD = dyn_cast(D))
+D = FTD->getTemplatedDecl();
   for (const auto *A : D->attrs()) {
 if (const auto *Avail = dyn_cast(A)) {
   // FIXME: this is copied from CheckAvailability. We should try to
diff --git a/clang/test/Sema/attr-availability-macosx.cpp 
b/clang/test/Sema/attr-availability-macosx.cpp
new file mode 100644
index 0..52f320d409281
--- /dev/null
+++ b/clang/test/Sema/attr-availability-macosx.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 "-triple" "arm64-apple-macosx10.15" -fsyntax-only -verify %s
+
+__attribute__((availability(macos,introduced=11)))
+inline bool try_acquire() {
+  return true;
+}
+
+template 
+__attribute__((availability(macos,introduced=11)))
+bool try_acquire_for(T duration) { // expected-note{{'try_acquire_for' 
has been marked as being introduced in macOS 11 here, but the deployment target 
is macOS 10.15}}
+  return try_acquire();
+}
+
+int main() {
+  try_acquire_for(1); // expected-warning{{'try_acquire_for' is only 
available on macOS 11 or newer}}
+  // expected-note@-1{{enclose 'try_acquire_for' in a __builtin_available 
check to silence this warning}}
+}
\ No newline at end of file

``




https://github.com/llvm/llvm-project/pull/94377
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix spurious availability warning (PR #94377)

2024-06-06 Thread Gábor Horváth via cfe-commits

Xazax-hun wrote:

Thos should fix the non-strict availability related repro from 
https://github.com/llvm/llvm-project/issues/40423 . It does not fix the strict 
case which is a separate codepath, so I did not mark this PR as fixing that bug 
report. 

https://github.com/llvm/llvm-project/pull/94377
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fixed grammatical error in "enum specifier" error msg #94443 (PR #94592)

2024-06-06 Thread via cfe-commits

https://github.com/kper created https://github.com/llvm/llvm-project/pull/94592

As discussed in #94443, this PR changes the wording to be more correct.

>From 6ff1ec93e93e988b4e4fb2f490d5ea5a7d6e506a Mon Sep 17 00:00:00 2001
From: Kevin Per 
Date: Wed, 5 Jun 2024 18:45:10 +
Subject: [PATCH] Fixed grammatical error in "enum specifier" error msg #94443

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td| 6 +++---
 clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp  | 4 ++--
 .../CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp   | 6 +++---
 clang/test/CXX/drs/cwg2xx.cpp   | 6 +++---
 clang/test/CXX/drs/cwg4xx.cpp   | 2 +-
 clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp   | 2 +-
 clang/test/CXX/temp/temp.spec/no-body.cpp   | 2 +-
 clang/test/SemaCXX/PR8755.cpp   | 2 +-
 clang/test/SemaCXX/using-decl-templates.cpp | 2 +-
 clang/test/SemaTemplate/template-id-expr.cpp| 2 +-
 10 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1a117245a325e3..4f74f62374d8b0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6088,9 +6088,9 @@ def err_redefinition_different_concept : Error<
   "redefinition of concept %0 with different template parameters or 
requirements">;
 def err_tag_reference_non_tag : Error<
   "%select{non-struct type|non-class type|non-union type|non-enum "
-  "type|typedef|type alias|template|type alias template|template "
-  "template argument}1 %0 cannot be referenced with a "
-  "%select{struct|interface|union|class|enum}2 specifier">;
+  "type|typedef|type alias|template|alias template|template "
+  "template argument}1 %0 cannot be referenced with the '"
+  "%select{struct|interface|union|class|enum}2' specifier">;
 def err_tag_reference_conflict : Error<
   "implicit declaration introduced by elaborated type conflicts with a "
   "%select{non-struct type|non-class type|non-union type|non-enum "
diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp 
b/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
index a908518f02ea2e..c58cbfefc7997c 100644
--- a/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
+++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
@@ -9,7 +9,7 @@ namespace test0 {
 typedef int A; // expected-note {{declared here}}
 
 int test() {
-  struct A a; // expected-error {{typedef 'A' cannot be referenced with a 
struct specifier}}
+  struct A a; // expected-error {{typedef 'A' cannot be referenced with 
the 'struct' specifier}}
   return a.foo;
 }
   }
@@ -18,7 +18,7 @@ namespace test0 {
 template  class A; // expected-note {{declared here}}
 
 int test() {
-  struct A a; // expected-error {{template 'A' cannot be referenced with a 
struct specifier}}
+  struct A a; // expected-error {{template 'A' cannot be referenced with 
the 'struct' specifier}}
   return a.foo;
 }
   }
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
index f3e79c0aae44a8..98c9b915c6ce9f 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
@@ -2,18 +2,18 @@
 
 struct A { typedef int type; };
 template using X = A; // expected-note {{declared here}}
-struct X* p2; // expected-error {{type alias template 'X' cannot be 
referenced with a struct specifier}}
+struct X* p2; // expected-error {{alias template 'X' cannot be referenced 
with the 'struct' specifier}}
 
 
 template using Id = T; // expected-note {{declared here}}
 template class F>
 struct Y {
-  struct F i; // expected-error {{type alias template 'Id' cannot be 
referenced with a struct specifier}}
+  struct F i; // expected-error {{alias template 'Id' cannot be 
referenced with the 'struct' specifier}}
   typename F::type j; // ok
 
   // FIXME: don't produce the diagnostic both for the definition and the 
instantiation.
   template using U = F; // expected-note 2{{declared here}}
-  struct Y::template U k; // expected-error 2{{type alias template 
'U' cannot be referenced with a struct specifier}}
+  struct Y::template U k; // expected-error 2{{alias template 'U' 
cannot be referenced with the 'struct' specifier}}
   typename Y::template U l; // ok
 };
 template struct Y; // expected-note {{requested here}}
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index 2b3131be33057a..99916dea9a9120 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -759,7 +759,7 @@ namespace cwg254 { // cwg254: 2.9
 typedef typename T::type type; // ok even if this is a typedef-n

[clang] Fixed grammatical error in "enum specifier" error msg #94443 (PR #94592)

2024-06-06 Thread via cfe-commits

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/94592
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fixed grammatical error in "enum specifier" error msg #94443 (PR #94592)

2024-06-06 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (kper)


Changes

As discussed in #94443, this PR changes the wording to be more correct.

---
Full diff: https://github.com/llvm/llvm-project/pull/94592.diff


10 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3-3) 
- (modified) clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp (+2-2) 
- (modified) clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp 
(+3-3) 
- (modified) clang/test/CXX/drs/cwg2xx.cpp (+3-3) 
- (modified) clang/test/CXX/drs/cwg4xx.cpp (+1-1) 
- (modified) clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp (+1-1) 
- (modified) clang/test/CXX/temp/temp.spec/no-body.cpp (+1-1) 
- (modified) clang/test/SemaCXX/PR8755.cpp (+1-1) 
- (modified) clang/test/SemaCXX/using-decl-templates.cpp (+1-1) 
- (modified) clang/test/SemaTemplate/template-id-expr.cpp (+1-1) 


``diff
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1a117245a325e3..4f74f62374d8b0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6088,9 +6088,9 @@ def err_redefinition_different_concept : Error<
   "redefinition of concept %0 with different template parameters or 
requirements">;
 def err_tag_reference_non_tag : Error<
   "%select{non-struct type|non-class type|non-union type|non-enum "
-  "type|typedef|type alias|template|type alias template|template "
-  "template argument}1 %0 cannot be referenced with a "
-  "%select{struct|interface|union|class|enum}2 specifier">;
+  "type|typedef|type alias|template|alias template|template "
+  "template argument}1 %0 cannot be referenced with the '"
+  "%select{struct|interface|union|class|enum}2' specifier">;
 def err_tag_reference_conflict : Error<
   "implicit declaration introduced by elaborated type conflicts with a "
   "%select{non-struct type|non-class type|non-union type|non-enum "
diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp 
b/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
index a908518f02ea2e..c58cbfefc7997c 100644
--- a/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
+++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
@@ -9,7 +9,7 @@ namespace test0 {
 typedef int A; // expected-note {{declared here}}
 
 int test() {
-  struct A a; // expected-error {{typedef 'A' cannot be referenced with a 
struct specifier}}
+  struct A a; // expected-error {{typedef 'A' cannot be referenced with 
the 'struct' specifier}}
   return a.foo;
 }
   }
@@ -18,7 +18,7 @@ namespace test0 {
 template  class A; // expected-note {{declared here}}
 
 int test() {
-  struct A a; // expected-error {{template 'A' cannot be referenced with a 
struct specifier}}
+  struct A a; // expected-error {{template 'A' cannot be referenced with 
the 'struct' specifier}}
   return a.foo;
 }
   }
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp 
b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
index f3e79c0aae44a8..98c9b915c6ce9f 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
@@ -2,18 +2,18 @@
 
 struct A { typedef int type; };
 template using X = A; // expected-note {{declared here}}
-struct X* p2; // expected-error {{type alias template 'X' cannot be 
referenced with a struct specifier}}
+struct X* p2; // expected-error {{alias template 'X' cannot be referenced 
with the 'struct' specifier}}
 
 
 template using Id = T; // expected-note {{declared here}}
 template class F>
 struct Y {
-  struct F i; // expected-error {{type alias template 'Id' cannot be 
referenced with a struct specifier}}
+  struct F i; // expected-error {{alias template 'Id' cannot be 
referenced with the 'struct' specifier}}
   typename F::type j; // ok
 
   // FIXME: don't produce the diagnostic both for the definition and the 
instantiation.
   template using U = F; // expected-note 2{{declared here}}
-  struct Y::template U k; // expected-error 2{{type alias template 
'U' cannot be referenced with a struct specifier}}
+  struct Y::template U k; // expected-error 2{{alias template 'U' 
cannot be referenced with the 'struct' specifier}}
   typename Y::template U l; // ok
 };
 template struct Y; // expected-note {{requested here}}
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index 2b3131be33057a..99916dea9a9120 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -759,7 +759,7 @@ namespace cwg254 { // cwg254: 2.9
 typedef typename T::type type; // ok even if this is a typedef-name, 
because
// it's not an elaborated-type-specifier
 typedef struct T::type foo;
-// expected-error@-1 {{typedef 'type' cannot be referenced with a str

[clang] [analyzer] Refine invalidation caused by `fread` (PR #93408)

2024-06-06 Thread Balazs Benics via cfe-commits


@@ -907,6 +945,73 @@ void StreamChecker::preWrite(const FnDescription *Desc, 
const CallEvent &Call,
   C.addTransition(State);
 }
 
+static std::optional getPointeeType(const MemRegion *R) {
+  if (!R)
+return std::nullopt;
+  if (const auto *ER = dyn_cast(R))
+return ER->getElementType();
+  if (const auto *TR = dyn_cast(R))
+return TR->getValueType();
+  if (const auto *SR = dyn_cast(R))
+return SR->getPointeeStaticType();
+  return std::nullopt;
+}
+
+static std::optional getStartIndex(SValBuilder &SVB,
+   const MemRegion *R) {
+  if (!R)
+return std::nullopt;
+
+  auto Zero = [&SVB] {
+BasicValueFactory &BVF = SVB.getBasicValueFactory();
+return nonloc::ConcreteInt(BVF.getIntValue(0, /*isUnsigned=*/false));
+  };
+
+  if (const auto *ER = dyn_cast(R))
+return ER->getIndex();
+  if (const auto *TR = dyn_cast(R))
+return Zero();
+  if (const auto *SR = dyn_cast(R))
+return Zero();
+  return std::nullopt;
+}
+
+static ProgramStateRef
+tryToInvalidateFReadBufferByElements(ProgramStateRef State, CheckerContext &C,
+ const CallEvent &Call, NonLoc SizeVal,
+ NonLoc NMembVal) {
+  // Try to invalidate the individual elements.
+  const auto *Buffer =
+  dyn_cast_or_null(Call.getArgSVal(0).getAsRegion());
+
+  std::optional ElemTy = getPointeeType(Buffer);
+  std::optional StartElementIndex =
+  getStartIndex(C.getSValBuilder(), Buffer);
+
+  // Drop the outermost ElementRegion to get the buffer.
+  if (const auto *ER = dyn_cast_or_null(Buffer))
+Buffer = dyn_cast(ER->getSuperRegion());
+
+  std::optional CountVal = getKnownValue(State, NMembVal);
+  std::optional Size = getKnownValue(State, SizeVal);
+  std::optional StartIndexVal =
+  getKnownValue(State, StartElementIndex.value_or(UnknownVal()));
+
+  if (ElemTy && CountVal && Size && StartIndexVal) {
+int64_t NumBytesRead = Size.value() * CountVal.value();
+int64_t ElemSizeInChars =
+C.getASTContext().getTypeSizeInChars(*ElemTy).getQuantity();
+bool DivisibleAccessSpan = (NumBytesRead % ElemSizeInChars) == 0;
+int64_t NumElementsRead = NumBytesRead / ElemSizeInChars;
+constexpr int MaxInvalidatedElementsLimit = 64;
+if (DivisibleAccessSpan && NumElementsRead <= MaxInvalidatedElementsLimit) 
{

steakhal wrote:

Applied a patch to this code such that the last partial element is considered 
as a full access.
This is indeed better than doing a fallback and invalidating the full buffer.
Also modified the test to demonstrate this, but there is yet another bug in the 
current Store:
If we read from a byte offset of an element, we still get unknown as a result: 
`int buffer[2] = {2,3}` then reading from `((char*)buffer)[1]` results in 
unknown. [Compiler explorer](https://godbolt.org/z/dTKGnYo9W).

https://github.com/llvm/llvm-project/pull/93408
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix spurious availability warning (PR #94377)

2024-06-06 Thread Gábor Horváth via cfe-commits

https://github.com/Xazax-hun edited 
https://github.com/llvm/llvm-project/pull/94377
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [cmake] Respect CLANG_LINK_CLANG_DYLIB for objlibs (PR #93454)

2024-06-06 Thread Nikita Popov via cfe-commits

nikic wrote:

I suspect I may have misdiagnosed the issue, and the actual problem may be just 
https://github.com/llvm/llvm-project/pull/94588. I'll double check whether this 
change is necessary before landing.

https://github.com/llvm/llvm-project/pull/93454
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Fix spurious non-strict availability warning (PR #94377)

2024-06-06 Thread Gábor Horváth via cfe-commits

https://github.com/Xazax-hun edited 
https://github.com/llvm/llvm-project/pull/94377
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Refine invalidation caused by `fread` (PR #93408)

2024-06-06 Thread Balazs Benics via cfe-commits

https://github.com/steakhal updated 
https://github.com/llvm/llvm-project/pull/93408




  
Unicorn! · GitHub

  body {
background-color: #f1f1f1;
margin: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  }

  .container { margin: 50px auto 40px auto; width: 600px; text-align: 
center; }

  a { color: #4183c4; text-decoration: none; }
  a:hover { text-decoration: underline; }

  h1 { letter-spacing: -1px; line-height: 60px; font-size: 60px; 
font-weight: 100; margin: 0px; text-shadow: 0 1px 0 #fff; }
  p { color: rgba(0, 0, 0, 0.5); margin: 10px 0 10px; font-size: 18px; 
font-weight: 200; line-height: 1.6em;}

  ul { list-style: none; margin: 25px 0; padding: 0; }
  li { display: table-cell; font-weight: bold; width: 1%; }

  .logo { display: inline-block; margin-top: 35px; }
  .logo-img-2x { display: none; }
  @media
  only screen and (-webkit-min-device-pixel-ratio: 2),
  only screen and (   min--moz-device-pixel-ratio: 2),
  only screen and ( -o-min-device-pixel-ratio: 2/1),
  only screen and (min-device-pixel-ratio: 2),
  only screen and (min-resolution: 192dpi),
  only screen and (min-resolution: 2dppx) {
.logo-img-1x { display: none; }
.logo-img-2x { display: inline-block; }
  }

  #suggestions {
margin-top: 35px;
color: #ccc;
  }
  #suggestions a {
color: #66;
font-weight: 200;
font-size: 14px;
margin: 0 10px;
  }


  
  


  

  

  We couldn't respond to your request in time.
  Sorry about that. Please try refreshing and contact us if the problem 
persists.
  
https://github.com/contact";>Contact Support —
https://www.githubstatus.com";>GitHub Status —
https://twitter.com/githubstatus";>@githubstatus
  

  

  

  

  

  


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [analyzer] Refine invalidation caused by `fread` (PR #93408)

2024-06-06 Thread Balazs Benics via cfe-commits

steakhal wrote:

Addressed all the feedback.

https://github.com/llvm/llvm-project/pull/93408
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] `doesNotMutateObject`: Handle calls to member functions … (PR #94362)

2024-06-06 Thread Clement Courbet via cfe-commits


@@ -36,6 +36,111 @@ void extractNodesByIdTo(ArrayRef Matches, 
StringRef ID,
 Nodes.insert(Match.getNodeAs(ID));
 }
 
+// If `D` has a const-qualified overload with otherwise identical
+// ref-qualifiers, returns that overload.
+const CXXMethodDecl *findConstOverload(const CXXMethodDecl &D) {
+  assert(!D.isConst());
+
+  DeclContext::lookup_result lookup_result =
+  D.getParent()->lookup(D.getNameInfo().getName());
+  if (lookup_result.isSingleResult()) {
+// No overload.
+return nullptr;
+  }
+  for (const Decl *overload : lookup_result) {
+const CXXMethodDecl *candidate = dyn_cast(overload);
+if (candidate && !candidate->isDeleted() && candidate->isConst() &&
+candidate->getRefQualifier() == D.getRefQualifier()) {

legrosbuffle wrote:

Overloading would be allowed in this case, but I think having a `const` 
overload with the same *parameter* types is enough to say that the use is 
immutable (not that the case when the return value is non-const and the object 
might be modified through the return value is caught by `(C)`). I've added a 
test to make this explicit (`weird_overload()`).

That being said, your comment made me realize that we were not checking that 
the parameter types were the same. Done and added tests (`at(Tag1)`). Thanks :)

https://github.com/llvm/llvm-project/pull/94362
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] r11 is reserved when using -mframe-chain=aapcs (PR #86951)

2024-06-06 Thread via cfe-commits

https://github.com/ostannard updated 
https://github.com/llvm/llvm-project/pull/86951

>From 1e141e80b0abf45f160c06f8eb39623df16434d8 Mon Sep 17 00:00:00 2001
From: Oliver Stannard 
Date: Thu, 6 Jun 2024 09:34:13 +0100
Subject: [PATCH 1/2] [IR] Add target-independent option to preserve
 frame-pointer register

This adds a new value "reserved" to the "frame-pointer" function
attribute. When this value is used, the frame pointer register must
either be reserved, or updated to point to a new frame record, but must
not be used for any other purpose.

This is not yet supported by most targets, but will be used for the Arm
-mframe-chain= option.
---
 clang/include/clang/Basic/CodeGenOptions.def |  2 +-
 clang/include/clang/Basic/CodeGenOptions.h   |  3 +++
 clang/include/clang/Driver/Options.td|  4 ++--
 clang/lib/CodeGen/CGCall.cpp |  1 +
 clang/lib/CodeGen/CodeGenModule.cpp  |  3 +++
 clang/lib/Driver/ToolChains/Clang.cpp|  3 +++
 llvm/docs/LangRef.rst|  6 +-
 llvm/include/llvm/Support/CodeGen.h  |  2 +-
 llvm/include/llvm/Target/TargetOptions.h |  5 +
 llvm/lib/CodeGen/CommandFlags.cpp|  5 +
 llvm/lib/CodeGen/TargetOptionsImpl.cpp   | 21 ++--
 llvm/lib/IR/Function.cpp |  3 +++
 llvm/lib/IR/Verifier.cpp |  2 +-
 13 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 07b0ca1691a67..7ffc40a00504f 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -61,7 +61,7 @@ CODEGENOPT(SeparateNamedSections, 1, 0) ///< Set for 
-fseparate-named-sections.
 CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. 
Enables the extended Altivec ABI on AIX.
 CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr.
 CODEGENOPT(AllTocData, 1, 0) ///< AIX -mtocdata
-ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// 
frame-pointer: all,non-leaf,none
+ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// 
frame-pointer: all,non-leaf,reserved,none
 
 CODEGENOPT(ClearASTBeforeBackend , 1, 0) ///< Free the AST before running 
backend code generation. Only works with -disable-free.
 CODEGENOPT(DisableFree   , 1, 0) ///< Don't free memory.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb..6887926cb34da 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -128,6 +128,7 @@ class CodeGenOptions : public CodeGenOptionsBase {
 
   enum class FramePointerKind {
 None,// Omit all frame pointers.
+Reserved,// Maintain valid frame pointer chain.
 NonLeaf, // Keep non-leaf frame pointers.
 All, // Keep all frame pointers.
   };
@@ -136,6 +137,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
 switch (Kind) {
 case FramePointerKind::None:
   return "none";
+case FramePointerKind::Reserved:
+  return "reserved";
 case FramePointerKind::NonLeaf:
   return "non-leaf";
 case FramePointerKind::All:
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 57f37c5023110..9b89b394cef52 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -7706,8 +7706,8 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">,
   MarshallingInfoFlag>;
 
 def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
-  HelpText<"Specify which frame pointers to retain.">, 
Values<"all,non-leaf,none">,
-  NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, 
NormalizedValues<["All", "NonLeaf", "None"]>,
+  HelpText<"Specify which frame pointers to retain.">, 
Values<"all,non-leaf,reserved,none">,
+  NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, 
NormalizedValues<["All", "NonLeaf", "Reserved", "None"]>,
   MarshallingInfoEnum, "None">;
 
 
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 97449a5e51e73..65d82285b907b 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1917,6 +1917,7 @@ static void getTrivialDefaultFunctionAttributes(
 case CodeGenOptions::FramePointerKind::None:
   // This is the default behavior.
   break;
+case CodeGenOptions::FramePointerKind::Reserved:
 case CodeGenOptions::FramePointerKind::NonLeaf:
 case CodeGenOptions::FramePointerKind::All:
   FuncAttrs.addAttribute("frame-pointer",
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index be7bf0b72dc0c..75b1449090389 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1328,6 +1328,9 @@ void CodeGenModule::Release() {
   case CodeGenOptions:

[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -0,0 +1,81 @@
+//=== ModuleDependencyScanner.cpp *- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "ModuleDependencyScanner.h"
+#include "support/Logger.h"
+
+namespace clang {
+namespace clangd {
+
+std::optional
+ModuleDependencyScanner::scan(PathRef FilePath) {
+  std::optional Cmd = CDB.getCompileCommand(FilePath);
+
+  if (!Cmd)
+return std::nullopt;
+
+  using namespace clang::tooling::dependencies;
+
+  llvm::SmallString<128> FilePathDir(FilePath);
+  llvm::sys::path::remove_filename(FilePathDir);
+  DependencyScanningTool ScanningTool(Service, TFS.view(FilePathDir));
+
+  llvm::Expected ScanningResult =
+  ScanningTool.getP1689ModuleDependencyFile(*Cmd, Cmd->Directory);
+
+  if (auto E = ScanningResult.takeError()) {
+log("Scanning modules dependencies for {0} failed: {1}", FilePath,
+llvm::toString(std::move(E)));
+return std::nullopt;
+  }
+
+  ModuleDependencyInfo Result;
+
+  if (ScanningResult->Provides) {
+ModuleNameToSource[ScanningResult->Provides->ModuleName] = FilePath;

ChuanqiXu9 wrote:

> Are we really going into all this complexity to optimize the case of files 
> with no modular dependencies? 

Yes, this is primarily the reason why we delay it.

> files with no modular dependencies is going to be so rare in practice

This assumption is not true to me unless we're talking about the ecosystem 10+ 
years later. (There is a website (https://arewemodulesyet.org/) tracking the 
progress. Although its progress bar is almost a joke).

Since programmers needs to refactor their code to use C++20 modules, we believe 
there will still be a lot of files unrelated to modules exists. Especially for 
headers.

To make this more clear, currently, there are 2 ways to use modules. One is to 
use modules extensively and get rid of headers. Examples are 
https://github.com/infiniflow/infinity and 
https://github.com/davidstone/technical-machine, where we can see rare headers 
and almost all the files are related to modules.

However, there are more projects are simply wrapped themselves with modules, so 
that the users can consume the library by including or by importing by their 
interest. (Or even importing in some .cc and including in some other .cc if the 
size of the code bases it too big). Most projects on the previous mentioned 
website uses this model. From the perspective, I think the assumption that 
modules-native (I called it) style won't take the place all over the world soon.

> so having this extra mental load and requirements about an implementation 
> detail that doesn't bring much benefits in practice, and planned to be 
> stripped away is just too much for maintenance.

Of course, since the first patch is not focus on  performance and the design, I 
can drop it if you really don't like it.


https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -740,6 +741,21 @@ 
DirectoryBasedGlobalCompilationDatabase::getProjectInfo(PathRef File) const {
   return Res->PI;
 }
 
+std::shared_ptr
+DirectoryBasedGlobalCompilationDatabase::getProjectModules(PathRef File) const 
{
+  CDBLookupRequest Req;
+  Req.FileName = File;
+  Req.ShouldBroadcast = false;
+  Req.FreshTime = Req.FreshTimeMissing =
+  std::chrono::steady_clock::time_point::min();
+  auto Res = lookupCDB(Req);
+  if (!Res)
+return {};
+  return ProjectModules::create(
+  ProjectModules::ProjectModulesKind::ScanningAllFiles,
+  Res->CDB->getAllFiles(), *this, Opts.TFS);

ChuanqiXu9 wrote:

Done by following other comments.

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -222,6 +222,9 @@ class TUScheduler {
 /// Cache (large) preamble data in RAM rather than temporary files on disk.
 bool StorePreamblesInMemory = false;
 
+/// Enable experimental support for modules.
+bool ExperimentalModulesSupport = false;

ChuanqiXu9 wrote:

Done

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -42,6 +42,8 @@
 
 namespace clang {
 namespace clangd {
+
+class ModulesBuilder;

ChuanqiXu9 wrote:

Done

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits




ChuanqiXu9 wrote:

Done

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -0,0 +1,339 @@
+//===- ModulesBuilder.cpp *- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "ModulesBuilder.h"
+#include "PrerequisiteModules.h"
+#include "support/Logger.h"
+
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/FrontendActions.h"
+
+namespace clang {
+namespace clangd {
+
+namespace {
+
+/// Get or create a path to store module files. Generally it should be:
+///
+///   project_root/.cache/clangd/module_files/{RequiredPrefixDir}/.
+///
+/// \param MainFile is used to get the root of the project from global
+/// compilation database. \param RequiredPrefixDir is used to get the user
+/// defined prefix for module files. This is useful when we want to seperate
+/// module files. e.g., we want to build module files for the same module unit
+/// `a.cppm` with 2 different users `b.cpp` and `c.cpp` and we don't want the
+/// module file for `b.cpp` be conflict with the module files for `c.cpp`. Then
+/// we can put the 2 module files into different dirs like:
+///
+///   project_root/.cache/clangd/module_files/b.cpp/a.pcm
+///   project_root/.cache/clangd/module_files/c.cpp/a.pcm
+llvm::SmallString<256> getModuleFilesPath(PathRef MainFile,
+  const GlobalCompilationDatabase &CDB,
+  StringRef RequiredPrefixDir) {
+  std::optional PI = CDB.getProjectInfo(MainFile);
+  if (!PI)
+return {};
+
+  // FIXME: PI->SourceRoot may be empty, depending on the CDB strategy.
+  llvm::SmallString<256> Result(PI->SourceRoot);
+
+  llvm::sys::path::append(Result, ".cache");
+  llvm::sys::path::append(Result, "clangd");
+  llvm::sys::path::append(Result, "module_files");
+
+  llvm::sys::path::append(Result, RequiredPrefixDir);
+
+  llvm::sys::fs::create_directories(Result, /*IgnoreExisting=*/true);
+
+  return Result;
+}
+
+/// Get the absolute path for the filename from the compile command.
+llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) {
+  llvm::SmallString<128> AbsolutePath;
+  if (llvm::sys::path::is_absolute(Cmd.Filename)) {
+AbsolutePath = Cmd.Filename;
+  } else {
+AbsolutePath = Cmd.Directory;
+llvm::sys::path::append(AbsolutePath, Cmd.Filename);
+llvm::sys::path::remove_dots(AbsolutePath, true);
+  }
+  return AbsolutePath;
+}
+
+/// Get a unique module file path under \param ModuleFilesPrefix.
+std::string getUniqueModuleFilePath(StringRef ModuleName,
+PathRef ModuleFilesPrefix) {
+  llvm::SmallString<256> ModuleFilePattern(ModuleFilesPrefix);
+  auto [PrimaryModuleName, PartitionName] = ModuleName.split(':');
+  llvm::sys::path::append(ModuleFilePattern, PrimaryModuleName);
+  if (!PartitionName.empty()) {
+ModuleFilePattern.append("-");
+ModuleFilePattern.append(PartitionName);
+  }
+
+  ModuleFilePattern.append("-%%-%%-%%-%%-%%-%%");
+  ModuleFilePattern.append(".pcm");
+
+  llvm::SmallString<256> ModuleFilePath;
+  llvm::sys::fs::createUniquePath(ModuleFilePattern, ModuleFilePath,
+  /*MakeAbsolute=*/false);
+
+  return (std::string)ModuleFilePath;
+}
+} // namespace
+
+bool ModulesBuilder::buildModuleFile(StringRef ModuleName,
+ const ThreadsafeFS *TFS,
+ std::shared_ptr MDB,
+ PathRef ModuleFilesPrefix,
+ PrerequisiteModules &BuiltModuleFiles) {
+  if (BuiltModuleFiles.isModuleUnitBuilt(ModuleName))
+return true;
+
+  PathRef ModuleUnitFileName = MDB->getSourceForModuleName(ModuleName);
+  /// It is possible that we're meeting third party modules (modules whose
+  /// source are not in the project. e.g, the std module may be a third-party
+  /// module for most project) or something wrong with the implementation of
+  /// ProjectModules.
+  /// FIXME: How should we treat third party modules here? If we want to ignore
+  /// third party modules, we should return true instead of false here.
+  /// Currently we simply bail out.
+  if (ModuleUnitFileName.empty())
+return false;
+
+  for (auto &RequiredModuleName : MDB->getRequiredModules(ModuleUnitFileName)) 
{
+// Return early if there are errors building the module file.
+if (!buildModuleFile(RequiredModuleName, TFS, MDB, ModuleFilesPrefix,
+ BuiltModuleFiles)) {
+  log("Failed to build module {0}", RequiredModuleName);
+  return false;
+}
+  }
+
+  auto Cmd = CDB.getCompileCommand(ModuleUnitFileName);
+  if (!Cmd)
+return false;
+
+  std::string ModuleFileName =
+  getUniqueModuleFilePath(ModuleName, M

[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -149,9 +154,13 @@ struct PreambleBuildStats {
 /// If \p PreambleCallback is set, it will be run on top of the AST while
 /// building the preamble.
 /// If Stats is not non-null, build statistics will be exported there.
+/// If \p RequiredModuleBuilder is not null, it will scan the source file
+/// to see if it is related to modules, and if yes, modules related things
+/// will be built.
 std::shared_ptr
 buildPreamble(PathRef FileName, CompilerInvocation CI,
   const ParseInputs &Inputs, bool StoreInMemory,
+  ModulesBuilder *RequiredModuleBuilder,

ChuanqiXu9 wrote:

Done

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits




ChuanqiXu9 wrote:

Done

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -192,8 +192,10 @@ TEST(PreamblePatchTest, PatchesPreambleIncludes) {
   TU.AdditionalFiles["b.h"] = "";
   TU.AdditionalFiles["c.h"] = "";
   auto PI = TU.inputs(FS);
-  auto BaselinePreamble = buildPreamble(
-  TU.Filename, *buildCompilerInvocation(PI, Diags), PI, true, nullptr);
+  MockCompilationDatabase CDB;
+  auto BaselinePreamble =
+  buildPreamble(TU.Filename, *buildCompilerInvocation(PI, Diags), PI, true,
+/*RequiredModuleBuilder=*/nullptr, nullptr);

ChuanqiXu9 wrote:

Agreed.  Done by adding an end-to-end test in the end of 
`PrerequisiteModulesTest.cpp`.

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -44,6 +44,8 @@ struct ParseOptions {
   bool ImportInsertions = false;
 };
 
+class ModulesBuilder;

ChuanqiXu9 wrote:

Done

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -208,15 +208,16 @@ ClangdServer::Options::operator TUScheduler::Options() 
const {
   Opts.UpdateDebounce = UpdateDebounce;
   Opts.ContextProvider = ContextProvider;
   Opts.PreambleThrottler = PreambleThrottler;
+  Opts.ExperimentalModulesSupport = ExperimentalModulesSupport;

ChuanqiXu9 wrote:

Done

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -0,0 +1,115 @@
+//===- ModulesBuilder.h --*- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// Experimental support for C++20 Modules.
+//
+// Currently we simplify the implementations by preventing reusing module files
+// across different versions and different source files. But this is clearly a
+// waste of time and space in the end of the day.
+//
+// TODO: Supporting reusing module files across different versions and
+// different source files.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULES_BUILDER_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULES_BUILDER_H
+
+#include "GlobalCompilationDatabase.h"
+#include "ProjectModules.h"
+
+#include "support/Path.h"
+#include "support/ThreadsafeFS.h"
+
+#include "clang/Frontend/CompilerInvocation.h"
+
+#include "llvm/ADT/SmallString.h"
+
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// Store all the needed module files information to parse a single
+/// source file. e.g.,
+///
+///   ```
+///   // a.cppm
+///   export module a;
+///
+///   // b.cppm
+///   export module b;
+///   import a;
+///
+///   // c.cppm
+///   export module c;
+///   import a;
+///   ```
+///
+/// For the source file `c.cppm`, an instance of the class will store
+/// the module files for `a.cppm` and `b.cppm`. But the module file for 
`c.cppm`
+/// won't be stored. Since it is not needed to parse `c.cppm`.
+///
+/// Users should only get PrerequisiteModules from
+/// `ModulesBuilder::buildPrerequisiteModulesFor(...)`.
+///
+/// Users can detect whether the PrerequisiteModules is still up to date by
+/// calling the `canReuse()` member function.
+///
+/// The users should call `adjustHeaderSearchOptions(...)` to update the
+/// compilation commands to select the built module files first. Before calling
+/// `adjustHeaderSearchOptions()`, users should call `canReuse()` first to 
check
+/// if all the stored module files are valid. In case they are not valid,
+/// users should call `ModulesBuilder::buildPrerequisiteModulesFor(...)` again
+/// to get the new PrerequisiteModules.
+class PrerequisiteModules {
+public:
+  /// Change commands to load the module files recorded in this
+  /// PrerequisiteModules first.
+  virtual void
+  adjustHeaderSearchOptions(HeaderSearchOptions &Options) const = 0;
+
+  /// Whether or not the built module files are up to date.
+  /// Note that this can only be used after building the module files.
+  virtual bool
+  canReuse(const CompilerInvocation &CI,
+   llvm::IntrusiveRefCntPtr) const = 0;
+
+  /// Return true if the modile file specified by ModuleName is built.
+  /// Note that this interface will only check the existence of the module
+  /// file instead of checking the validness of the module file.
+  virtual bool isModuleUnitBuilt(llvm::StringRef ModuleName) const = 0;
+
+  virtual ~PrerequisiteModules() = default;
+};
+
+/// This class handles building module files for a given source file.
+///
+/// In the future, we want the class to manage the module files acorss
+/// different versions and different source files.
+class ModulesBuilder {
+public:
+  ModulesBuilder(const GlobalCompilationDatabase &CDB) : CDB(CDB) {}
+
+  ModulesBuilder(const ModulesBuilder &) = delete;
+  ModulesBuilder(ModulesBuilder &&) = delete;
+
+  ModulesBuilder &operator=(const ModulesBuilder &) = delete;
+  ModulesBuilder &operator=(ModulesBuilder &&) = delete;
+
+  std::unique_ptr
+  buildPrerequisiteModulesFor(PathRef File, const ThreadsafeFS *TFS) const;

ChuanqiXu9 wrote:

Done

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -0,0 +1,370 @@
+//===- ModulesBuilder.cpp *- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "ModulesBuilder.h"
+
+#include "Compiler.h"
+#include "support/Logger.h"
+
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/FrontendActions.h"
+
+#include "clang/Serialization/ASTReader.h"
+
+namespace clang {
+namespace clangd {
+
+namespace {
+
+// Create a path to store module files. Generally it should be:
+//
+//   {TEMP_DIRS}/clangd/module_files/{PrefixDir}-%%-%%-%%-%%-%%-%%/.
+//
+// {TEMP_DIRS} is the temporary directory for the system, e.g., "/var/tmp"
+// or "C:/TEMP".
+//
+// '%%' means random value to make the generated path unique.
+//
+// \param MainFile is used to get the root of the project from global
+// compilation database. \param PrefixDir is used to get the user
+// defined prefix for module files. This is useful when we want to seperate
+// module files. e.g., we want to build module files for the same module unit
+// `a.cppm` with 2 different users `b.cpp` and `c.cpp` and we don't want the
+// module file for `b.cpp` be conflict with the module files for `c.cpp`. Then
+// we can put the 2 module files into different dirs like:
+//
+//   ${TEMP_DIRS}/clangd/module_files/b.cpp/a.pcm
+//   ${TEMP_DIRS}/clangd/module_files/c.cpp/a.pcm
+//
+// TODO: Move these module fils out of the temporary directory if the module
+// files are persistent.
+llvm::SmallString<256> getUniqueModuleFilesPath(PathRef MainFile,
+llvm::StringRef PrefixDir) {
+  llvm::SmallString<256> ResultPattern;
+
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/true,
+ ResultPattern);
+
+  llvm::sys::path::append(ResultPattern, "clangd");
+  llvm::sys::path::append(ResultPattern, "module_files");
+
+  llvm::sys::path::append(ResultPattern, PrefixDir);
+
+  ResultPattern.append("-%%-%%-%%-%%-%%-%%");
+
+  llvm::SmallString<256> Result;
+  llvm::sys::fs::createUniquePath(ResultPattern, Result,
+  /*MakeAbsolute=*/false);
+
+  llvm::sys::fs::create_directories(Result);
+  return Result;
+}
+
+// Get the absolute path for the filename from the compile command.
+llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) {
+  llvm::SmallString<128> AbsolutePath;
+  if (llvm::sys::path::is_absolute(Cmd.Filename)) {
+AbsolutePath = Cmd.Filename;
+  } else {
+AbsolutePath = Cmd.Directory;
+llvm::sys::path::append(AbsolutePath, Cmd.Filename);
+llvm::sys::path::remove_dots(AbsolutePath, true);
+  }
+  return AbsolutePath;
+}
+
+// Get a unique module file path under \param ModuleFilesPrefix.
+std::string getModuleFilePath(llvm::StringRef ModuleName,
+  PathRef ModuleFilesPrefix) {
+  llvm::SmallString<256> ModuleFilePattern(ModuleFilesPrefix);
+  auto [PrimaryModuleName, PartitionName] = ModuleName.split(':');
+  llvm::sys::path::append(ModuleFilePattern, PrimaryModuleName);
+  if (!PartitionName.empty()) {
+ModuleFilePattern.append("-");
+ModuleFilePattern.append(PartitionName);
+  }
+
+  ModuleFilePattern.append(".pcm");
+
+  llvm::SmallString<256> ModuleFilePath;
+  llvm::sys::fs::createUniquePath(ModuleFilePattern, ModuleFilePath,
+  /*MakeAbsolute=*/false);
+
+  return std::string(ModuleFilePath);
+}
+} // namespace
+
+// FailedPrerequisiteModules - stands for the PrerequisiteModules which has
+// errors happened during the building process.
+class FailedPrerequisiteModules : public PrerequisiteModules {
+public:
+  ~FailedPrerequisiteModules() override = default;
+
+  // We shouldn't adjust the compilation commands based on
+  // FailedPrerequisiteModules.
+  void adjustHeaderSearchOptions(HeaderSearchOptions &Options) const override {
+  }
+
+  // FailedPrerequisiteModules can never be reused.
+  bool
+  canReuse(const CompilerInvocation &CI,
+   llvm::IntrusiveRefCntPtr) const override {
+return false;
+  }
+
+  // No module unit got built in FailedPrerequisiteModules.
+  bool isModuleUnitBuilt(llvm::StringRef ModuleName) const override {
+return false;
+  }
+};
+
+// StandalonePrerequisiteModules - stands for PrerequisiteModules for which all
+// the required modules are built successfully. All the module files
+// are owned by the StandalonePrerequisiteModules class.
+//
+// Any of the built module files won't be shared with other instances of the
+// class. So that we can avoid worrying thread safety.
+//
+// We don't need to worry about duplicated module names here since the standard
+// guarantees the module names should be unique to a pr

[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -0,0 +1,370 @@
+//===- ModulesBuilder.cpp *- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "ModulesBuilder.h"
+
+#include "Compiler.h"
+#include "support/Logger.h"
+
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/FrontendActions.h"
+
+#include "clang/Serialization/ASTReader.h"
+
+namespace clang {
+namespace clangd {
+
+namespace {
+
+// Create a path to store module files. Generally it should be:
+//
+//   {TEMP_DIRS}/clangd/module_files/{PrefixDir}-%%-%%-%%-%%-%%-%%/.
+//
+// {TEMP_DIRS} is the temporary directory for the system, e.g., "/var/tmp"
+// or "C:/TEMP".
+//
+// '%%' means random value to make the generated path unique.
+//
+// \param MainFile is used to get the root of the project from global
+// compilation database. \param PrefixDir is used to get the user
+// defined prefix for module files. This is useful when we want to seperate
+// module files. e.g., we want to build module files for the same module unit
+// `a.cppm` with 2 different users `b.cpp` and `c.cpp` and we don't want the
+// module file for `b.cpp` be conflict with the module files for `c.cpp`. Then
+// we can put the 2 module files into different dirs like:
+//
+//   ${TEMP_DIRS}/clangd/module_files/b.cpp/a.pcm
+//   ${TEMP_DIRS}/clangd/module_files/c.cpp/a.pcm
+//
+// TODO: Move these module fils out of the temporary directory if the module
+// files are persistent.
+llvm::SmallString<256> getUniqueModuleFilesPath(PathRef MainFile,
+llvm::StringRef PrefixDir) {
+  llvm::SmallString<256> ResultPattern;
+
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/true,
+ ResultPattern);
+
+  llvm::sys::path::append(ResultPattern, "clangd");
+  llvm::sys::path::append(ResultPattern, "module_files");
+
+  llvm::sys::path::append(ResultPattern, PrefixDir);
+
+  ResultPattern.append("-%%-%%-%%-%%-%%-%%");
+
+  llvm::SmallString<256> Result;
+  llvm::sys::fs::createUniquePath(ResultPattern, Result,
+  /*MakeAbsolute=*/false);
+
+  llvm::sys::fs::create_directories(Result);
+  return Result;
+}
+
+// Get the absolute path for the filename from the compile command.
+llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) {
+  llvm::SmallString<128> AbsolutePath;
+  if (llvm::sys::path::is_absolute(Cmd.Filename)) {
+AbsolutePath = Cmd.Filename;
+  } else {
+AbsolutePath = Cmd.Directory;
+llvm::sys::path::append(AbsolutePath, Cmd.Filename);
+llvm::sys::path::remove_dots(AbsolutePath, true);
+  }
+  return AbsolutePath;
+}
+
+// Get a unique module file path under \param ModuleFilesPrefix.
+std::string getModuleFilePath(llvm::StringRef ModuleName,
+  PathRef ModuleFilesPrefix) {
+  llvm::SmallString<256> ModuleFilePattern(ModuleFilesPrefix);
+  auto [PrimaryModuleName, PartitionName] = ModuleName.split(':');
+  llvm::sys::path::append(ModuleFilePattern, PrimaryModuleName);
+  if (!PartitionName.empty()) {
+ModuleFilePattern.append("-");
+ModuleFilePattern.append(PartitionName);
+  }
+
+  ModuleFilePattern.append(".pcm");
+
+  llvm::SmallString<256> ModuleFilePath;
+  llvm::sys::fs::createUniquePath(ModuleFilePattern, ModuleFilePath,
+  /*MakeAbsolute=*/false);
+
+  return std::string(ModuleFilePath);
+}
+} // namespace
+
+// FailedPrerequisiteModules - stands for the PrerequisiteModules which has
+// errors happened during the building process.
+class FailedPrerequisiteModules : public PrerequisiteModules {
+public:
+  ~FailedPrerequisiteModules() override = default;
+
+  // We shouldn't adjust the compilation commands based on
+  // FailedPrerequisiteModules.
+  void adjustHeaderSearchOptions(HeaderSearchOptions &Options) const override {
+  }
+
+  // FailedPrerequisiteModules can never be reused.
+  bool
+  canReuse(const CompilerInvocation &CI,
+   llvm::IntrusiveRefCntPtr) const override {
+return false;
+  }
+
+  // No module unit got built in FailedPrerequisiteModules.
+  bool isModuleUnitBuilt(llvm::StringRef ModuleName) const override {
+return false;
+  }
+};
+
+// StandalonePrerequisiteModules - stands for PrerequisiteModules for which all
+// the required modules are built successfully. All the module files
+// are owned by the StandalonePrerequisiteModules class.
+//
+// Any of the built module files won't be shared with other instances of the
+// class. So that we can avoid worrying thread safety.
+//
+// We don't need to worry about duplicated module names here since the standard
+// guarantees the module names should be unique to a pr

[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -0,0 +1,115 @@
+//===- ModulesBuilder.h --*- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// Experimental support for C++20 Modules.
+//
+// Currently we simplify the implementations by preventing reusing module files
+// across different versions and different source files. But this is clearly a
+// waste of time and space in the end of the day.
+//
+// TODO: Supporting reusing module files across different versions and
+// different source files.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULES_BUILDER_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULES_BUILDER_H
+
+#include "GlobalCompilationDatabase.h"
+#include "ProjectModules.h"
+
+#include "support/Path.h"
+#include "support/ThreadsafeFS.h"
+
+#include "clang/Frontend/CompilerInvocation.h"
+
+#include "llvm/ADT/SmallString.h"
+
+#include 
+
+namespace clang {
+namespace clangd {
+
+/// Store all the needed module files information to parse a single
+/// source file. e.g.,
+///
+///   ```
+///   // a.cppm
+///   export module a;
+///
+///   // b.cppm
+///   export module b;
+///   import a;
+///
+///   // c.cppm
+///   export module c;
+///   import a;
+///   ```
+///
+/// For the source file `c.cppm`, an instance of the class will store
+/// the module files for `a.cppm` and `b.cppm`. But the module file for 
`c.cppm`
+/// won't be stored. Since it is not needed to parse `c.cppm`.
+///
+/// Users should only get PrerequisiteModules from
+/// `ModulesBuilder::buildPrerequisiteModulesFor(...)`.
+///
+/// Users can detect whether the PrerequisiteModules is still up to date by
+/// calling the `canReuse()` member function.
+///
+/// The users should call `adjustHeaderSearchOptions(...)` to update the
+/// compilation commands to select the built module files first. Before calling
+/// `adjustHeaderSearchOptions()`, users should call `canReuse()` first to 
check
+/// if all the stored module files are valid. In case they are not valid,
+/// users should call `ModulesBuilder::buildPrerequisiteModulesFor(...)` again
+/// to get the new PrerequisiteModules.
+class PrerequisiteModules {
+public:
+  /// Change commands to load the module files recorded in this
+  /// PrerequisiteModules first.
+  virtual void
+  adjustHeaderSearchOptions(HeaderSearchOptions &Options) const = 0;
+
+  /// Whether or not the built module files are up to date.
+  /// Note that this can only be used after building the module files.
+  virtual bool
+  canReuse(const CompilerInvocation &CI,
+   llvm::IntrusiveRefCntPtr) const = 0;
+
+  /// Return true if the modile file specified by ModuleName is built.
+  /// Note that this interface will only check the existence of the module
+  /// file instead of checking the validness of the module file.
+  virtual bool isModuleUnitBuilt(llvm::StringRef ModuleName) const = 0;

ChuanqiXu9 wrote:

Done

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -0,0 +1,370 @@
+//===- ModulesBuilder.cpp *- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "ModulesBuilder.h"
+
+#include "Compiler.h"
+#include "support/Logger.h"
+
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/FrontendActions.h"
+
+#include "clang/Serialization/ASTReader.h"
+
+namespace clang {
+namespace clangd {
+
+namespace {
+
+// Create a path to store module files. Generally it should be:
+//
+//   {TEMP_DIRS}/clangd/module_files/{PrefixDir}-%%-%%-%%-%%-%%-%%/.
+//
+// {TEMP_DIRS} is the temporary directory for the system, e.g., "/var/tmp"
+// or "C:/TEMP".
+//
+// '%%' means random value to make the generated path unique.
+//
+// \param MainFile is used to get the root of the project from global
+// compilation database. \param PrefixDir is used to get the user
+// defined prefix for module files. This is useful when we want to seperate
+// module files. e.g., we want to build module files for the same module unit
+// `a.cppm` with 2 different users `b.cpp` and `c.cpp` and we don't want the
+// module file for `b.cpp` be conflict with the module files for `c.cpp`. Then
+// we can put the 2 module files into different dirs like:
+//
+//   ${TEMP_DIRS}/clangd/module_files/b.cpp/a.pcm
+//   ${TEMP_DIRS}/clangd/module_files/c.cpp/a.pcm
+//
+// TODO: Move these module fils out of the temporary directory if the module
+// files are persistent.
+llvm::SmallString<256> getUniqueModuleFilesPath(PathRef MainFile,
+llvm::StringRef PrefixDir) {
+  llvm::SmallString<256> ResultPattern;
+
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/true,
+ ResultPattern);
+
+  llvm::sys::path::append(ResultPattern, "clangd");
+  llvm::sys::path::append(ResultPattern, "module_files");
+
+  llvm::sys::path::append(ResultPattern, PrefixDir);
+
+  ResultPattern.append("-%%-%%-%%-%%-%%-%%");
+
+  llvm::SmallString<256> Result;
+  llvm::sys::fs::createUniquePath(ResultPattern, Result,
+  /*MakeAbsolute=*/false);
+
+  llvm::sys::fs::create_directories(Result);
+  return Result;
+}
+
+// Get the absolute path for the filename from the compile command.
+llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) {
+  llvm::SmallString<128> AbsolutePath;
+  if (llvm::sys::path::is_absolute(Cmd.Filename)) {
+AbsolutePath = Cmd.Filename;
+  } else {
+AbsolutePath = Cmd.Directory;
+llvm::sys::path::append(AbsolutePath, Cmd.Filename);
+llvm::sys::path::remove_dots(AbsolutePath, true);
+  }
+  return AbsolutePath;
+}
+
+// Get a unique module file path under \param ModuleFilesPrefix.
+std::string getModuleFilePath(llvm::StringRef ModuleName,
+  PathRef ModuleFilesPrefix) {
+  llvm::SmallString<256> ModuleFilePattern(ModuleFilesPrefix);
+  auto [PrimaryModuleName, PartitionName] = ModuleName.split(':');
+  llvm::sys::path::append(ModuleFilePattern, PrimaryModuleName);
+  if (!PartitionName.empty()) {
+ModuleFilePattern.append("-");
+ModuleFilePattern.append(PartitionName);
+  }
+
+  ModuleFilePattern.append(".pcm");
+
+  llvm::SmallString<256> ModuleFilePath;
+  llvm::sys::fs::createUniquePath(ModuleFilePattern, ModuleFilePath,
+  /*MakeAbsolute=*/false);
+
+  return std::string(ModuleFilePath);
+}
+} // namespace
+
+// FailedPrerequisiteModules - stands for the PrerequisiteModules which has
+// errors happened during the building process.
+class FailedPrerequisiteModules : public PrerequisiteModules {
+public:
+  ~FailedPrerequisiteModules() override = default;
+
+  // We shouldn't adjust the compilation commands based on
+  // FailedPrerequisiteModules.
+  void adjustHeaderSearchOptions(HeaderSearchOptions &Options) const override {
+  }
+
+  // FailedPrerequisiteModules can never be reused.
+  bool
+  canReuse(const CompilerInvocation &CI,
+   llvm::IntrusiveRefCntPtr) const override {
+return false;
+  }
+
+  // No module unit got built in FailedPrerequisiteModules.
+  bool isModuleUnitBuilt(llvm::StringRef ModuleName) const override {
+return false;
+  }
+};
+
+// StandalonePrerequisiteModules - stands for PrerequisiteModules for which all
+// the required modules are built successfully. All the module files
+// are owned by the StandalonePrerequisiteModules class.
+//
+// Any of the built module files won't be shared with other instances of the
+// class. So that we can avoid worrying thread safety.
+//
+// We don't need to worry about duplicated module names here since the standard
+// guarantees the module names should be unique to a pr

[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits




ChuanqiXu9 wrote:

Done

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits


@@ -0,0 +1,87 @@
+//===- PrerequisiteModules.h -*- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREREQUISITEMODULES_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREREQUISITEMODULES_H
+
+#include "Compiler.h"
+#include "support/Path.h"
+
+#include "clang/Lex/HeaderSearchOptions.h"
+
+#include "llvm/ADT/StringSet.h"
+
+namespace clang {
+namespace clangd {
+
+class ModulesBuilder;
+
+/// Store all the needed module files information to parse a single
+/// source file. e.g.,
+///
+///   ```
+///   // a.cppm
+///   export module a;
+///
+///   // b.cppm
+///   export module b;
+///   import a;
+///
+///   // c.cppm
+///   export module c;
+///   import a;
+///   ```
+///
+/// For the source file `c.cppm`, an instance of the class will store
+/// the module files for `a.cppm` and `b.cppm`. But the module file for 
`c.cppm`

ChuanqiXu9 wrote:

Oh, nice catch. The things written is not consistent with what I thought. I've 
refactored it. Thanks.

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] `doesNotMutateObject`: Handle calls to member functions … (PR #94362)

2024-06-06 Thread Clement Courbet via cfe-commits

https://github.com/legrosbuffle updated 
https://github.com/llvm/llvm-project/pull/94362

>From 8a7e3ee49295b55193440da6b796c9ada43ee5ef Mon Sep 17 00:00:00 2001
From: Clement Courbet 
Date: Tue, 4 Jun 2024 12:49:39 +
Subject: [PATCH 1/2] [clang-tidy] `doesNotMutateObject`: Handle calls to
 member functions and operators that have non-const overloads.

This allows  `unnecessary-copy-initialization` to warn on more cases.

The common case is a class with a a set of const/non-sconst overloads
(e.g. std::vector::operator[]).

```
void F() {
  std::vector v;
  // ...

  const Expensive e = v[i];
}
```
---
 .../UnnecessaryCopyInitialization.cpp |  21 ++-
 .../clang-tidy/utils/DeclRefExprUtils.cpp | 163 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   4 +-
 .../unnecessary-copy-initialization.cpp   |  29 +++-
 .../clang-tidy/DeclRefExprUtilsTest.cpp   |  39 -
 5 files changed, 229 insertions(+), 27 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp 
b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
index 9beb185cba929..78a1f9a73687d 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -75,16 +75,15 @@ void recordRemoval(const DeclStmt &Stmt, ASTContext 
&Context,
   }
 }
 
-AST_MATCHER_FUNCTION_P(StatementMatcher, isConstRefReturningMethodCall,
+AST_MATCHER_FUNCTION_P(StatementMatcher, isRefReturningMethodCall,
std::vector, ExcludedContainerTypes) {
   // Match method call expressions where the `this` argument is only used as
-  // const, this will be checked in `check()` part. This returned const
-  // reference is highly likely to outlive the local const reference of the
-  // variable being declared. The assumption is that the const reference being
-  // returned either points to a global static variable or to a member of the
-  // called object.
+  // const, this will be checked in `check()` part. This returned reference is
+  // highly likely to outlive the local const reference of the variable being
+  // declared. The assumption is that the reference being returned either 
points
+  // to a global static variable or to a member of the called object.
   const auto MethodDecl =
-  cxxMethodDecl(returns(hasCanonicalType(matchers::isReferenceToConst(
+  cxxMethodDecl(returns(hasCanonicalType(referenceType(
   .bind(MethodDeclId);
   const auto ReceiverExpr =
   ignoringParenImpCasts(declRefExpr(to(varDecl().bind(ObjectArgId;
@@ -121,7 +120,7 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, 
initializerReturnsReferenceToConst,
   declRefExpr(to(varDecl(hasLocalStorage()).bind(OldVarDeclId)));
   return expr(
   anyOf(isConstRefReturningFunctionCall(),
-isConstRefReturningMethodCall(ExcludedContainerTypes),
+isRefReturningMethodCall(ExcludedContainerTypes),
 ignoringImpCasts(OldVarDeclRef),
 ignoringImpCasts(unaryOperator(hasOperatorName("&"),
hasUnaryOperand(OldVarDeclRef);
@@ -259,9 +258,9 @@ void 
UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) {
 .bind("blockStmt");
   };
 
-  
Finder->addMatcher(LocalVarCopiedFrom(anyOf(isConstRefReturningFunctionCall(),
-  isConstRefReturningMethodCall(
-  ExcludedContainerTypes))),
+  Finder->addMatcher(LocalVarCopiedFrom(anyOf(
+ isConstRefReturningFunctionCall(),
+ isRefReturningMethodCall(ExcludedContainerTypes))),
  this);
 
   Finder->addMatcher(LocalVarCopiedFrom(declRefExpr(
diff --git a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp 
b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
index a48e45e135681..4ee8a3628061b 100644
--- a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
+++ b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
@@ -36,6 +36,111 @@ void extractNodesByIdTo(ArrayRef Matches, 
StringRef ID,
 Nodes.insert(Match.getNodeAs(ID));
 }
 
+// If `D` has a const-qualified overload with otherwise identical
+// ref-qualifiers, returns that overload.
+const CXXMethodDecl *findConstOverload(const CXXMethodDecl &D) {
+  assert(!D.isConst());
+
+  DeclContext::lookup_result lookup_result =
+  D.getParent()->lookup(D.getNameInfo().getName());
+  if (lookup_result.isSingleResult()) {
+// No overload.
+return nullptr;
+  }
+  for (const Decl *overload : lookup_result) {
+const CXXMethodDecl *candidate = dyn_cast(overload);
+if (candidate && !candidate->isDeleted() && candidate->isConst() &&
+candidate->getRefQualifier() == D.getRefQualifier()) {
+  return candidate;
+}
+  }
+  return nullptr;
+}
+
+// Returns true

[clang] [llvm] [ARM] r11 is reserved when using -mframe-chain=aapcs (PR #86951)

2024-06-06 Thread via cfe-commits

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 eea05c6b3369736b703e2a5e3ca08ba6ad8a51dc 
7272dd8f58e9f445f758a10ae3d91aaa166c91f1 -- 
clang/include/clang/Basic/CodeGenOptions.h clang/lib/CodeGen/CGCall.cpp 
clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/ToolChains/Arch/ARM.cpp 
clang/lib/Driver/ToolChains/Clang.cpp 
clang/lib/Driver/ToolChains/CommonArgs.cpp llvm/include/llvm/Support/CodeGen.h 
llvm/include/llvm/Target/TargetOptions.h llvm/lib/CodeGen/CommandFlags.cpp 
llvm/lib/CodeGen/TargetOptionsImpl.cpp llvm/lib/IR/Function.cpp 
llvm/lib/IR/Verifier.cpp llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp 
llvm/lib/Target/ARM/ARMFrameLowering.cpp llvm/lib/Target/ARM/ARMFrameLowering.h
``





View the diff from clang-format here.


``diff
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 6887926cb3..00523a84d3 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -127,10 +127,10 @@ public:
   std::string BinutilsVersion;
 
   enum class FramePointerKind {
-None,// Omit all frame pointers.
-Reserved,// Maintain valid frame pointer chain.
-NonLeaf, // Keep non-leaf frame pointers.
-All, // Keep all frame pointers.
+None, // Omit all frame pointers.
+Reserved, // Maintain valid frame pointer chain.
+NonLeaf,  // Keep non-leaf frame pointers.
+All,  // Keep all frame pointers.
   };
 
   static StringRef getFramePointerKindName(FramePointerKind Kind) {
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 61c8f6812c..2a4c1369f5 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -166,7 +166,7 @@ static bool useFramePointerForTargetByDefault(const 
llvm::opt::ArgList &Args,
 
 static bool useLeafFramePointerForTargetByDefault(const llvm::Triple &Triple) {
   if (Triple.isAArch64() || Triple.isPS() || Triple.isVE() ||
-(Triple.isAndroid() && Triple.isRISCV64()))
+  (Triple.isAndroid() && Triple.isRISCV64()))
 return false;
 
   return true;

``




https://github.com/llvm/llvm-project/pull/86951
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-06 Thread Jon Chesterfield via cfe-commits


@@ -992,6 +993,8 @@ void AMDGPUPassConfig::addIRPasses() {
   if (isPassEnabled(EnableImageIntrinsicOptimizer))
 addPass(createAMDGPUImageIntrinsicOptimizerPass(&TM));
 
+  addPass(createExpandVariadicsPass(ExpandVariadicsMode::Lowering));

JonChesterfield wrote:

I'm also paranoid enough to want that, it's 
'--expand-variadics-override=disable' from the command line or changing the 
::Lowering in that line to ::Disable. Commenting out the addPass also kills it, 
but would cause the lit pipeline tests to fail. I'll put a comment above that 
pass saying this.

https://github.com/llvm/llvm-project/pull/93362
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [serialization] no transitive decl change (PR #92083)

2024-06-06 Thread David Spickett via cfe-commits

DavidSpickett wrote:

> Thanks. Reproduced. But it surprised me that I can't run the commands you 
> mentioned, but I need to run:
> ./bin/lldb-dotest -p TestTemplateWithSameArg.py -G gmodules

Running the tests as modules is perhaps opt in, we have the ability to run them 
with different debug info types too. So this is not surprising. Well, it is for 
you, but doesn't mean there's anything wrong here :)

> And I am also slightly surprised that after I change the code, it doesn't 
> work if I run ninja lldb-test only I need to run ninja clang lldb. Do I 
> misconfigure anything? I build lldb by:

My comment about `lld-test` referred to a different failing test I think (and 
if we did have some dependencies incorrect, it wouldn't surprise me). Nothing 
wrong with that config line though.

So good news is Linux and Windows lldb are ok (Mac will report back soon I 
assume), but now we have failures on 32 bit Arm builds:
https://lab.llvm.org/buildbot/#/builders/245/builds/25498

I'm going to reproduce this shortly but my bet is that this is undefined 
behaviour of some kind. It may not be due to your code but your code may be 
exposing a pre-existing issue.

https://github.com/llvm/llvm-project/pull/92083
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [ARM] r11 is reserved when using -mframe-chain=aapcs (PR #86951)

2024-06-06 Thread via cfe-commits

https://github.com/ostannard updated 
https://github.com/llvm/llvm-project/pull/86951

>From 1e141e80b0abf45f160c06f8eb39623df16434d8 Mon Sep 17 00:00:00 2001
From: Oliver Stannard 
Date: Thu, 6 Jun 2024 09:34:13 +0100
Subject: [PATCH 1/4] [IR] Add target-independent option to preserve
 frame-pointer register

This adds a new value "reserved" to the "frame-pointer" function
attribute. When this value is used, the frame pointer register must
either be reserved, or updated to point to a new frame record, but must
not be used for any other purpose.

This is not yet supported by most targets, but will be used for the Arm
-mframe-chain= option.
---
 clang/include/clang/Basic/CodeGenOptions.def |  2 +-
 clang/include/clang/Basic/CodeGenOptions.h   |  3 +++
 clang/include/clang/Driver/Options.td|  4 ++--
 clang/lib/CodeGen/CGCall.cpp |  1 +
 clang/lib/CodeGen/CodeGenModule.cpp  |  3 +++
 clang/lib/Driver/ToolChains/Clang.cpp|  3 +++
 llvm/docs/LangRef.rst|  6 +-
 llvm/include/llvm/Support/CodeGen.h  |  2 +-
 llvm/include/llvm/Target/TargetOptions.h |  5 +
 llvm/lib/CodeGen/CommandFlags.cpp|  5 +
 llvm/lib/CodeGen/TargetOptionsImpl.cpp   | 21 ++--
 llvm/lib/IR/Function.cpp |  3 +++
 llvm/lib/IR/Verifier.cpp |  2 +-
 13 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 07b0ca1691a67..7ffc40a00504f 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -61,7 +61,7 @@ CODEGENOPT(SeparateNamedSections, 1, 0) ///< Set for 
-fseparate-named-sections.
 CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. 
Enables the extended Altivec ABI on AIX.
 CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr.
 CODEGENOPT(AllTocData, 1, 0) ///< AIX -mtocdata
-ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// 
frame-pointer: all,non-leaf,none
+ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// 
frame-pointer: all,non-leaf,reserved,none
 
 CODEGENOPT(ClearASTBeforeBackend , 1, 0) ///< Free the AST before running 
backend code generation. Only works with -disable-free.
 CODEGENOPT(DisableFree   , 1, 0) ///< Don't free memory.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb..6887926cb34da 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -128,6 +128,7 @@ class CodeGenOptions : public CodeGenOptionsBase {
 
   enum class FramePointerKind {
 None,// Omit all frame pointers.
+Reserved,// Maintain valid frame pointer chain.
 NonLeaf, // Keep non-leaf frame pointers.
 All, // Keep all frame pointers.
   };
@@ -136,6 +137,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
 switch (Kind) {
 case FramePointerKind::None:
   return "none";
+case FramePointerKind::Reserved:
+  return "reserved";
 case FramePointerKind::NonLeaf:
   return "non-leaf";
 case FramePointerKind::All:
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 57f37c5023110..9b89b394cef52 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -7706,8 +7706,8 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">,
   MarshallingInfoFlag>;
 
 def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
-  HelpText<"Specify which frame pointers to retain.">, 
Values<"all,non-leaf,none">,
-  NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, 
NormalizedValues<["All", "NonLeaf", "None"]>,
+  HelpText<"Specify which frame pointers to retain.">, 
Values<"all,non-leaf,reserved,none">,
+  NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, 
NormalizedValues<["All", "NonLeaf", "Reserved", "None"]>,
   MarshallingInfoEnum, "None">;
 
 
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 97449a5e51e73..65d82285b907b 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1917,6 +1917,7 @@ static void getTrivialDefaultFunctionAttributes(
 case CodeGenOptions::FramePointerKind::None:
   // This is the default behavior.
   break;
+case CodeGenOptions::FramePointerKind::Reserved:
 case CodeGenOptions::FramePointerKind::NonLeaf:
 case CodeGenOptions::FramePointerKind::All:
   FuncAttrs.addAttribute("frame-pointer",
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index be7bf0b72dc0c..75b1449090389 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1328,6 +1328,9 @@ void CodeGenModule::Release() {
   case CodeGenOptions:

[clang] a86c1e7 - [clang][Interp] Member Pointers (#91303)

2024-06-06 Thread via cfe-commits

Author: Timm Baeder
Date: 2024-06-06T11:17:48+02:00
New Revision: a86c1e7175d4acd8357326184bf4f88c8192676f

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

LOG: [clang][Interp] Member Pointers (#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`.

Added: 
clang/lib/AST/Interp/MemberPointer.cpp
clang/lib/AST/Interp/MemberPointer.h
clang/test/AST/Interp/memberpointers.cpp

Modified: 
clang/lib/AST/CMakeLists.txt
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/Context.cpp
clang/lib/AST/Interp/Context.h
clang/lib/AST/Interp/Descriptor.cpp
clang/lib/AST/Interp/Disasm.cpp
clang/lib/AST/Interp/Interp.cpp
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/InterpFrame.cpp
clang/lib/AST/Interp/InterpStack.cpp
clang/lib/AST/Interp/InterpStack.h
clang/lib/AST/Interp/Opcodes.td
clang/lib/AST/Interp/Pointer.cpp
clang/lib/AST/Interp/Pointer.h
clang/lib/AST/Interp/PrimType.cpp
clang/lib/AST/Interp/PrimType.h
clang/test/AST/Interp/eval-order.cpp
clang/test/AST/Interp/literals.cpp
clang/test/CodeGenCXX/pointers-to-data-members.cpp
clang/test/SemaCXX/attr-weak.cpp
clang/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
clang/unittests/AST/Interp/toAPValue.cpp

Removed: 




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 ea259639dace7..d124248a3605f 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)
+  return true;
+
+if (!this->emitCastMemberPtrPtr(BO))
+  return false;
+return DiscardResult ? this->emitPopPtr(BO) : true;
+  }
 
   // Typecheck the args.
   std::optional LT = classify(LHS->getType());
@@ -2773,6 +2819,8 @@ bool 
ByteCodeEx

[clang] [clang][Interp] Member Pointers (PR #91303)

2024-06-06 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
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-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits




ChuanqiXu9 wrote:

> I think that needs to happen eventually as well

Agreed.

> similar to preambles supporting in-memory storage, and it's actually not that 
> hard, GenerateModuleInterfaceAction already has an overrideable 
> CreateOutputFile method.

I am slightly confused. Do you say to move the IO to the memory instead of 
on-disk files? If true, we're close to that since we can write them to /tmp 
directories. I thought you're saying we need to get rid of the reading and 
writing process for module files.

> Also this comment is not solely about virtiualizing CDB, but also about the 
> way we're setting up tests. I don't think we need any of the compile flags 
> you're explicitly setting in the tests. The whole purpose of current 
> implementation is to rely on new module paths we provide into the 
> header-search-options. So there isn't any value in spelling those out 
> explicitly, rendering test setup more complicated. 

Agreed. In the new added test, I meant to use `TestTU` with `AdditionalFiles` 
to mimic a multiple module units project, but it fails. It looks like it can 
only accept headers. I feel there are a lot of spaces to improve. But I think 
it may be fine to leave it as is and improve this later. My plan after this 
patch is to make the module files reusable. I think the functionality to 
support modules in clangd is at least usable after that.

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] `doesNotMutateObject`: Handle calls to member functions … (PR #94362)

2024-06-06 Thread Clement Courbet via cfe-commits


@@ -259,9 +258,9 @@ void 
UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) {
 .bind("blockStmt");
   };
 
-  
Finder->addMatcher(LocalVarCopiedFrom(anyOf(isConstRefReturningFunctionCall(),
-  isConstRefReturningMethodCall(
-  ExcludedContainerTypes))),
+  Finder->addMatcher(LocalVarCopiedFrom(anyOf(
+ isConstRefReturningFunctionCall(),
+ isRefReturningMethodCall(ExcludedContainerTypes))),

legrosbuffle wrote:

Done

https://github.com/llvm/llvm-project/pull/94362
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-tidy] `doesNotMutateObject`: Handle calls to member functions … (PR #94362)

2024-06-06 Thread Clement Courbet via cfe-commits

https://github.com/legrosbuffle updated 
https://github.com/llvm/llvm-project/pull/94362

>From 8a7e3ee49295b55193440da6b796c9ada43ee5ef Mon Sep 17 00:00:00 2001
From: Clement Courbet 
Date: Tue, 4 Jun 2024 12:49:39 +
Subject: [PATCH 1/3] [clang-tidy] `doesNotMutateObject`: Handle calls to
 member functions and operators that have non-const overloads.

This allows  `unnecessary-copy-initialization` to warn on more cases.

The common case is a class with a a set of const/non-sconst overloads
(e.g. std::vector::operator[]).

```
void F() {
  std::vector v;
  // ...

  const Expensive e = v[i];
}
```
---
 .../UnnecessaryCopyInitialization.cpp |  21 ++-
 .../clang-tidy/utils/DeclRefExprUtils.cpp | 163 +-
 clang-tools-extra/docs/ReleaseNotes.rst   |   4 +-
 .../unnecessary-copy-initialization.cpp   |  29 +++-
 .../clang-tidy/DeclRefExprUtilsTest.cpp   |  39 -
 5 files changed, 229 insertions(+), 27 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp 
b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
index 9beb185cba929..78a1f9a73687d 100644
--- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
+++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -75,16 +75,15 @@ void recordRemoval(const DeclStmt &Stmt, ASTContext 
&Context,
   }
 }
 
-AST_MATCHER_FUNCTION_P(StatementMatcher, isConstRefReturningMethodCall,
+AST_MATCHER_FUNCTION_P(StatementMatcher, isRefReturningMethodCall,
std::vector, ExcludedContainerTypes) {
   // Match method call expressions where the `this` argument is only used as
-  // const, this will be checked in `check()` part. This returned const
-  // reference is highly likely to outlive the local const reference of the
-  // variable being declared. The assumption is that the const reference being
-  // returned either points to a global static variable or to a member of the
-  // called object.
+  // const, this will be checked in `check()` part. This returned reference is
+  // highly likely to outlive the local const reference of the variable being
+  // declared. The assumption is that the reference being returned either 
points
+  // to a global static variable or to a member of the called object.
   const auto MethodDecl =
-  cxxMethodDecl(returns(hasCanonicalType(matchers::isReferenceToConst(
+  cxxMethodDecl(returns(hasCanonicalType(referenceType(
   .bind(MethodDeclId);
   const auto ReceiverExpr =
   ignoringParenImpCasts(declRefExpr(to(varDecl().bind(ObjectArgId;
@@ -121,7 +120,7 @@ AST_MATCHER_FUNCTION_P(StatementMatcher, 
initializerReturnsReferenceToConst,
   declRefExpr(to(varDecl(hasLocalStorage()).bind(OldVarDeclId)));
   return expr(
   anyOf(isConstRefReturningFunctionCall(),
-isConstRefReturningMethodCall(ExcludedContainerTypes),
+isRefReturningMethodCall(ExcludedContainerTypes),
 ignoringImpCasts(OldVarDeclRef),
 ignoringImpCasts(unaryOperator(hasOperatorName("&"),
hasUnaryOperand(OldVarDeclRef);
@@ -259,9 +258,9 @@ void 
UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) {
 .bind("blockStmt");
   };
 
-  
Finder->addMatcher(LocalVarCopiedFrom(anyOf(isConstRefReturningFunctionCall(),
-  isConstRefReturningMethodCall(
-  ExcludedContainerTypes))),
+  Finder->addMatcher(LocalVarCopiedFrom(anyOf(
+ isConstRefReturningFunctionCall(),
+ isRefReturningMethodCall(ExcludedContainerTypes))),
  this);
 
   Finder->addMatcher(LocalVarCopiedFrom(declRefExpr(
diff --git a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp 
b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
index a48e45e135681..4ee8a3628061b 100644
--- a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
+++ b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp
@@ -36,6 +36,111 @@ void extractNodesByIdTo(ArrayRef Matches, 
StringRef ID,
 Nodes.insert(Match.getNodeAs(ID));
 }
 
+// If `D` has a const-qualified overload with otherwise identical
+// ref-qualifiers, returns that overload.
+const CXXMethodDecl *findConstOverload(const CXXMethodDecl &D) {
+  assert(!D.isConst());
+
+  DeclContext::lookup_result lookup_result =
+  D.getParent()->lookup(D.getNameInfo().getName());
+  if (lookup_result.isSingleResult()) {
+// No overload.
+return nullptr;
+  }
+  for (const Decl *overload : lookup_result) {
+const CXXMethodDecl *candidate = dyn_cast(overload);
+if (candidate && !candidate->isDeleted() && candidate->isConst() &&
+candidate->getRefQualifier() == D.getRefQualifier()) {
+  return candidate;
+}
+  }
+  return nullptr;
+}
+
+// Returns true

[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

2024-06-06 Thread Chuanqi Xu via cfe-commits

ChuanqiXu9 wrote:

> Just a note, I am building on Windows with MSVC cl.exe and ninja and get this:
> 
> ```
> C:\Program Files\Microsoft Visual 
> Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\memory(3138): error 
> C2027: use of undefined type 'clang::clangd::ProjectModules'
> ```
> 
> While building ConfigCompile.cpp.obj, I was able to solve it by adding 
> `#include "ProjectModules.h"` into `ConfigCompile.h` before `#include 
> "GlobalCompilationDatabase.h"`.
> 
> Likewise with `BackgroundIndexLoader.cpp.obj` and adding to 
> `index\background.h`, it appears any time `GlobalCompilationDatabase.h` is 
> included that `ProjectModules.h` would need to be included first. It also 
> seems like `ProjectModules.h` cannot be included in 
> `GlobalCompilationDatabase.h` due to a circular dependency. I am still 
> building so there might be similar issues somewhere else in the codebase but 
> this is the base issue.
> 
> Not sure how to resolve other than adding a `#include` everywhere, seems like 
> there an issue with include order on MSVC or something.

I can't reproduce this. I can't find `ConfigCompile.h` even. But I made some 
changes about the interface to the patch from the suggestion of @kadircet . So 
I guess maybe it worth a new try.

https://github.com/llvm/llvm-project/pull/66462
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-06 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);

arsenm wrote:

const always to the left. East const is weird 

https://github.com/llvm/llvm-proj

[clang] 86295dc - Revert "[Analyzer][CFG] Correctly handle rebuilt default arg and default init expression (#91879)" (#94597)

2024-06-06 Thread via cfe-commits

Author: bgra8
Date: 2024-06-06T11:46:33+02:00
New Revision: 86295dc197db2f08f4eb582ed1026a8f74ac3338

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

LOG: Revert "[Analyzer][CFG] Correctly handle rebuilt default arg and default 
init expression (#91879)" (#94597)

This depends on https://github.com/llvm/llvm-project/pull/92527 which
needs to be reverted due to
https://github.com/llvm/llvm-project/pull/92527#issuecomment-2149120420.

This reverts commit 905b402a5d8f1490d668f40942390ebd6e87aa8f.

Co-authored-by: Bogdan Graur 

Added: 


Modified: 
clang/lib/AST/ParentMap.cpp
clang/lib/Analysis/CFG.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
clang/test/Analysis/cxx-uninitialized-object.cpp
clang/test/Analysis/lifetime-extended-regions.cpp

Removed: 




diff  --git a/clang/lib/AST/ParentMap.cpp b/clang/lib/AST/ParentMap.cpp
index 534793b837bbb..3d6a1cc84c7b1 100644
--- a/clang/lib/AST/ParentMap.cpp
+++ b/clang/lib/AST/ParentMap.cpp
@@ -97,22 +97,6 @@ static void BuildParentMap(MapTy& M, Stmt* S,
   BuildParentMap(M, SubStmt, OVMode);
 }
 break;
-  case Stmt::CXXDefaultArgExprClass:
-if (auto *Arg = dyn_cast(S)) {
-  if (Arg->hasRewrittenInit()) {
-M[Arg->getExpr()] = S;
-BuildParentMap(M, Arg->getExpr(), OVMode);
-  }
-}
-break;
-  case Stmt::CXXDefaultInitExprClass:
-if (auto *Init = dyn_cast(S)) {
-  if (Init->hasRewrittenInit()) {
-M[Init->getExpr()] = S;
-BuildParentMap(M, Init->getExpr(), OVMode);
-  }
-}
-break;
   default:
 for (Stmt *SubStmt : S->children()) {
   if (SubStmt) {

diff  --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 02317257c2740..64e6155de090c 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -556,10 +556,6 @@ class CFGBuilder {
 
 private:
   // Visitors to walk an AST and construct the CFG.
-  CFGBlock *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Default,
-   AddStmtChoice asc);
-  CFGBlock *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Default,
-AddStmtChoice asc);
   CFGBlock *VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc);
   CFGBlock *VisitAddrLabelExpr(AddrLabelExpr *A, AddStmtChoice asc);
   CFGBlock *VisitAttributedStmt(AttributedStmt *A, AddStmtChoice asc);
@@ -2258,10 +2254,16 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc,
asc, ExternallyDestructed);
 
 case Stmt::CXXDefaultArgExprClass:
-  return VisitCXXDefaultArgExpr(cast(S), asc);
-
 case Stmt::CXXDefaultInitExprClass:
-  return VisitCXXDefaultInitExpr(cast(S), asc);
+  // FIXME: The expression inside a CXXDefaultArgExpr is owned by the
+  // called function's declaration, not by the caller. If we simply add
+  // this expression to the CFG, we could end up with the same Expr
+  // appearing multiple times (PR13385).
+  //
+  // It's likewise possible for multiple CXXDefaultInitExprs for the same
+  // expression to be used in the same function (through aggregate
+  // initialization).
+  return VisitStmt(S, asc);
 
 case Stmt::CXXBindTemporaryExprClass:
   return VisitCXXBindTemporaryExpr(cast(S), asc);
@@ -2431,40 +2433,6 @@ CFGBlock *CFGBuilder::VisitChildren(Stmt *S) {
   return B;
 }
 
-CFGBlock *CFGBuilder::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Arg,
- AddStmtChoice asc) {
-  if (Arg->hasRewrittenInit()) {
-if (asc.alwaysAdd(*this, Arg)) {
-  autoCreateBlock();
-  appendStmt(Block, Arg);
-}
-return VisitStmt(Arg->getExpr(), asc);
-  }
-
-  // We can't add the default argument if it's not rewritten because the
-  // expression inside a CXXDefaultArgExpr is owned by the called function's
-  // declaration, not by the caller, we could end up with the same expression
-  // appearing multiple times.
-  return VisitStmt(Arg, asc);
-}
-
-CFGBlock *CFGBuilder::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Init,
-  AddStmtChoice asc) {
-  if (Init->hasRewrittenInit()) {
-if (asc.alwaysAdd(*this, Init)) {
-  autoCreateBlock();
-  appendStmt(Block, Init);
-}
-return VisitStmt(Init->getExpr(), asc);
-  }
-
-  // We can't add the default initializer if it's not rewritten because 
multiple
-  // CXXDefaultInitExprs for the same sub-expression to be used in the same
-  // function (through aggregate initialization). we could end up with the same
-  // expression appearing multiple times.
-  return VisitStmt(Init, asc);
-}
-
 CFGBlock *CFGBuilder::VisitInitListExpr(InitListExpr *ILE, AddStmtChoice asc) {
 

[clang] Revert "[Analyzer][CFG] Correctly handle rebuilt default arg and default init expression (#91879)" (PR #94597)

2024-06-06 Thread via cfe-commits

https://github.com/bgra8 closed https://github.com/llvm/llvm-project/pull/94597
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libc] [llvm] [AMDGPU] Implement variadic functions by IR lowering (PR #93362)

2024-06-06 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,1037 @@
+//===-- ExpandVariadicsPass.cpp *- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is an optimization pass for variadic functions. If called from codegen,
+// it can serve as the implementation of variadic functions for a given target.
+//
+// The strategy is to turn the ... part of a variadic function into a va_list
+// and fix up the call sites. The majority of the pass is target independent.
+// The exceptions are the va_list type itself and the rules for where to store
+// variables in memory such that va_arg can iterate over them given a va_list.
+//
+// The majority of the plumbing is splitting the variadic function into a
+// single basic block that packs the variadic arguments into a va_list and
+// a second function that does the work of the original. That packing is
+// exactly what is done by va_start. Further, the transform from ... to va_list
+// replaced va_start with an operation to copy a va_list from the new argument,
+// which is exactly a va_copy. This is useful for reducing target-dependence.
+//
+// A va_list instance is a forward iterator, where the primary operation va_arg
+// is dereference-then-increment. This interface forces significant convergent
+// evolution between target specific implementations. The variation in runtime
+// data layout is limited to that representable by the iterator, parameterised
+// by the type passed to the va_arg instruction.
+//
+// Therefore the majority of the target specific subtlety is packing arguments
+// into a stack allocated buffer such that a va_list can be initialised with it
+// and the va_arg expansion for the target will find the arguments at runtime.
+//
+// The aggregate effect is to unblock other transforms, most critically the
+// general purpose inliner. Known calls to variadic functions become zero cost.
+//
+// Consistency with clang is primarily tested by emitting va_arg using clang
+// then expanding the variadic functions using this pass, followed by trying
+// to constant fold the functions to no-ops.
+//
+// Target specific behaviour is tested in IR - mainly checking that values are
+// put into positions in call frames that make sense for that particular 
target.
+//
+// There is one "clever" invariant in use. va_start intrinsics that are not
+// within a varidic functions are an error in the IR verifier. When this
+// transform moves blocks from a variadic function into a fixed arity one, it
+// moves va_start intrinsics along with everything else. That means that the
+// va_start intrinsics that need to be rewritten to use the trailing argument
+// are exactly those that are in non-variadic functions so no further state
+// is needed to distinguish those that need to be rewritten.
+//
+//===--===//
+
+#include "llvm/Transforms/IPO/ExpandVariadics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+#define DEBUG_TYPE "expand-variadics"
+
+using namespace llvm;
+
+namespace {
+
+cl::opt ExpandVariadicsModeOption(
+DEBUG_TYPE "-override", cl::desc("Override the behaviour of " DEBUG_TYPE),
+cl::init(ExpandVariadicsMode::Unspecified),
+cl::values(clEnumValN(ExpandVariadicsMode::Unspecified, "unspecified",
+  "Use the implementation defaults"),
+   clEnumValN(ExpandVariadicsMode::Disable, "disable",
+  "Disable the pass entirely"),
+   clEnumValN(ExpandVariadicsMode::Optimize, "optimize",
+  "Optimise without changing ABI"),
+   clEnumValN(ExpandVariadicsMode::Lowering, "lowering",
+  "Change variadic calling convention")));
+
+bool commandLineOverride() {
+  return ExpandVariadicsModeOption != ExpandVariadicsMode::Unspecified;
+}
+
+// Instances of this class encapsulate the target-dependant behaviour as a
+// function of triple. Implementing a new ABI is adding a case to the switch
+// in create(llvm::Triple) at the end of this file.
+class VariadicABIInfo {
+protected:
+  VariadicABIInfo() {}
+
+public:
+  static std::unique_ptr create(llvm::Triple const &Triple);
+
+  // Allow overriding whether the pass runs on a per-target basis
+  virtual bool enableForTarget() = 0;
+
+  

[clang] 026fbdf - [clang][Interp] Handle one-past-the-end pointers in SubPtr

2024-06-06 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-06-06T11:48:31+02:00
New Revision: 026fbdf934d4adc8b6abe544ba1bcfa3b64293ac

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

LOG: [clang][Interp] Handle one-past-the-end pointers in SubPtr

Added: 


Modified: 
clang/lib/AST/Interp/Interp.h
clang/test/AST/Interp/arrays.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 17f05548a190..1248eeb79cbf 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1773,8 +1773,10 @@ inline bool SubPtr(InterpState &S, CodePtr OpPC) {
 return true;
   }
 
-  T A = T::from(LHS.getIndex());
-  T B = T::from(RHS.getIndex());
+  T A = LHS.isElementPastEnd() ? T::from(LHS.getNumElems())
+   : T::from(LHS.getIndex());
+  T B = RHS.isElementPastEnd() ? T::from(RHS.getNumElems())
+   : T::from(RHS.getIndex());
   return AddSubMulHelper(S, OpPC, A.bitWidth(), A, B);
 }
 

diff  --git a/clang/test/AST/Interp/arrays.cpp 
b/clang/test/AST/Interp/arrays.cpp
index dd5064d993e6..6146d41c5ff5 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -609,3 +609,9 @@ namespace ArrayMemberAccess {
 bool cond = a->x;
   }
 }
+
+namespace OnePastEndSub {
+  struct A {};
+  constexpr A a[3][3];
+  constexpr int 
diff 2 = &a[1][3] - &a[1][0]; /// Used to crash.
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] e285818 - Revert "[serialization] no transitive decl change (#92083)"

2024-06-06 Thread Chuanqi Xu via cfe-commits

Author: Chuanqi Xu
Date: 2024-06-06T17:49:59+08:00
New Revision: e2858189bd99e6914dc2f63ab55b053a74b4e58b

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

LOG: Revert "[serialization] no transitive decl change (#92083)"

This reverts commit 97c866f6c86456b3316006e6beff47e68a81c00a.

This fails on 32bit machines. See
https://github.com/llvm/llvm-project/pull/92083

Added: 


Modified: 
clang/include/clang/AST/DeclBase.h
clang/include/clang/AST/DeclID.h
clang/include/clang/Serialization/ASTBitCodes.h
clang/include/clang/Serialization/ASTReader.h
clang/include/clang/Serialization/ModuleFile.h
clang/include/clang/Serialization/ModuleManager.h
clang/lib/AST/DeclBase.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/lib/Serialization/ModuleFile.cpp

Removed: 
clang/test/Modules/no-transitive-decls-change.cppm



diff  --git a/clang/include/clang/AST/DeclBase.h 
b/clang/include/clang/AST/DeclBase.h
index 5f19af1891b7..600ce73c7f01 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -708,7 +708,10 @@ class alignas(8) Decl {
 
   /// Set the owning module ID.  This may only be called for
   /// deserialized Decls.
-  void setOwningModuleID(unsigned ID);
+  void setOwningModuleID(unsigned ID) {
+assert(isFromASTFile() && "Only works on a deserialized declaration");
+*((unsigned*)this - 2) = ID;
+  }
 
 public:
   /// Determine the availability of the given declaration.
@@ -781,11 +784,19 @@ class alignas(8) Decl {
 
   /// Retrieve the global declaration ID associated with this
   /// declaration, which specifies where this Decl was loaded from.
-  GlobalDeclID getGlobalID() const;
+  GlobalDeclID getGlobalID() const {
+if (isFromASTFile())
+  return (*((const GlobalDeclID *)this - 1));
+return GlobalDeclID();
+  }
 
   /// Retrieve the global ID of the module that owns this particular
   /// declaration.
-  unsigned getOwningModuleID() const;
+  unsigned getOwningModuleID() const {
+if (isFromASTFile())
+  return *((const unsigned*)this - 2);
+return 0;
+  }
 
 private:
   Module *getOwningModuleSlow() const;

diff  --git a/clang/include/clang/AST/DeclID.h 
b/clang/include/clang/AST/DeclID.h
index 32d2ed41a374..614ba06b6386 100644
--- a/clang/include/clang/AST/DeclID.h
+++ b/clang/include/clang/AST/DeclID.h
@@ -19,8 +19,6 @@
 #include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/ADT/iterator.h"
 
-#include 
-
 namespace clang {
 
 /// Predefined declaration IDs.
@@ -109,16 +107,12 @@ class DeclIDBase {
   ///
   /// DeclID should only be used directly in serialization. All other users
   /// should use LocalDeclID or GlobalDeclID.
-  using DeclID = uint64_t;
+  using DeclID = uint32_t;
 
 protected:
   DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {}
   explicit DeclIDBase(DeclID ID) : ID(ID) {}
 
-  explicit DeclIDBase(unsigned LocalID, unsigned ModuleFileIndex) {
-ID = (DeclID)LocalID | ((DeclID)ModuleFileIndex << 32);
-  }
-
 public:
   DeclID get() const { return ID; }
 
@@ -130,10 +124,6 @@ class DeclIDBase {
 
   bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; }
 
-  unsigned getModuleFileIndex() const { return ID >> 32; }
-
-  unsigned getLocalDeclIndex() const;
-
   friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) {
 return LHS.ID == RHS.ID;
   }
@@ -166,9 +156,6 @@ class LocalDeclID : public DeclIDBase {
   LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {}
   explicit LocalDeclID(DeclID ID) : Base(ID) {}
 
-  explicit LocalDeclID(unsigned LocalID, unsigned ModuleFileIndex)
-  : Base(LocalID, ModuleFileIndex) {}
-
   LocalDeclID &operator++() {
 ++ID;
 return *this;
@@ -188,9 +175,6 @@ class GlobalDeclID : public DeclIDBase {
   GlobalDeclID() : Base() {}
   explicit GlobalDeclID(DeclID ID) : Base(ID) {}
 
-  explicit GlobalDeclID(unsigned LocalID, unsigned ModuleFileIndex)
-  : Base(LocalID, ModuleFileIndex) {}
-
   // For DeclIDIterator to be able to convert a GlobalDeclID
   // to a LocalDeclID.
   explicit operator LocalDeclID() const { return LocalDeclID(this->ID); }

diff  --git a/clang/include/clang/Serialization/ASTBitCodes.h 
b/clang/include/clang/Serialization/ASTBitCodes.h
index 3f3fb8869f5f..f59ff6af4c76 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -255,12 +255,6 @@ class DeclOffset {
   }
 };
 
-// The unaligned decl ID used in the Blobs of bistreams.
-using unaligned_decl_id_t =
-llvm::support::detail::packed_endian_specific_integral<
-serialization::DeclID, llvm::endianness::native,
-llvm::support::unaligned>;
-
 /// The number of predefined p

[clang] [amdgpu] Pass variadic arguments without splitting (PR #94083)

2024-06-06 Thread Matt Arsenault via cfe-commits

arsenm wrote:

> @arsenm You're right about passing larger things indirectly. I'm intending to 
> land this as-is, with the types inlined, as that unblocks #93362. I'm nervous 
> that the extra pointer indirection will hit the same memory error that 
> tweaking codegen in that patch hits (it's a similar sort of pattern to the 
> top level argument passing) and wish to postpone that until there is a 
> working baseline.

I do think we need to revisit some threshold at some point. We should use byref 
for anything that's most likely to hit the stack anyway 

https://github.com/llvm/llvm-project/pull/94083
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [amdgpu] Pass variadic arguments without splitting (PR #94083)

2024-06-06 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,293 @@
+// REQUIRES: amdgpu-registered-target
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --function-signature
+// RUN: %clang_cc1 -cc1 -std=c23 -triple amdgcn-amd-amdhsa -emit-llvm -O1 %s 
-o - | FileCheck %s
+
+void sink_0(...);
+void sink_1(int, ...);
+void sink_2(double, int, ...);
+
+// Simple scalar values
+
+// CHECK-LABEL: define {{[^@]+}}@zero_varargs
+// CHECK-SAME: (i32 noundef [[F0:%.*]], double noundef [[F1:%.*]]) 
local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:tail call void (...) @sink_0() #[[ATTR2:[0-9]+]]
+// CHECK-NEXT:tail call void (i32, ...) @sink_1(i32 noundef [[F0]]) 
#[[ATTR2]]
+// CHECK-NEXT:tail call void (double, i32, ...) @sink_2(double noundef 
[[F1]], i32 noundef [[F0]]) #[[ATTR2]]
+// CHECK-NEXT:ret void
+//
+void zero_varargs(int f0, double f1)
+{
+  sink_0();
+  sink_1(f0);
+  sink_2(f1, f0);
+}
+
+// CHECK-LABEL: define {{[^@]+}}@one_i32
+// CHECK-SAME: (i32 noundef [[F0:%.*]], double noundef [[F1:%.*]], i32 noundef 
[[V0:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:tail call void (...) @sink_0(i32 noundef [[V0]]) #[[ATTR2]]
+// CHECK-NEXT:tail call void (i32, ...) @sink_1(i32 noundef [[F0]], i32 
noundef [[V0]]) #[[ATTR2]]
+// CHECK-NEXT:tail call void (double, i32, ...) @sink_2(double noundef 
[[F1]], i32 noundef [[F0]], i32 noundef [[V0]]) #[[ATTR2]]
+// CHECK-NEXT:ret void
+//
+void one_i32(int f0, double f1, int v0)
+{
+  sink_0(v0);
+  sink_1(f0, v0);
+  sink_2(f1, f0, v0);
+}
+
+// CHECK-LABEL: define {{[^@]+}}@one_ptr
+// CHECK-SAME: (i32 noundef [[F0:%.*]], double noundef [[F1:%.*]], ptr noundef 
[[V0:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:tail call void (...) @sink_0(ptr noundef [[V0]]) #[[ATTR2]]
+// CHECK-NEXT:tail call void (i32, ...) @sink_1(i32 noundef [[F0]], ptr 
noundef [[V0]]) #[[ATTR2]]
+// CHECK-NEXT:tail call void (double, i32, ...) @sink_2(double noundef 
[[F1]], i32 noundef [[F0]], ptr noundef [[V0]]) #[[ATTR2]]
+// CHECK-NEXT:ret void
+//
+void one_ptr(int f0, double f1, void* v0)
+{
+  sink_0(v0);
+  sink_1(f0, v0);
+  sink_2(f1, f0, v0);
+}
+
+// CHECK-LABEL: define {{[^@]+}}@one_f64
+// CHECK-SAME: (i32 noundef [[F0:%.*]], double noundef [[F1:%.*]], double 
noundef [[V0:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:tail call void (...) @sink_0(double noundef [[V0]]) 
#[[ATTR2]]
+// CHECK-NEXT:tail call void (i32, ...) @sink_1(i32 noundef [[F0]], double 
noundef [[V0]]) #[[ATTR2]]
+// CHECK-NEXT:tail call void (double, i32, ...) @sink_2(double noundef 
[[F1]], i32 noundef [[F0]], double noundef [[V0]]) #[[ATTR2]]
+// CHECK-NEXT:ret void
+//
+void one_f64(int f0, double f1, double v0)
+{
+  sink_0(v0);
+  sink_1(f0, v0);
+  sink_2(f1, f0, v0);
+}
+
+
+// C has various type promotion rules for variadics
+
+// CHECK-LABEL: define {{[^@]+}}@one_i8
+// CHECK-SAME: (i32 noundef [[F0:%.*]], double noundef [[F1:%.*]], i8 noundef 
signext [[V0:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[CONV:%.*]] = sext i8 [[V0]] to i32
+// CHECK-NEXT:tail call void (...) @sink_0(i32 noundef [[CONV]]) #[[ATTR2]]
+// CHECK-NEXT:tail call void (i32, ...) @sink_1(i32 noundef [[F0]], i32 
noundef [[CONV]]) #[[ATTR2]]
+// CHECK-NEXT:tail call void (double, i32, ...) @sink_2(double noundef 
[[F1]], i32 noundef [[F0]], i32 noundef [[CONV]]) #[[ATTR2]]
+// CHECK-NEXT:ret void
+//
+void one_i8(int f0, double f1, char v0)
+{
+  sink_0(v0);
+  sink_1(f0, v0);
+  sink_2(f1, f0, v0);
+}
+
+// CHECK-LABEL: define {{[^@]+}}@one_i16
+// CHECK-SAME: (i32 noundef [[F0:%.*]], double noundef [[F1:%.*]], i16 noundef 
signext [[V0:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[CONV:%.*]] = sext i16 [[V0]] to i32
+// CHECK-NEXT:tail call void (...) @sink_0(i32 noundef [[CONV]]) #[[ATTR2]]
+// CHECK-NEXT:tail call void (i32, ...) @sink_1(i32 noundef [[F0]], i32 
noundef [[CONV]]) #[[ATTR2]]
+// CHECK-NEXT:tail call void (double, i32, ...) @sink_2(double noundef 
[[F1]], i32 noundef [[F0]], i32 noundef [[CONV]]) #[[ATTR2]]
+// CHECK-NEXT:ret void
+//
+void one_i16(int f0, double f1, short v0)
+{
+  sink_0(v0);
+  sink_1(f0, v0);
+  sink_2(f1, f0, v0);
+}
+
+// CHECK-LABEL: define {{[^@]+}}@one_f32
+// CHECK-SAME: (i32 noundef [[F0:%.*]], double noundef [[F1:%.*]], float 
noundef [[V0:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[CONV:%.*]] = fpext float [[V0]] to double
+// CHECK-NEXT:tail call void (...) @sink_0(double noundef [[CONV]]) 
#[[ATTR2]]
+// CHECK-NEXT:tail call void (i32, ...) @sink_1(i32 noundef [[F0]], double 
noundef [[CONV]]) #[[ATTR2]]
+// CHECK-NEXT:tail call void (double, i32, ...) @sink_2(double noundef 
[[F1]], i32 noundef [[F0]], double noundef [[C

[clang] Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#92527)" (PR #94600)

2024-06-06 Thread via cfe-commits

https://github.com/bgra8 created https://github.com/llvm/llvm-project/pull/94600

Reverting due to
https://github.com/llvm/llvm-project/pull/92527#issuecomment-2149120420.

This reverts commit f049d72ac2bcc40fd91d4e95148658021fb24bf1.


>From fbaa1ce73030c456c62ab8b2d002b8f04b6913a7 Mon Sep 17 00:00:00 2001
From: Bogdan Graur 
Date: Thu, 6 Jun 2024 09:48:36 +
Subject: [PATCH] Revert "Reapply "[Clang][CWG1815] Support lifetime extension
 of temporary created by aggregate initialization using a default member
 initializer" (#92527)"

Reverting due to
https://github.com/llvm/llvm-project/pull/92527#issuecomment-2149120420.

This reverts commit f049d72ac2bcc40fd91d4e95148658021fb24bf1.
---
 .../clang/Basic/DiagnosticSemaKinds.td|  6 ++
 clang/lib/Sema/SemaExpr.cpp   | 31 ++--
 clang/lib/Sema/SemaExprCXX.cpp|  3 +
 clang/lib/Sema/SemaInit.cpp   | 19 -
 clang/lib/Sema/TreeTransform.h| 12 +--
 clang/test/AST/ast-dump-default-init-json.cpp |  6 +-
 clang/test/AST/ast-dump-default-init.cpp  |  2 +-
 .../Analysis/lifetime-extended-regions.cpp|  9 +--
 clang/test/CXX/drs/cwg16xx.cpp|  2 +
 clang/test/CXX/drs/cwg18xx.cpp| 19 ++---
 clang/test/CXX/special/class.temporary/p6.cpp | 34 -
 clang/test/SemaCXX/constexpr-default-arg.cpp  |  4 +-
 .../cxx11-default-member-initializers.cpp | 74 ---
 clang/test/SemaCXX/eval-crashes.cpp   |  6 +-
 clang/www/cxx_dr_status.html  |  2 +-
 15 files changed, 61 insertions(+), 168 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 87745140cb0eb..9f0b6f5a36389 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10082,6 +10082,12 @@ def warn_new_dangling_initializer_list : Warning<
   "the allocated initializer list}0 "
   "will be destroyed at the end of the full-expression">,
   InGroup;
+def warn_unsupported_lifetime_extension : Warning<
+  "lifetime extension of "
+  "%select{temporary|backing array of initializer list}0 created "
+  "by aggregate initialization using a default member initializer "
+  "is not yet supported; lifetime of %select{temporary|backing array}0 "
+  "will end at the end of the full-expression">, InGroup;
 
 // For non-floating point, expressions of the form x == x or x != x
 // should result in a warning, since these always evaluate to a constant.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d8c77e3e0a5cd..76145f291887c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5572,9 +5572,10 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation 
CallLoc,
 Res = Immediate.TransformInitializer(Param->getInit(),
  /*NotCopy=*/false);
   });
-  if (Res.isUsable())
-Res = ConvertParamDefaultArgument(Param, Res.get(),
-  Res.get()->getBeginLoc());
+  if (Res.isInvalid())
+return ExprError();
+  Res = ConvertParamDefaultArgument(Param, Res.get(),
+Res.get()->getBeginLoc());
   if (Res.isInvalid())
 return ExprError();
   Init = Res.get();
@@ -5610,7 +5611,7 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation 
Loc, FieldDecl *Field) {
   Expr *Init = nullptr;
 
   bool NestedDefaultChecking = isCheckingDefaultArgumentOrInitializer();
-  bool InLifetimeExtendingContext = isInLifetimeExtendingContext();
+
   EnterExpressionEvaluationContext EvalContext(
   *this, ExpressionEvaluationContext::PotentiallyEvaluated, Field);
 
@@ -5645,35 +5646,19 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation 
Loc, FieldDecl *Field) {
   ImmediateCallVisitor V(getASTContext());
   if (!NestedDefaultChecking)
 V.TraverseDecl(Field);
-
-  // CWG1815
-  // Support lifetime extension of temporary created by aggregate
-  // initialization using a default member initializer. We should always 
rebuild
-  // the initializer if it contains any temporaries (if the initializer
-  // expression is an ExprWithCleanups). Then make sure the normal lifetime
-  // extension code recurses into the default initializer and does lifetime
-  // extension when warranted.
-  bool ContainsAnyTemporaries =
-  isa_and_present(Field->getInClassInitializer());
-  if (V.HasImmediateCalls || InLifetimeExtendingContext ||
-  ContainsAnyTemporaries) {
+  if (V.HasImmediateCalls) {
 ExprEvalContexts.back().DelayedDefaultInitializationContext = {Loc, Field,
CurContext};
 ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer =
 NestedDefaultChecking;
-// Pass down lifetime extending flag, and collect temporaries in
-// Create

[clang] Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#92527)" (PR #94600)

2024-06-06 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (bgra8)


Changes

Reverting due to
https://github.com/llvm/llvm-project/pull/92527#issuecomment-2149120420.

This reverts commit f049d72ac2bcc40fd91d4e95148658021fb24bf1.


---
Full diff: https://github.com/llvm/llvm-project/pull/94600.diff


15 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+6) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+8-23) 
- (modified) clang/lib/Sema/SemaExprCXX.cpp (+3) 
- (modified) clang/lib/Sema/SemaInit.cpp (+18-1) 
- (modified) clang/lib/Sema/TreeTransform.h (+4-8) 
- (modified) clang/test/AST/ast-dump-default-init-json.cpp (+3-3) 
- (modified) clang/test/AST/ast-dump-default-init.cpp (+1-1) 
- (modified) clang/test/Analysis/lifetime-extended-regions.cpp (+4-5) 
- (modified) clang/test/CXX/drs/cwg16xx.cpp (+2) 
- (modified) clang/test/CXX/drs/cwg18xx.cpp (+5-14) 
- (modified) clang/test/CXX/special/class.temporary/p6.cpp (-34) 
- (modified) clang/test/SemaCXX/constexpr-default-arg.cpp (+2-2) 
- (modified) clang/test/SemaCXX/cxx11-default-member-initializers.cpp (-74) 
- (modified) clang/test/SemaCXX/eval-crashes.cpp (+4-2) 
- (modified) clang/www/cxx_dr_status.html (+1-1) 


``diff
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 87745140cb0eb..9f0b6f5a36389 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10082,6 +10082,12 @@ def warn_new_dangling_initializer_list : Warning<
   "the allocated initializer list}0 "
   "will be destroyed at the end of the full-expression">,
   InGroup;
+def warn_unsupported_lifetime_extension : Warning<
+  "lifetime extension of "
+  "%select{temporary|backing array of initializer list}0 created "
+  "by aggregate initialization using a default member initializer "
+  "is not yet supported; lifetime of %select{temporary|backing array}0 "
+  "will end at the end of the full-expression">, InGroup;
 
 // For non-floating point, expressions of the form x == x or x != x
 // should result in a warning, since these always evaluate to a constant.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d8c77e3e0a5cd..76145f291887c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5572,9 +5572,10 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation 
CallLoc,
 Res = Immediate.TransformInitializer(Param->getInit(),
  /*NotCopy=*/false);
   });
-  if (Res.isUsable())
-Res = ConvertParamDefaultArgument(Param, Res.get(),
-  Res.get()->getBeginLoc());
+  if (Res.isInvalid())
+return ExprError();
+  Res = ConvertParamDefaultArgument(Param, Res.get(),
+Res.get()->getBeginLoc());
   if (Res.isInvalid())
 return ExprError();
   Init = Res.get();
@@ -5610,7 +5611,7 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation 
Loc, FieldDecl *Field) {
   Expr *Init = nullptr;
 
   bool NestedDefaultChecking = isCheckingDefaultArgumentOrInitializer();
-  bool InLifetimeExtendingContext = isInLifetimeExtendingContext();
+
   EnterExpressionEvaluationContext EvalContext(
   *this, ExpressionEvaluationContext::PotentiallyEvaluated, Field);
 
@@ -5645,35 +5646,19 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation 
Loc, FieldDecl *Field) {
   ImmediateCallVisitor V(getASTContext());
   if (!NestedDefaultChecking)
 V.TraverseDecl(Field);
-
-  // CWG1815
-  // Support lifetime extension of temporary created by aggregate
-  // initialization using a default member initializer. We should always 
rebuild
-  // the initializer if it contains any temporaries (if the initializer
-  // expression is an ExprWithCleanups). Then make sure the normal lifetime
-  // extension code recurses into the default initializer and does lifetime
-  // extension when warranted.
-  bool ContainsAnyTemporaries =
-  isa_and_present(Field->getInClassInitializer());
-  if (V.HasImmediateCalls || InLifetimeExtendingContext ||
-  ContainsAnyTemporaries) {
+  if (V.HasImmediateCalls) {
 ExprEvalContexts.back().DelayedDefaultInitializationContext = {Loc, Field,
CurContext};
 ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer =
 NestedDefaultChecking;
-// Pass down lifetime extending flag, and collect temporaries in
-// CreateMaterializeTemporaryExpr when we rewrite the call argument.
-keepInLifetimeExtendingContext();
+
 EnsureImmediateInvocationInDefaultArgs Immediate(*this);
 ExprResult Res;
-
-// Rebuild CXXDefaultInitExpr might cause diagnostics.
-SFINAETrap Trap(*this);
 runWithSufficientStackSpace(Loc, [&] {
   Res = Immediate.TransformInitializer(Field->getInClassIniti

[clang] 7f52e4c - Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#92527)" (#94600)

2024-06-06 Thread via cfe-commits

Author: bgra8
Date: 2024-06-06T11:59:52+02:00
New Revision: 7f52e4c755fcd02232964f19bb0226878255f274

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

LOG: Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary 
created by aggregate initialization using a default member initializer" 
(#92527)" (#94600)

Reverting due to
https://github.com/llvm/llvm-project/pull/92527#issuecomment-2149120420.

This reverts commit f049d72ac2bcc40fd91d4e95148658021fb24bf1.

Co-authored-by: Bogdan Graur 

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/TreeTransform.h
clang/test/AST/ast-dump-default-init-json.cpp
clang/test/AST/ast-dump-default-init.cpp
clang/test/Analysis/lifetime-extended-regions.cpp
clang/test/CXX/drs/cwg16xx.cpp
clang/test/CXX/drs/cwg18xx.cpp
clang/test/CXX/special/class.temporary/p6.cpp
clang/test/SemaCXX/constexpr-default-arg.cpp
clang/test/SemaCXX/cxx11-default-member-initializers.cpp
clang/test/SemaCXX/eval-crashes.cpp
clang/www/cxx_dr_status.html

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 87745140cb0eb..9f0b6f5a36389 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10082,6 +10082,12 @@ def warn_new_dangling_initializer_list : Warning<
   "the allocated initializer list}0 "
   "will be destroyed at the end of the full-expression">,
   InGroup;
+def warn_unsupported_lifetime_extension : Warning<
+  "lifetime extension of "
+  "%select{temporary|backing array of initializer list}0 created "
+  "by aggregate initialization using a default member initializer "
+  "is not yet supported; lifetime of %select{temporary|backing array}0 "
+  "will end at the end of the full-expression">, InGroup;
 
 // For non-floating point, expressions of the form x == x or x != x
 // should result in a warning, since these always evaluate to a constant.

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d8c77e3e0a5cd..76145f291887c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5572,9 +5572,10 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation 
CallLoc,
 Res = Immediate.TransformInitializer(Param->getInit(),
  /*NotCopy=*/false);
   });
-  if (Res.isUsable())
-Res = ConvertParamDefaultArgument(Param, Res.get(),
-  Res.get()->getBeginLoc());
+  if (Res.isInvalid())
+return ExprError();
+  Res = ConvertParamDefaultArgument(Param, Res.get(),
+Res.get()->getBeginLoc());
   if (Res.isInvalid())
 return ExprError();
   Init = Res.get();
@@ -5610,7 +5611,7 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation 
Loc, FieldDecl *Field) {
   Expr *Init = nullptr;
 
   bool NestedDefaultChecking = isCheckingDefaultArgumentOrInitializer();
-  bool InLifetimeExtendingContext = isInLifetimeExtendingContext();
+
   EnterExpressionEvaluationContext EvalContext(
   *this, ExpressionEvaluationContext::PotentiallyEvaluated, Field);
 
@@ -5645,35 +5646,19 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation 
Loc, FieldDecl *Field) {
   ImmediateCallVisitor V(getASTContext());
   if (!NestedDefaultChecking)
 V.TraverseDecl(Field);
-
-  // CWG1815
-  // Support lifetime extension of temporary created by aggregate
-  // initialization using a default member initializer. We should always 
rebuild
-  // the initializer if it contains any temporaries (if the initializer
-  // expression is an ExprWithCleanups). Then make sure the normal lifetime
-  // extension code recurses into the default initializer and does lifetime
-  // extension when warranted.
-  bool ContainsAnyTemporaries =
-  isa_and_present(Field->getInClassInitializer());
-  if (V.HasImmediateCalls || InLifetimeExtendingContext ||
-  ContainsAnyTemporaries) {
+  if (V.HasImmediateCalls) {
 ExprEvalContexts.back().DelayedDefaultInitializationContext = {Loc, Field,
CurContext};
 ExprEvalContexts.back().IsCurrentlyCheckingDefaultArgumentOrInitializer =
 NestedDefaultChecking;
-// Pass down lifetime extending flag, and collect temporaries in
-// CreateMaterializeTemporaryExpr when we rewrite the call argument.
-keepInLifetimeExtendingContext();
+
 EnsureImmediateInvocationInDefaultArgs Immediate(*this);
 ExprResult Res;
-
-// Rebuil

[clang] Revert "Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (#92527)" (PR #94600)

2024-06-06 Thread via cfe-commits

https://github.com/bgra8 closed https://github.com/llvm/llvm-project/pull/94600
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [RISCV] Add processor definition for SpacemiT-X60 (PR #94564)

2024-06-06 Thread Shao-Ce SUN via cfe-commits

https://github.com/sunshaoce updated 
https://github.com/llvm/llvm-project/pull/94564

>From 363e29385277c049bc91a86e76ff6f6ae70ceaa9 Mon Sep 17 00:00:00 2001
From: Shao-Ce SUN 
Date: Thu, 6 Jun 2024 12:05:33 +0800
Subject: [PATCH 1/4] [RISCV] Add processor definition for Spacemit-K1

---
 clang/test/Driver/riscv-cpus.c| 12 ++
 clang/test/Misc/target-invalid-cpu-note.c |  4 ++--
 llvm/lib/Target/RISCV/RISCVProcessors.td  | 29 +++
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
index ff2bd6f7c8ba3..32d7910ab4daa 100644
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -31,6 +31,18 @@
 // MCPU-XIANGSHAN-NANHU-SAME: "-target-feature" "+zks" "-target-feature" 
"+zksed" "-target-feature" "+zksh" "-target-feature" "+svinval"
 // MCPU-XIANGSHAN-NANHU-SAME: "-target-abi" "lp64d"
 
+// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=spacemit-k1 | FileCheck 
-check-prefix=MCPU-SPACEMIT-K1 %s
+// MCPU-SPACEMIT-K1: "-nostdsysteminc" "-target-cpu" "spacemit-k1"
+// MCPU-SPACEMIT-K1-SAME: "-target-feature" "+m" "-target-feature" "+a" 
"-target-feature" "+f" "-target-feature" "+d"
+// MCPU-SPACEMIT-K1-SAME: "-target-feature" "+c" "-target-feature" "+v" 
"-target-feature" "+zicond" "-target-feature" "+zicsr"
+// MCPU-SPACEMIT-K1-SAME: "-target-feature" "+zifencei" "-target-feature" 
"+zmmul" "-target-feature" "+zfh"
+// MCPU-SPACEMIT-K1-SAME: "-target-feature" "+zfhmin" "-target-feature" "+zba" 
"-target-feature" "+zbb" "-target-feature" "+zbc"
+// MCPU-SPACEMIT-K1-SAME: "-target-feature" "+zbkb" "-target-feature" "+zbkc" 
"-target-feature" "+zbs" "-target-feature" "+zve32f"
+// MCPU-SPACEMIT-K1-SAME: "-target-feature" "+zve32x" "-target-feature" 
"+zve64d" "-target-feature" "+zve64f" "-target-feature" "+zve64x"
+// MCPU-SPACEMIT-K1-SAME: "-target-feature" "+zvfh" "-target-feature" 
"+zvfhmin"
+// MCPU-SPACEMIT-K1-SAME: "-target-feature" "+zvl128b" "-target-feature" 
"+zvl256b" "-target-feature" "+zvl32b" "-target-feature" "+zvl64b"
+// MCPU-SPACEMIT-K1-SAME: "-target-abi" "lp64d"
+
 // We cannot check much for -mcpu=native, but it should be replaced by a valid 
CPU string.
 // RUN: %clang --target=riscv64 -### -c %s -mcpu=native 2> %t.err || true
 // RUN: FileCheck --input-file=%t.err -check-prefix=MCPU-NATIVE %s
diff --git a/clang/test/Misc/target-invalid-cpu-note.c 
b/clang/test/Misc/target-invalid-cpu-note.c
index 6558fd753d1d1..04e92360fe665 100644
--- a/clang/test/Misc/target-invalid-cpu-note.c
+++ b/clang/test/Misc/target-invalid-cpu-note.c
@@ -85,7 +85,7 @@
 
 // RUN: not %clang_cc1 -triple riscv64 -target-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix RISCV64
 // RISCV64: error: unknown target CPU 'not-a-cpu'
-// RISCV64-NEXT: note: valid target CPU values are: generic-rv64, rocket-rv64, 
sifive-p450, sifive-p670, sifive-s21, sifive-s51, sifive-s54, sifive-s76, 
sifive-u54, sifive-u74, sifive-x280, veyron-v1, xiangshan-nanhu{{$}}
+// RISCV64-NEXT: note: valid target CPU values are: generic-rv64, rocket-rv64, 
sifive-p450, sifive-p670, sifive-s21, sifive-s51, sifive-s54, sifive-s76, 
sifive-u54, sifive-u74, sifive-x280, spacemit-k1, veyron-v1, 
xiangshan-nanhu{{$}}
 
 // RUN: not %clang_cc1 -triple riscv32 -tune-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix TUNE-RISCV32
 // TUNE-RISCV32: error: unknown target CPU 'not-a-cpu'
@@ -93,4 +93,4 @@
 
 // RUN: not %clang_cc1 -triple riscv64 -tune-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix TUNE-RISCV64
 // TUNE-RISCV64: error: unknown target CPU 'not-a-cpu'
-// TUNE-RISCV64-NEXT: note: valid target CPU values are: generic-rv64, 
rocket-rv64, sifive-p450, sifive-p670, sifive-s21, sifive-s51, sifive-s54, 
sifive-s76, sifive-u54, sifive-u74, sifive-x280, veyron-v1, xiangshan-nanhu, 
generic, rocket, sifive-7-series{{$}}
+// TUNE-RISCV64-NEXT: note: valid target CPU values are: generic-rv64, 
rocket-rv64, sifive-p450, sifive-p670, sifive-s21, sifive-s51, sifive-s54, 
sifive-s76, sifive-u54, sifive-u74, sifive-x280, spacemit-k1, veyron-v1, 
xiangshan-nanhu, generic, rocket, sifive-7-series{{$}}
diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td 
b/llvm/lib/Target/RISCV/RISCVProcessors.td
index 6ebf9f1eb0452..08602e9d06cc9 100644
--- a/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -381,3 +381,32 @@ def XIANGSHAN_NANHU : 
RISCVProcessorModel<"xiangshan-nanhu",
 TuneZExtHFusion,
 TuneZExtWFusion,
 TuneShiftedZExtWFusion]>;
+
+def SPACEMIT_K1 : RISCVProcessorModel<"spacemit-k1",
+   NoSchedModel,
+   [Feature64Bit,
+FeatureStdExtI,
+FeatureStdExtM,
+

[clang] [clang] Report erroneous floating point results in _Complex math (PR #90588)

2024-06-06 Thread Timm Baeder via cfe-commits

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] [flang] [llvm] [mlir] [Flang]Fix for changed code at the end of AllocaIP. (PR #92430)

2024-06-06 Thread Tom Eccles via cfe-commits

https://github.com/tblah approved this pull request.

LGTM if @Meinersbur is happy. It's a shame about the fallout to the clang tests 
but I can see that would be very difficult to avoid.

Thank you for persisting with this difficult patch.

https://github.com/llvm/llvm-project/pull/92430
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Reapply "[Clang][CWG1815] Support lifetime extension of temporary created by aggregate initialization using a default member initializer" (PR #92527)

2024-06-06 Thread via cfe-commits

alexfh wrote:

> Here's the reproducer:
> 
> ```c++
> struct a {
>   virtual int *b();
> };
> template  struct d : a {
>   int *b() { new c; }
> };
> int *e(a *);
> struct f {
>   char *g;
> };
> struct h {};
> struct i {
>   i(const f &);
>   i(h);
> };
> struct l {
>   i j = i({.g = ""});
> };
> int *k = e(new d);
> struct n : l {};
> int *m = e(new d);
> ```

A bit clearer repro: https://gcc.godbolt.org/z/r9EdcoW8G

The new clang behavior seems wrong to me.

https://github.com/llvm/llvm-project/pull/92527
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [PowerPC] Support -mno-red-zone option (PR #94581)

2024-06-06 Thread Qiu Chaofan via cfe-commits

https://github.com/ecnelises updated 
https://github.com/llvm/llvm-project/pull/94581

>From 4e078099d8e15fd984ef38435d6f792bbb3d754c Mon Sep 17 00:00:00 2001
From: Qiu Chaofan 
Date: Thu, 6 Jun 2024 14:06:48 +0800
Subject: [PATCH 1/2] [PowerPC] Support -mno-red-zone option

---
 clang/lib/Driver/ToolChains/Clang.cpp | 3 +++
 clang/test/Driver/flags.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 4e1c52462e584..3a37c05c8b44b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2022,6 +2022,9 @@ void Clang::AddPPCTargetArgs(const ArgList &Args,
 CmdArgs.push_back("-mabi=vec-extabi");
   }
 
+  if (!Args.hasFlag(options::OPT_mred_zone, options::OPT_mno_red_zone, true))
+CmdArgs.push_back("-disable-red-zone");
+
   ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
   if (FloatABI == ppc::FloatABI::Soft) {
 // Floating point operations and argument passing are soft.
diff --git a/clang/test/Driver/flags.c b/clang/test/Driver/flags.c
index 16b760609c36d..7d2bef63fca3e 100644
--- a/clang/test/Driver/flags.c
+++ b/clang/test/Driver/flags.c
@@ -33,3 +33,6 @@
 //
 // RUN: %clang --target=riscv64 -### -S -mno-implicit-float %s 2>&1 | 
FileCheck -check-prefix=TEST11 %s
 // TEST11: "-no-implicit-float"
+//
+// RUN: %clang --target=ppc64le -### -S -mno-red-zone %s 2>&1 | FileCheck 
-check-prefix=TEST12 %s
+// TEST12: "-disable-red-zone"

>From b8e076e175f42e07a329d2bee4878785f6145288 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan 
Date: Thu, 6 Jun 2024 18:02:58 +0800
Subject: [PATCH 2/2] Add noredzone LLC test

---
 llvm/test/CodeGen/PowerPC/noredzone.ll | 513 +
 1 file changed, 513 insertions(+)
 create mode 100644 llvm/test/CodeGen/PowerPC/noredzone.ll

diff --git a/llvm/test/CodeGen/PowerPC/noredzone.ll 
b/llvm/test/CodeGen/PowerPC/noredzone.ll
new file mode 100644
index 0..3bd1e0867ba11
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/noredzone.ll
@@ -0,0 +1,513 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64-ibm-aix < %s | FileCheck 
-check-prefix=AIX64
+; RUN: llc -verify-machineinstrs -mtriple=powerpc-ibm-aix < %s | FileCheck 
-check-prefix=AIX32
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu < %s | 
FileCheck -check-prefix=LE64
+
+define signext i32 @leaf1_noredzone(i32 signext %a, i32 signext %b) #0 {
+; AIX64-LABEL: leaf1_noredzone:
+; AIX64:   # %bb.0: # %entry
+; AIX64-NEXT:stdu 1, -64(1)
+; AIX64-NEXT:stw 3, 60(1)
+; AIX64-NEXT:add 3, 3, 4
+; AIX64-NEXT:extsw 3, 3
+; AIX64-NEXT:stw 4, 56(1)
+; AIX64-NEXT:addi 1, 1, 64
+; AIX64-NEXT:blr
+;
+; AIX32-LABEL: leaf1_noredzone:
+; AIX32:   # %bb.0: # %entry
+; AIX32-NEXT:stwu 1, -32(1)
+; AIX32-NEXT:stw 3, 28(1)
+; AIX32-NEXT:add 3, 3, 4
+; AIX32-NEXT:stw 4, 24(1)
+; AIX32-NEXT:addi 1, 1, 32
+; AIX32-NEXT:blr
+;
+; LE64-LABEL: leaf1_noredzone:
+; LE64:   # %bb.0: # %entry
+; LE64-NEXT:stdu 1, -48(1)
+; LE64-NEXT:stw 3, 44(1)
+; LE64-NEXT:add 3, 3, 4
+; LE64-NEXT:stw 4, 40(1)
+; LE64-NEXT:extsw 3, 3
+; LE64-NEXT:addi 1, 1, 48
+; LE64-NEXT:blr
+entry:
+  %a.addr = alloca i32, align 4
+  %b.addr = alloca i32, align 4
+  store i32 %a, ptr %a.addr, align 4
+  store i32 %b, ptr %b.addr, align 4
+  %0 = load i32, ptr %a.addr, align 4
+  %1 = load i32, ptr %b.addr, align 4
+  %add = add nsw i32 %0, %1
+  ret i32 %add
+}
+
+define void @nonleaf1_noredzone(i32 signext %a, i32 signext %b) #0 {
+; AIX64-LABEL: nonleaf1_noredzone:
+; AIX64:   # %bb.0: # %entry
+; AIX64-NEXT:mflr 0
+; AIX64-NEXT:stdu 1, -128(1)
+; AIX64-NEXT:std 0, 144(1)
+; AIX64-NEXT:stw 3, 124(1)
+; AIX64-NEXT:add 3, 3, 4
+; AIX64-NEXT:extsw 3, 3
+; AIX64-NEXT:stw 4, 120(1)
+; AIX64-NEXT:bl .leaf2[PR]
+; AIX64-NEXT:nop
+; AIX64-NEXT:lwz 3, 124(1)
+; AIX64-NEXT:lwz 4, 120(1)
+; AIX64-NEXT:sub 3, 3, 4
+; AIX64-NEXT:extsw 3, 3
+; AIX64-NEXT:bl .leaf2[PR]
+; AIX64-NEXT:nop
+; AIX64-NEXT:addi 1, 1, 128
+; AIX64-NEXT:ld 0, 16(1)
+; AIX64-NEXT:mtlr 0
+; AIX64-NEXT:blr
+;
+; AIX32-LABEL: nonleaf1_noredzone:
+; AIX32:   # %bb.0: # %entry
+; AIX32-NEXT:mflr 0
+; AIX32-NEXT:stwu 1, -64(1)
+; AIX32-NEXT:stw 0, 72(1)
+; AIX32-NEXT:stw 3, 60(1)
+; AIX32-NEXT:add 3, 3, 4
+; AIX32-NEXT:stw 4, 56(1)
+; AIX32-NEXT:bl .leaf2[PR]
+; AIX32-NEXT:nop
+; AIX32-NEXT:lwz 3, 60(1)
+; AIX32-NEXT:lwz 4, 56(1)
+; AIX32-NEXT:sub 3, 3, 4
+; AIX32-NEXT:bl .leaf2[PR]
+; AIX32-NEXT:nop
+; AIX32-NEXT:addi 1, 1, 64
+; AIX32-NEXT:lwz 0, 8(1)
+; AIX32-NEXT:mtlr 0
+; AIX32-NEXT:blr
+;
+; LE64-LABEL: nonleaf1_noredzone:
+; LE64:   # %bb.0: # %entry
+; LE64-NEXT:mflr 0
+; 

  1   2   3   4   5   >