[clang] [clang] Fix --entry command line option (PR #69114)

2023-10-26 Thread Fangrui Song via cfe-commits


@@ -5474,7 +5474,8 @@ def _dyld_prefix_EQ : Joined<["--"], "dyld-prefix=">;
 def _dyld_prefix : Separate<["--"], "dyld-prefix">, Alias<_dyld_prefix_EQ>;
 def _encoding_EQ : Joined<["--"], "encoding=">, Alias;
 def _encoding : Separate<["--"], "encoding">, Alias;
-def _entry : Flag<["--"], "entry">, Alias;
+def : Joined<["--"], "entry=">, Flags<[LinkerInput]>, Group, 
Alias;

MaskRay wrote:

Remove Flags and Group. They are ignored.

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


[clang] [RecursiveASTVisitor] Fix RecursiveASTVisitor (RAV) fails to visit the initializer of a bitfield (PR #69557)

2023-10-26 Thread Shivam Gupta via cfe-commits

https://github.com/xgupta updated 
https://github.com/llvm/llvm-project/pull/69557

>From 2e363be5e79e2aeeb219628db0c917e530e04d99 Mon Sep 17 00:00:00 2001
From: Shivam Gupta 
Date: Thu, 19 Oct 2023 09:06:43 +0530
Subject: [PATCH 1/4] [RecursiveASTVisitor] Fix RecursiveASTVisitor (RAV) fails
 to visit the initializer of a bitfield

Patch by Scott McPeak
---
 clang/include/clang/AST/RecursiveASTVisitor.h |  2 +-
 clang/unittests/Tooling/CMakeLists.txt|  1 +
 .../BitfieldInitializer.cpp   | 34 +++
 3 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 
clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp

diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index 3dd23eb38eeabfc..53bc15e1b19f668 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2103,7 +2103,7 @@ DEF_TRAVERSE_DECL(FieldDecl, {
   TRY_TO(TraverseDeclaratorHelper(D));
   if (D->isBitField())
 TRY_TO(TraverseStmt(D->getBitWidth()));
-  else if (D->hasInClassInitializer())
+  if (D->hasInClassInitializer())
 TRY_TO(TraverseStmt(D->getInClassInitializer()));
 })
 
diff --git a/clang/unittests/Tooling/CMakeLists.txt 
b/clang/unittests/Tooling/CMakeLists.txt
index 2fbe78e3fab7528..5a10a6b285390e9 100644
--- a/clang/unittests/Tooling/CMakeLists.txt
+++ b/clang/unittests/Tooling/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_unittest(ToolingTests
   QualTypeNamesTest.cpp
   RangeSelectorTest.cpp
   RecursiveASTVisitorTests/Attr.cpp
+  RecursiveASTVisitorTests/BitfieldInitializer.cpp
   RecursiveASTVisitorTests/CallbacksLeaf.cpp
   RecursiveASTVisitorTests/CallbacksUnaryOperator.cpp
   RecursiveASTVisitorTests/CallbacksBinaryOperator.cpp
diff --git 
a/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp 
b/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp
new file mode 100644
index 000..676a491a43040ea
--- /dev/null
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp
@@ -0,0 +1,34 @@
+//===- unittest/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp -===//
+//
+// 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 "TestVisitor.h"
+#include 
+
+using namespace clang;
+
+namespace {
+
+// Check to ensure that bitfield initializers are visited.
+class BitfieldInitializerVisitor : public 
ExpectedLocationVisitor {
+public:
+  bool VisitIntegerLiteral(IntegerLiteral *IL) {
+Match(std::to_string(IL->getValue().getSExtValue()), IL->getLocation());
+return true;
+  }
+};
+
+TEST(RecursiveASTVisitor, BitfieldInitializerIsVisited) {
+  BitfieldInitializerVisitor Visitor;
+  Visitor.ExpectMatch("123", 2, 15); 
+  EXPECT_TRUE(Visitor.runOver(
+"struct S {\n"
+"  int x : 8 = 123;\n"
+"};\n"));
+}
+
+} // end anonymous namespace

>From a6fa113206562f373f3aba81ce81acd5d9dcf9d1 Mon Sep 17 00:00:00 2001
From: Shivam Gupta 
Date: Thu, 19 Oct 2023 09:24:38 +0530
Subject: [PATCH 2/4] clang-format

---
 .../RecursiveASTVisitorTests/BitfieldInitializer.cpp | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git 
a/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp 
b/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp
index 676a491a43040ea..c11e726fe855284 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp
@@ -14,7 +14,8 @@ using namespace clang;
 namespace {
 
 // Check to ensure that bitfield initializers are visited.
-class BitfieldInitializerVisitor : public 
ExpectedLocationVisitor {
+class BitfieldInitializerVisitor
+: public ExpectedLocationVisitor {
 public:
   bool VisitIntegerLiteral(IntegerLiteral *IL) {
 Match(std::to_string(IL->getValue().getSExtValue()), IL->getLocation());
@@ -24,11 +25,10 @@ class BitfieldInitializerVisitor : public 
ExpectedLocationVisitorFrom 1ce8c2ca7bf5110e4bfb11eeaaa891183e73f2e5 Mon Sep 17 00:00:00 2001
From: Shivam Gupta 
Date: Wed, 25 Oct 2023 22:16:34 +0530
Subject: [PATCH 3/4] Added release note

---
 clang/docs/ReleaseNotes.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 42f20b9a9bb0410..a1f373b167a33cb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -650,6 +650,9 @@ Bug Fixes to AST Handling
   `Issue 64170 `_
 - Fixed ``hasAnyBase`` not binding nodes in its submatcher.
   (`#65421 `_)
+- Fixed a

[clang] 897cc8a - [RecursiveASTVisitor] Fix RecursiveASTVisitor (RAV) fails to visit the initializer of a bitfield (#69557)

2023-10-26 Thread via cfe-commits

Author: Shivam Gupta
Date: 2023-10-26T12:39:48+05:30
New Revision: 897cc8a7d7c0e47686322dbd4b95ecad30bb2298

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

LOG: [RecursiveASTVisitor] Fix RecursiveASTVisitor (RAV) fails to visit the 
initializer of a bitfield (#69557)

The problem was introduced in the commit
https://github.com/llvm/llvm-project/commit/6b8e3c02ca44fb6c3738bb0c75859c11a03e30ed
when the possibility of initialized bitfields was added, but the logic
in RecursiveASTVisitor was not updated. This PR fixed that.

This fixes https://github.com/llvm/llvm-project/issues/64916.

Patch by Scott McPeak

-

Co-authored-by: cor3ntin 

Added: 
clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/include/clang/AST/RecursiveASTVisitor.h
clang/unittests/Tooling/CMakeLists.txt

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 42f20b9a9bb0410..074116d2edf9f99 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -650,6 +650,9 @@ Bug Fixes to AST Handling
   `Issue 64170 `_
 - Fixed ``hasAnyBase`` not binding nodes in its submatcher.
   (`#65421 `_)
+- Fixed a bug where RecursiveASTVisitor fails to visit the
+  initializer of a bitfield.
+  `Issue 64916 `_
 
 Miscellaneous Bug Fixes
 ^^^

diff  --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index 3dd23eb38eeabfc..53bc15e1b19f668 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2103,7 +2103,7 @@ DEF_TRAVERSE_DECL(FieldDecl, {
   TRY_TO(TraverseDeclaratorHelper(D));
   if (D->isBitField())
 TRY_TO(TraverseStmt(D->getBitWidth()));
-  else if (D->hasInClassInitializer())
+  if (D->hasInClassInitializer())
 TRY_TO(TraverseStmt(D->getInClassInitializer()));
 })
 

diff  --git a/clang/unittests/Tooling/CMakeLists.txt 
b/clang/unittests/Tooling/CMakeLists.txt
index 2fbe78e3fab7528..5a10a6b285390e9 100644
--- a/clang/unittests/Tooling/CMakeLists.txt
+++ b/clang/unittests/Tooling/CMakeLists.txt
@@ -25,6 +25,7 @@ add_clang_unittest(ToolingTests
   QualTypeNamesTest.cpp
   RangeSelectorTest.cpp
   RecursiveASTVisitorTests/Attr.cpp
+  RecursiveASTVisitorTests/BitfieldInitializer.cpp
   RecursiveASTVisitorTests/CallbacksLeaf.cpp
   RecursiveASTVisitorTests/CallbacksUnaryOperator.cpp
   RecursiveASTVisitorTests/CallbacksBinaryOperator.cpp

diff  --git 
a/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp 
b/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp
new file mode 100644
index 000..c11e726fe855284
--- /dev/null
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp
@@ -0,0 +1,34 @@
+//===- unittest/Tooling/RecursiveASTVisitorTests/BitfieldInitializer.cpp -===//
+//
+// 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 "TestVisitor.h"
+#include 
+
+using namespace clang;
+
+namespace {
+
+// Check to ensure that bitfield initializers are visited.
+class BitfieldInitializerVisitor
+: public ExpectedLocationVisitor {
+public:
+  bool VisitIntegerLiteral(IntegerLiteral *IL) {
+Match(std::to_string(IL->getValue().getSExtValue()), IL->getLocation());
+return true;
+  }
+};
+
+TEST(RecursiveASTVisitor, BitfieldInitializerIsVisited) {
+  BitfieldInitializerVisitor Visitor;
+  Visitor.ExpectMatch("123", 2, 15);
+  EXPECT_TRUE(Visitor.runOver("struct S {\n"
+  "  int x : 8 = 123;\n"
+  "};\n"));
+}
+
+} // end anonymous namespace



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


[clang] [RecursiveASTVisitor] Fix RecursiveASTVisitor (RAV) fails to visit the initializer of a bitfield (PR #69557)

2023-10-26 Thread Shivam Gupta via cfe-commits

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


[clang] [RecursiveASTVisitor] Fix RecursiveASTVisitor (RAV) fails to visit the initializer of a bitfield (PR #69557)

2023-10-26 Thread Shivam Gupta via cfe-commits

xgupta wrote:

Thanks @cor3ntin for the review!

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


[clang] 6e2d67e - [RISCV] Support predefined macro __riscv_misaligned_[fast,avoid]. (#65756)

2023-10-26 Thread via cfe-commits

Author: Yeting Kuo
Date: 2023-10-26T15:10:57+08:00
New Revision: 6e2d67e7d66f46fbe4f4c35c7c59d3a8706ea8b0

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

LOG: [RISCV] Support predefined macro __riscv_misaligned_[fast,avoid]. (#65756)

RISC-V C API introduced predefined macro to achieve hints about
unaligned accesses ([pr]). This patch defines __riscv_misaligned_fast
when using -mno-strict-align, otherwise, defines
__riscv_misaligned_avoid.

Note: This ignores __riscv_misaligned_slow which is also defined by
spec.

[pr]: https://github.com/riscv-non-isa/riscv-c-api-doc/pull/40

Added: 


Modified: 
clang/lib/Basic/Targets/RISCV.cpp
clang/lib/Basic/Targets/RISCV.h
clang/test/Preprocessor/riscv-target-features.c

Removed: 




diff  --git a/clang/lib/Basic/Targets/RISCV.cpp 
b/clang/lib/Basic/Targets/RISCV.cpp
index 5f75619b745546c..0b9ebeaf5e75bbd 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -210,6 +210,11 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions 
&Opts,
   if (VScale && VScale->first && VScale->first == VScale->second)
 Builder.defineMacro("__riscv_v_fixed_vlen",
 Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock));
+
+  if (FastUnalignedAccess)
+Builder.defineMacro("__riscv_misaligned_fast");
+  else
+Builder.defineMacro("__riscv_misaligned_avoid");
 }
 
 static constexpr Builtin::Info BuiltinInfo[] = {
@@ -328,6 +333,8 @@ bool 
RISCVTargetInfo::handleTargetFeatures(std::vector &Features,
   if (ISAInfo->hasExtension("zfh") || ISAInfo->hasExtension("zhinx"))
 HasLegalHalfType = true;
 
+  FastUnalignedAccess = llvm::is_contained(Features, "+unaligned-scalar-mem");
+
   return true;
 }
 

diff  --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 6be0e49ca2f5525..e5424d318401fb0 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -29,6 +29,9 @@ class RISCVTargetInfo : public TargetInfo {
   std::string ABI, CPU;
   std::unique_ptr ISAInfo;
 
+private:
+  bool FastUnalignedAccess;
+
 public:
   RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
   : TargetInfo(Triple) {

diff  --git a/clang/test/Preprocessor/riscv-target-features.c 
b/clang/test/Preprocessor/riscv-target-features.c
index ffdec34ca615fe3..3a0435f9c97906f 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -1246,3 +1246,15 @@
 // RUN: -march=rv64i_zve32x_zvkt1p0 -x c -E -dM %s \
 // RUN: -o - | FileCheck --check-prefix=CHECK-ZVKT-EXT %s
 // CHECK-ZVKT-EXT: __riscv_zvkt 100{{$}}
+
+// RUN: %clang --target=riscv32-unknown-linux-gnu -march=rv32i -x c -E -dM %s \
+// RUN: -o - | FileCheck %s --check-prefix=CHECK-MISALIGNED-AVOID
+// RUN: %clang --target=riscv64-unknown-linux-gnu -march=rv64i -x c -E -dM %s \
+// RUN: -o - | FileCheck %s --check-prefix=CHECK-MISALIGNED-AVOID
+// CHECK-MISALIGNED-AVOID: __riscv_misaligned_avoid 1
+
+// RUN: %clang --target=riscv32-unknown-linux-gnu -march=rv32i -E -dM %s \
+// RUN:   -munaligned-access -o - | FileCheck %s 
--check-prefix=CHECK-MISALIGNED-FAST
+// RUN: %clang --target=riscv64-unknown-linux-gnu -march=rv64i -E -dM %s \
+// RUN:   -munaligned-access -o - | FileCheck %s 
--check-prefix=CHECK-MISALIGNED-FAST
+// CHECK-MISALIGNED-FAST: __riscv_misaligned_fast 1



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


[clang] [RISCV] Support predefined macro __riscv_misaligned_[fast,avoid]. (PR #65756)

2023-10-26 Thread Yeting Kuo via cfe-commits

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


[clang] [clang][nullability] Use `proves()` and `assume()` instead of deprecated synonyms. (PR #70297)

2023-10-26 Thread via cfe-commits

https://github.com/martinboehme created 
https://github.com/llvm/llvm-project/pull/70297

None

>From f57ebb921dc5c3289cf19c3075c00fb91119acd6 Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Thu, 26 Oct 2023 07:21:18 +
Subject: [PATCH] [clang][nullability] Use `proves()` and `assume()` instead of
 deprecated synonyms.

---
 .../lib/Analysis/FlowSensitive/HTMLLogger.cpp |   9 +-
 .../Models/ChromiumCheckModel.cpp |   2 +-
 .../Models/UncheckedOptionalAccessModel.cpp   |  22 ++-
 .../TypeErasedDataflowAnalysis.cpp|   2 +-
 .../FlowSensitive/ChromiumCheckModelTest.cpp  |   4 +-
 .../FlowSensitive/SignAnalysisTest.cpp|  45 +++---
 .../Analysis/FlowSensitive/TransferTest.cpp   | 152 +-
 .../TypeErasedDataflowAnalysisTest.cpp|  74 +
 8 files changed, 149 insertions(+), 161 deletions(-)

diff --git a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp 
b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
index 8aef1d6f46089d2..8329367098b1dbb 100644
--- a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
+++ b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
@@ -114,11 +114,10 @@ class ModelDumper {
 // guaranteed true/false here is valuable and hard to determine by hand.
 if (auto *B = llvm::dyn_cast(&V)) {
   JOS.attribute("formula", llvm::to_string(B->formula()));
-  JOS.attribute(
-  "truth", Env.flowConditionImplies(B->formula()) ? "true"
-   : 
Env.flowConditionImplies(Env.arena().makeNot(B->formula()))
-   ? "false"
-   : "unknown");
+  JOS.attribute("truth", Env.proves(B->formula()) ? "true"
+ : Env.proves(Env.arena().makeNot(B->formula()))
+ ? "false"
+ : "unknown");
 }
   }
   void dump(const StorageLocation &L) {
diff --git a/clang/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp 
b/clang/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp
index 895f4ff04a172f9..f49087ababc44ce 100644
--- a/clang/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp
@@ -59,7 +59,7 @@ bool ChromiumCheckModel::transfer(const CFGElement &Element, 
Environment &Env) {
 if (const auto *M = dyn_cast(Call->getDirectCallee())) {
   if (isCheckLikeMethod(CheckDecls, *M)) {
 // Mark this branch as unreachable.
-Env.addToFlowCondition(Env.arena().makeLiteral(false));
+Env.assume(Env.arena().makeLiteral(false));
 return true;
   }
 }
diff --git 
a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp 
b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
index 8bd9a030f50cda0..55d0713639d90da 100644
--- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
@@ -413,7 +413,7 @@ bool isEmptyOptional(const Value &OptionalVal, const 
Environment &Env) {
   auto *HasValueVal =
   cast_or_null(OptionalVal.getProperty("has_value"));
   return HasValueVal != nullptr &&
- Env.flowConditionImplies(Env.arena().makeNot(HasValueVal->formula()));
+ Env.proves(Env.arena().makeNot(HasValueVal->formula()));
 }
 
 /// Returns true if and only if `OptionalVal` is initialized and known to be
@@ -421,8 +421,7 @@ bool isEmptyOptional(const Value &OptionalVal, const 
Environment &Env) {
 bool isNonEmptyOptional(const Value &OptionalVal, const Environment &Env) {
   auto *HasValueVal =
   cast_or_null(OptionalVal.getProperty("has_value"));
-  return HasValueVal != nullptr &&
- Env.flowConditionImplies(HasValueVal->formula());
+  return HasValueVal != nullptr && Env.proves(HasValueVal->formula());
 }
 
 Value *getValueBehindPossiblePointer(const Expr &E, const Environment &Env) {
@@ -490,8 +489,8 @@ void transferValueOrImpl(
   if (HasValueVal == nullptr)
 return;
 
-  Env.addToFlowCondition(ModelPred(Env, forceBoolValue(Env, *ValueOrPredExpr),
-   HasValueVal->formula()));
+  Env.assume(ModelPred(Env, forceBoolValue(Env, *ValueOrPredExpr),
+   HasValueVal->formula()));
 }
 
 void transferValueOrStringEmptyCall(const clang::Expr *ComparisonExpr,
@@ -717,8 +716,8 @@ void transferOptionalAndOptionalCmp(const 
clang::CXXOperatorCallExpr *CmpExpr,
 if (auto *RHasVal = getHasValue(Env, Env.getValue(*CmpExpr->getArg(1 {
   if (CmpExpr->getOperator() == clang::OO_ExclaimEqual)
 CmpValue = &A.makeNot(*CmpValue);
-  Env.addToFlowCondition(evaluateEquality(A, *CmpValue, LHasVal->formula(),
-  RHasVal->formula()));
+  Env.assume(evaluateEquality(A, *CmpValue, LHasVal->formula(),
+  RHasVal->formula()));
 }
 }
 
@@ -729,7 +728,7 @@ void transferOptionalAndValueCmp(cons

[clang] [Docs][LTO] Updated HowToSubmitABug.rst for LTO crashes (PR #68389)

2023-10-26 Thread Shivam Gupta via cfe-commits

https://github.com/xgupta updated 
https://github.com/llvm/llvm-project/pull/68389

>From bdf991f4563e3aa840bec35b1678ad4fe8f9fbb6 Mon Sep 17 00:00:00 2001
From: Shivam Gupta 
Date: Fri, 6 Oct 2023 12:32:24 +0530
Subject: [PATCH 1/5] [Docs][LTO] Update HowToSubmitABug.rst for LTO crashes

---
 llvm/docs/HowToSubmitABug.rst | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/llvm/docs/HowToSubmitABug.rst b/llvm/docs/HowToSubmitABug.rst
index 733dae6c928d098..88f9af44add7c64 100644
--- a/llvm/docs/HowToSubmitABug.rst
+++ b/llvm/docs/HowToSubmitABug.rst
@@ -153,6 +153,57 @@ Please run this, then file a bug with the instructions and 
reduced .bc file
 that bugpoint emits.  If something goes wrong with bugpoint, please submit
 the "foo.bc" file and the option that llc crashes with.
 
+​.. _lto-crash:
+
+LTO bugs
+---
+
+If you find a bug that crashes llvm in LTO phase (by using -flto option),
+compile your source file to a .bc file by passing
+"``-flto -fuse-ld=lld -Wl,-plugin-opt=save-temps``"
+to clang (in addition to the options you already pass). If you are building
+a project, pass the appropriate CFLAGS, CXXFLAG​S and LDFLAGS for example -
+
+.. code-block:: bash
+
+   export CFLAGS="-flto -fuse-ld=lld" CXXFLAGS="-flto -fuse-ld=lld" 
LDFLAGS="-Wl,-plugin-opt=save-temps"
+
+This will generate four intermediate bytecode files:
+
+1. a.out.0.0.preopt.bc  (Before any link-time optimizations (LTO) are 
applied)
+2. a.out.0.2.internalize.bc (After initial optimizations applied)
+3. a.out.0.4.opt.bc (After the more extensive set of optimizations has 
been applied)
+4. a.out.0.5.precodegen.bc  (After LTO but before it's translated into machine 
code)
+
+Once you have these, one of the following commands should fail:
+
+#. ``opt "-passes=lto" a.out.0.0.preopt.bc``
+#. ``opt "-passes=lto" a.out.0.2.internalize.bc``
+#. ``opt "-passes=lto" a.out.0.4.opt.bc``
+#. ``llc a.out.0.5.precodegen.bc``
+
+If one of these do crash, you should be able to reduce
+this with :program:`llvm-reduce`
+command line (use the bc file corresponding to the command above that failed):
+
+#. ``llvm-reduce --test llvm-reduce.sh a.out.0.2.internalize.bc``
+
+An example of ``llvm-reduce.sh`` script
+
+.. code-block:: bash
+
+   $ cat llvm-reduce.sh
+   #!/usr/bin/env bash
+
+   $HOME/llvm/llvm-project/build/bin/opt "-passes=lto" $1 -o temp.bc  2>&1 
| tee err.log
+   grep "It->second == &Insn" err.log
+   exit $?
+
+Here we have grepped the failed assert message.
+
+Please run this, then file a bug with the instructions and reduced .bc file
+that llvm-reduce emits.
+
 .. _miscompiling:
 
 Miscompilations

>From 1823285171ddbefc49065c4995e9c33bee7b952a Mon Sep 17 00:00:00 2001
From: Shivam Gupta 
Date: Thu, 19 Oct 2023 10:57:25 +0530
Subject: [PATCH 2/5] address review comment

---
 llvm/docs/HowToSubmitABug.rst | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/llvm/docs/HowToSubmitABug.rst b/llvm/docs/HowToSubmitABug.rst
index 88f9af44add7c64..197ed3e0fde6893 100644
--- a/llvm/docs/HowToSubmitABug.rst
+++ b/llvm/docs/HowToSubmitABug.rst
@@ -168,6 +168,12 @@ a project, pass the appropriate CFLAGS, CXXFLAG​S and 
LDFLAGS for example -
 
export CFLAGS="-flto -fuse-ld=lld" CXXFLAGS="-flto -fuse-ld=lld" 
LDFLAGS="-Wl,-plugin-opt=save-temps"
 
+On Windows, you should use lld-link as the linker.
+
+.. code-block:: bash
+
+   export CFLAGS="-flto -fuse-ld=lld-link" CXXFLAGS="-flto -fuse-ld=lld-link" 
LDFLAGS="-Wl,-plugin-opt=save-temps"
+
 This will generate four intermediate bytecode files:
 
 1. a.out.0.0.preopt.bc  (Before any link-time optimizations (LTO) are 
applied)

>From 0e19d37bf4eb9a312b4989fe941837e285f92a97 Mon Sep 17 00:00:00 2001
From: Shivam Gupta 
Date: Thu, 19 Oct 2023 12:29:23 +0530
Subject: [PATCH 3/5] rebase and improve some wording

---
 llvm/docs/HowToSubmitABug.rst | 36 ---
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/llvm/docs/HowToSubmitABug.rst b/llvm/docs/HowToSubmitABug.rst
index 197ed3e0fde6893..7e9ac089a0f70a1 100644
--- a/llvm/docs/HowToSubmitABug.rst
+++ b/llvm/docs/HowToSubmitABug.rst
@@ -158,30 +158,34 @@ the "foo.bc" file and the option that llc crashes with.
 LTO bugs
 ---
 
-If you find a bug that crashes llvm in LTO phase (by using -flto option),
-compile your source file to a .bc file by passing
-"``-flto -fuse-ld=lld -Wl,-plugin-opt=save-temps``"
-to clang (in addition to the options you already pass). If you are building
-a project, pass the appropriate CFLAGS, CXXFLAG​S and LDFLAGS for example -
+If you encounter a bug that leads to crashes in the LLVM LTO phase when using
+the `-flto` option, follow these steps to diagnose and report the issue:
+
+Compile your source file to a .bc (Bitcode) file with the following flags,
+in addition to your existing compilation options:
 
 .. code-block:: bash
 
export CFLAGS="-flto -fuse-ld=lld" CXXFLAGS=

[clang] [Clang][Driver] Add new flags to control machine instruction verification (PR #70282)

2023-10-26 Thread Nikita Popov via cfe-commits

nikic wrote:

I'm not convinced that adding this flag makes sense, given that you can already 
use `-mllvm -verify-machineinstrs`. This is a developer option, and I don't 
think it should be exposed by the clang driver (and if you expose it in cc1 
only, then `-Xclang -fverify-machine-code` is really no better than `-mllvm 
-verify-machineinstrs`). We have a lot of different verification options for 
different things, and I don't think they should be exposed to end users.

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


[clang] [RISCV] Add processor definition for XiangShan-NanHu (PR #70294)

2023-10-26 Thread Wang Pengcheng via cfe-commits

wangpc-pp wrote:

LGTM in general, except one question: will zicbom and zicboz be in the final 
RTL?

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


[clang] [PowerPC] Support local-dynamic TLS relocation on AIX (PR #66316)

2023-10-26 Thread Felix via cfe-commits


@@ -649,6 +649,14 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
  uint64_t &FixedValue) {
   auto getIndex = [this](const MCSymbol *Sym,
  const MCSectionXCOFF *ContainingCsect) {
+// Fixup relocation flag for AIX TLS local-dynamic mode.
+if (Sym->getName().equals("_Renamed..5f24__TLSML[UA]")) {

orcguru wrote:

> We generally prefer `==` over `equals`

Thank you for pointing out!

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


[clang] [clang] [Gnu] Improve GCCVersion parsing to match versions such as "10-win32" (PR #69079)

2023-10-26 Thread Martin Storsjö via cfe-commits

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


[clang] 05dcfa4 - [clang] [Gnu] Improve GCCVersion parsing to match versions such as "10-win32" (#69079)

2023-10-26 Thread via cfe-commits

Author: Martin Storsjö
Date: 2023-10-26T10:55:53+03:00
New Revision: 05dcfa44c0f4c68c3a7b831d6ac2dd0572741ece

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

LOG: [clang] [Gnu] Improve GCCVersion parsing to match versions such as 
"10-win32" (#69079)

In earlier GCC versions, the Debian/Ubuntu provided mingw toolchains
were packaged in /usr/lib/gcc/ with version strings such as
"5.3-win32", which were matched and found since
6afcd64eb65fca233a7b173f88cffb2c2c9c114c. However in recent versions,
they have stopped including the minor version number and only have
version strings such as "10-win32" and "10-posix".

Generalize the parsing code to tolerate the patch suffix to be present
on a version number with only a major number.

Refactor the string parsing code to highlight the overall structure of
the parsing. This implementation should yield the same result as before,
except for when there's only one segment and it has trailing, non-number
contents.

This allows Clang to find the GCC libraries and headers in Debian/Ubuntu
provided MinGW cross compilers.

Added: 


Modified: 
clang/lib/Driver/ToolChains/Gnu.cpp
clang/unittests/Driver/GCCVersionTest.cpp

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index cdd911af9a73361..a98dfa02fc717a5 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -2007,45 +2007,72 @@ Generic_GCC::GCCVersion 
Generic_GCC::GCCVersion::Parse(StringRef VersionText) {
   std::pair First = VersionText.split('.');
   std::pair Second = First.second.split('.');
 
-  GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
-  if (First.first.getAsInteger(10, GoodVersion.Major) || GoodVersion.Major < 0)
-return BadVersion;
-  GoodVersion.MajorStr = First.first.str();
-  if (First.second.empty())
-return GoodVersion;
+  StringRef MajorStr = First.first;
   StringRef MinorStr = Second.first;
-  if (Second.second.empty()) {
-if (size_t EndNumber = MinorStr.find_first_not_of("0123456789")) {
-  GoodVersion.PatchSuffix = std::string(MinorStr.substr(EndNumber));
-  MinorStr = MinorStr.slice(0, EndNumber);
-}
-  }
-  if (MinorStr.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0)
-return BadVersion;
-  GoodVersion.MinorStr = MinorStr.str();
+  StringRef PatchStr = Second.second;
 
-  // First look for a number prefix and parse that if present. Otherwise just
-  // stash the entire patch string in the suffix, and leave the number
-  // unspecified. This covers versions strings such as:
-  //   5(handled above)
+  GCCVersion GoodVersion = {VersionText.str(), -1, -1, -1, "", "", ""};
+
+  // Parse version number strings such as:
+  //   5
   //   4.4
   //   4.4-patched
   //   4.4.0
   //   4.4.x
   //   4.4.2-rc4
   //   4.4.x-patched
-  // And retains any patch number it finds.
-  StringRef PatchText = Second.second;
-  if (!PatchText.empty()) {
-if (size_t EndNumber = PatchText.find_first_not_of("0123456789")) {
-  // Try to parse the number and any suffix.
-  if (PatchText.slice(0, EndNumber).getAsInteger(10, GoodVersion.Patch) ||
-  GoodVersion.Patch < 0)
-return BadVersion;
-  GoodVersion.PatchSuffix = std::string(PatchText.substr(EndNumber));
+  //   10-win32
+  // Split on '.', handle 1, 2 or 3 such segments. Each segment must contain
+  // purely a number, except for the last one, where a non-number suffix
+  // is stored in PatchSuffix. The third segment is allowed to not contain
+  // a number at all.
+
+  auto TryParseLastNumber = [&](StringRef Segment, int &Number,
+std::string &OutStr) -> bool {
+// Look for a number prefix and parse that, and split out any trailing
+// string into GoodVersion.PatchSuffix.
+
+if (size_t EndNumber = Segment.find_first_not_of("0123456789")) {
+  StringRef NumberStr = Segment.slice(0, EndNumber);
+  if (NumberStr.getAsInteger(10, Number) || Number < 0)
+return false;
+  OutStr = NumberStr;
+  GoodVersion.PatchSuffix = Segment.substr(EndNumber);
+  return true;
 }
+return false;
+  };
+  auto TryParseNumber = [](StringRef Segment, int &Number) -> bool {
+if (Segment.getAsInteger(10, Number) || Number < 0)
+  return false;
+return true;
+  };
+
+  if (MinorStr.empty()) {
+// If no minor string, major is the last segment
+if (!TryParseLastNumber(MajorStr, GoodVersion.Major, GoodVersion.MajorStr))
+  return BadVersion;
+return GoodVersion;
   }
 
+  if (!TryParseNumber(MajorStr, GoodVersion.Major))
+return BadVersion;
+  GoodVersion.MajorStr = MajorStr;
+
+  if (PatchStr.empty()) {
+// If no patch string, minor is the last seg

[clang] de7c006 - [PowerPC] Fix use of FPSCR builtins in smmintrin.h (#67299)

2023-10-26 Thread via cfe-commits

Author: Qiu Chaofan
Date: 2023-10-26T15:56:32+08:00
New Revision: de7c0068329d78027df7b7184d72646c1ca9f2bd

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

LOG: [PowerPC] Fix use of FPSCR builtins in smmintrin.h (#67299)

smmintrin.h uses __builtin_mffs, __builtin_mffsl, __builtin_mtfsf and
__builtin_set_fpscr_rn. This patch replaces the uses with ppc prefix
and implement the missing ones.

Added: 


Modified: 
clang/include/clang/Basic/BuiltinsPPC.def
clang/lib/Basic/Targets/PPC.cpp
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/Headers/ppc_wrappers/smmintrin.h
clang/test/CodeGen/PowerPC/builtins-ppc.c
clang/test/CodeGen/PowerPC/ppc-emmintrin.c
clang/test/CodeGen/PowerPC/ppc-mmintrin.c
clang/test/CodeGen/PowerPC/ppc-pmmintrin.c
clang/test/CodeGen/PowerPC/ppc-smmintrin.c
clang/test/CodeGen/PowerPC/ppc-tmmintrin.c
clang/test/CodeGen/PowerPC/ppc-x86gprintrin.c

Removed: 




diff  --git a/clang/include/clang/Basic/BuiltinsPPC.def 
b/clang/include/clang/Basic/BuiltinsPPC.def
index 18a1186053481ed..a35488ed3dfa565 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -151,9 +151,11 @@ TARGET_BUILTIN(__builtin_ppc_extract_exp, "Uid", "", 
"power9-vector")
 TARGET_BUILTIN(__builtin_ppc_extract_sig, "ULLid", "", "power9-vector")
 BUILTIN(__builtin_ppc_mtfsb0, "vUIi", "")
 BUILTIN(__builtin_ppc_mtfsb1, "vUIi", "")
+BUILTIN(__builtin_ppc_mffs, "d", "")
 TARGET_BUILTIN(__builtin_ppc_mffsl, "d", "", "isa-v30-instructions")
 BUILTIN(__builtin_ppc_mtfsf, "vUIiUi", "")
 BUILTIN(__builtin_ppc_mtfsfi, "vUIiUIi", "")
+BUILTIN(__builtin_ppc_set_fpscr_rn, "di", "")
 TARGET_BUILTIN(__builtin_ppc_insert_exp, "ddULLi", "", "power9-vector")
 BUILTIN(__builtin_ppc_fmsub, "", "")
 BUILTIN(__builtin_ppc_fmsubs, "", "")

diff  --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 0d87a3a4e8c20f3..5ce276e1af9ef64 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -264,6 +264,10 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
   Builder.defineMacro("__builtin_minfe", "__builtin_ppc_minfe");
   Builder.defineMacro("__builtin_minfl", "__builtin_ppc_minfl");
   Builder.defineMacro("__builtin_minfs", "__builtin_ppc_minfs");
+  Builder.defineMacro("__builtin_mffs", "__builtin_ppc_mffs");
+  Builder.defineMacro("__builtin_mffsl", "__builtin_ppc_mffsl");
+  Builder.defineMacro("__builtin_mtfsf", "__builtin_ppc_mtfsf");
+  Builder.defineMacro("__builtin_set_fpscr_rn", "__builtin_ppc_set_fpscr_rn");
 }
 
 /// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 85be8bdd00516cb..dce5ee5888c458e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -17397,6 +17397,11 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned 
BuiltinID,
 Value *Op1 = EmitScalarExpr(E->getArg(1));
 return Builder.CreateFDiv(Op0, Op1, "swdiv");
   }
+  case PPC::BI__builtin_ppc_set_fpscr_rn:
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_setrnd),
+  {EmitScalarExpr(E->getArg(0))});
+  case PPC::BI__builtin_ppc_mffs:
+return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_readflm));
   }
 }
 

diff  --git a/clang/lib/Headers/ppc_wrappers/smmintrin.h 
b/clang/lib/Headers/ppc_wrappers/smmintrin.h
index 349b395c4f00b92..19cdecb18d2b83f 100644
--- a/clang/lib/Headers/ppc_wrappers/smmintrin.h
+++ b/clang/lib/Headers/ppc_wrappers/smmintrin.h
@@ -14,7 +14,7 @@
 
 #ifndef NO_WARN_X86_INTRINSICS
 /* This header is distributed to simplify porting x86_64 code that
-   makes explicit use of Intel intrinsics to powerp64/powerpc64le.
+   makes explicit use of Intel intrinsics to powerpc64/powerpc64le.
 
It is the user's responsibility to determine if the results are
acceptable and make additional changes as necessary.
@@ -68,10 +68,10 @@ extern __inline __m128d
 __asm__("mffsce %0" : "=f"(__fpscr_save.__fr));
 __enables_save.__fpscr = __fpscr_save.__fpscr & 0xf8;
 #else
-__fpscr_save.__fr = __builtin_mffs();
+__fpscr_save.__fr = __builtin_ppc_mffs();
 __enables_save.__fpscr = __fpscr_save.__fpscr & 0xf8;
 __fpscr_save.__fpscr &= ~0xf8;
-__builtin_mtfsf(0b0011, __fpscr_save.__fr);
+__builtin_ppc_mtfsf(0b0011, __fpscr_save.__fr);
 #endif
 /* Insert an artificial "read/write" reference to the variable
read below, to ensure the compiler does not schedule
@@ -83,10 +83,15 @@ extern __inline __m128d
 
   switch (__rounding) {
   case _MM_FROUND_TO_NEAREST_INT:
-__fpscr_save.__fr = __builtin_mffsl();
+#ifdef _ARCH_PWR9
+__fpscr_save.__

[clang-tools-extra] [PowerPC] Fix use of FPSCR builtins in smmintrin.h (PR #67299)

2023-10-26 Thread Qiu Chaofan via cfe-commits

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


[clang-tools-extra] [clang-tidy] Improve bugprone-unused-return-value check (PR #66573)

2023-10-26 Thread Congcong Cai via cfe-commits

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


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


[clang] [Driver] Reject unsupported -mcmodel= (PR #70262)

2023-10-26 Thread Peter Smith via cfe-commits

https://github.com/smithp35 commented:

I'm happy with this on the AArch64 side.

If clang for a target defaults to position independent code this may lead to 
some -mcmodel=large projects failing to build, at least until they add -fno-pic 

Could we add this to the release notes? Perhaps in the form that users of 
-mcmodel=large on AArch64 are recommended to add -fno-pic.

I think this is better than -mcmodel=large silently producing non position 
independent code. 

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


[clang] [DAGCombine] Fold setcc_eq infinity into is.fpclass (PR #67829)

2023-10-26 Thread Qiu Chaofan via cfe-commits

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

>From 45906e0ec45c9302f4d9af10b94276c7f7185fef Mon Sep 17 00:00:00 2001
From: Qiu Chaofan 
Date: Sat, 30 Sep 2023 00:21:14 +0800
Subject: [PATCH 1/2] [DAGCombine] Fold setcc_eq infinity into is.fpclass

---
 .../CodeGen/SelectionDAG/TargetLowering.cpp   | 14 +
 llvm/test/CodeGen/PowerPC/fp-classify.ll  | 53 +++
 llvm/test/CodeGen/PowerPC/is_fpclass.ll   |  7 +--
 3 files changed, 34 insertions(+), 40 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp 
b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index c0e88051dc427f1..ec5591a3528eab8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -5064,6 +5064,20 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue 
N0, SDValue N1,
   }
 }
 
+if (isOperationLegalOrCustom(ISD::IS_FPCLASS, N0.getValueType()) &&
+!isFPImmLegal(CFP->getValueAPF(), CFP->getValueType(0))) {
+  bool IsFabs = N0.getOpcode() == ISD::FABS;
+  SDValue Op = IsFabs ? N0.getOperand(0) : N0;
+  if ((Cond == ISD::SETOEQ || Cond == ISD::SETUEQ) && CFP->isInfinity()) {
+FPClassTest Flag = CFP->isNegative() ? (IsFabs ? fcNone : fcNegInf)
+ : (IsFabs ? fcInf : fcPosInf);
+if (Cond == ISD::SETUEQ)
+  Flag |= fcNan;
+return DAG.getNode(ISD::IS_FPCLASS, dl, VT, Op,
+   DAG.getTargetConstant(Flag, dl, MVT::i32));
+  }
+}
+
 // If the condition is not legal, see if we can find an equivalent one
 // which is legal.
 if (!isCondCodeLegal(Cond, N0.getSimpleValueType())) {
diff --git a/llvm/test/CodeGen/PowerPC/fp-classify.ll 
b/llvm/test/CodeGen/PowerPC/fp-classify.ll
index 26cde62071224fb..7de35b880a5d9cf 100644
--- a/llvm/test/CodeGen/PowerPC/fp-classify.ll
+++ b/llvm/test/CodeGen/PowerPC/fp-classify.ll
@@ -18,12 +18,9 @@ define zeroext i1 @abs_isinff(float %x) {
 ;
 ; P9-LABEL: abs_isinff:
 ; P9:   # %bb.0: # %entry
-; P9-NEXT:addis 3, 2, .LCPI0_0@toc@ha
-; P9-NEXT:xsabsdp 0, 1
-; P9-NEXT:li 4, 1
-; P9-NEXT:lfs 1, .LCPI0_0@toc@l(3)
+; P9-NEXT:xststdcsp 0, 1, 48
 ; P9-NEXT:li 3, 0
-; P9-NEXT:fcmpu 0, 0, 1
+; P9-NEXT:li 4, 1
 ; P9-NEXT:iseleq 3, 4, 3
 ; P9-NEXT:blr
 entry:
@@ -46,12 +43,9 @@ define zeroext i1 @abs_isinf(double %x) {
 ;
 ; P9-LABEL: abs_isinf:
 ; P9:   # %bb.0: # %entry
-; P9-NEXT:addis 3, 2, .LCPI1_0@toc@ha
-; P9-NEXT:xsabsdp 0, 1
-; P9-NEXT:li 4, 1
-; P9-NEXT:lfs 1, .LCPI1_0@toc@l(3)
+; P9-NEXT:xststdcdp 0, 1, 48
 ; P9-NEXT:li 3, 0
-; P9-NEXT:fcmpu 0, 0, 1
+; P9-NEXT:li 4, 1
 ; P9-NEXT:iseleq 3, 4, 3
 ; P9-NEXT:blr
 entry:
@@ -91,13 +85,9 @@ define zeroext i1 @abs_isinfq(fp128 %x) {
 ;
 ; P9-LABEL: abs_isinfq:
 ; P9:   # %bb.0: # %entry
-; P9-NEXT:addis 3, 2, .LCPI2_0@toc@ha
-; P9-NEXT:xsabsqp 2, 2
-; P9-NEXT:li 4, 1
-; P9-NEXT:addi 3, 3, .LCPI2_0@toc@l
-; P9-NEXT:lxv 35, 0(3)
+; P9-NEXT:xststdcqp 0, 2, 48
 ; P9-NEXT:li 3, 0
-; P9-NEXT:xscmpuqp 0, 2, 3
+; P9-NEXT:li 4, 1
 ; P9-NEXT:iseleq 3, 4, 3
 ; P9-NEXT:blr
 entry:
@@ -119,12 +109,10 @@ define zeroext i1 @abs_isinfornanf(float %x) {
 ;
 ; P9-LABEL: abs_isinfornanf:
 ; P9:   # %bb.0: # %entry
-; P9-NEXT:addis 3, 2, .LCPI3_0@toc@ha
-; P9-NEXT:xsabsdp 0, 1
-; P9-NEXT:lfs 1, .LCPI3_0@toc@l(3)
-; P9-NEXT:li 3, 1
-; P9-NEXT:fcmpu 0, 0, 1
-; P9-NEXT:isellt 3, 0, 3
+; P9-NEXT:xststdcsp 0, 1, 112
+; P9-NEXT:li 3, 0
+; P9-NEXT:li 4, 1
+; P9-NEXT:iseleq 3, 4, 3
 ; P9-NEXT:blr
 entry:
   %0 = tail call float @llvm.fabs.f32(float %x)
@@ -145,12 +133,10 @@ define zeroext i1 @abs_isinfornan(double %x) {
 ;
 ; P9-LABEL: abs_isinfornan:
 ; P9:   # %bb.0: # %entry
-; P9-NEXT:addis 3, 2, .LCPI4_0@toc@ha
-; P9-NEXT:xsabsdp 0, 1
-; P9-NEXT:lfs 1, .LCPI4_0@toc@l(3)
-; P9-NEXT:li 3, 1
-; P9-NEXT:fcmpu 0, 0, 1
-; P9-NEXT:isellt 3, 0, 3
+; P9-NEXT:xststdcdp 0, 1, 112
+; P9-NEXT:li 3, 0
+; P9-NEXT:li 4, 1
+; P9-NEXT:iseleq 3, 4, 3
 ; P9-NEXT:blr
 entry:
   %0 = tail call double @llvm.fabs.f64(double %x)
@@ -212,13 +198,10 @@ define zeroext i1 @abs_isinfornanq(fp128 %x) {
 ;
 ; P9-LABEL: abs_isinfornanq:
 ; P9:   # %bb.0: # %entry
-; P9-NEXT:addis 3, 2, .LCPI5_0@toc@ha
-; P9-NEXT:xsabsqp 2, 2
-; P9-NEXT:addi 3, 3, .LCPI5_0@toc@l
-; P9-NEXT:lxv 35, 0(3)
-; P9-NEXT:li 3, 1
-; P9-NEXT:xscmpuqp 0, 2, 3
-; P9-NEXT:isellt 3, 0, 3
+; P9-NEXT:xststdcqp 0, 2, 112
+; P9-NEXT:li 3, 0
+; P9-NEXT:li 4, 1
+; P9-NEXT:iseleq 3, 4, 3
 ; P9-NEXT:blr
 entry:
   %0 = tail call fp128 @llvm.fabs.f128(fp128 %x)
diff --git a/llvm/test/CodeGen/PowerPC/is_fpclass.ll 
b/llvm/test/CodeGen/PowerPC/is_fpclass.ll
index 1ba4749d7437df5..57f457553a54070 10

[clang] [Driver] Reject unsupported -mcmodel= (PR #70262)

2023-10-26 Thread Kito Cheng via cfe-commits

kito-cheng wrote:

LGTM for the RISC-V bits, thanks :)

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


[clang] [clang][NFC] Refactor enums that hold size of `Type` and `DeclContext` bit-fields (PR #70296)

2023-10-26 Thread Chuanqi Xu via cfe-commits

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

LGTM. Consistency is good.

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


[clang] [analyzer] Extend EnumCastOutOfRange diagnostics (PR #68191)

2023-10-26 Thread Endre Fülöp via cfe-commits

https://github.com/gamesh411 updated 
https://github.com/llvm/llvm-project/pull/68191

From a08f51109bd93f88271f0548719c52c75afc96e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= 
Date: Wed, 4 Oct 2023 10:38:00 +0200
Subject: [PATCH 1/3] [analyzer] Extend EnumCastOutOfRange diagnostics

EnumCastOutOfRange checker now reports the name of the enum in the
warning message. Additionally, a note-tag is placed to highlight the
location of the declaration.
---
 .../Checkers/EnumCastOutOfRangeChecker.cpp|  33 --
 clang/test/Analysis/enum-cast-out-of-range.c  |  13 ++-
 .../test/Analysis/enum-cast-out-of-range.cpp  | 108 +-
 3 files changed, 87 insertions(+), 67 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
index 89be6a47250a245..6163f7a23804091 100644
--- a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
@@ -59,7 +59,7 @@ class ConstraintBasedEQEvaluator {
 // value can be matching.
 class EnumCastOutOfRangeChecker : public Checker> {
   mutable std::unique_ptr EnumValueCastOutOfRange;
-  void reportWarning(CheckerContext &C) const;
+  void reportWarning(CheckerContext &C, const EnumDecl *E) const;
 
 public:
   void checkPreStmt(const CastExpr *CE, CheckerContext &C) const;
@@ -72,21 +72,36 @@ EnumValueVector getDeclValuesForEnum(const EnumDecl *ED) {
   EnumValueVector DeclValues(
   std::distance(ED->enumerator_begin(), ED->enumerator_end()));
   llvm::transform(ED->enumerators(), DeclValues.begin(),
- [](const EnumConstantDecl *D) { return D->getInitVal(); });
+  [](const EnumConstantDecl *D) { return D->getInitVal(); });
   return DeclValues;
 }
 } // namespace
 
-void EnumCastOutOfRangeChecker::reportWarning(CheckerContext &C) const {
+void EnumCastOutOfRangeChecker::reportWarning(CheckerContext &C,
+  const EnumDecl *E) const {
+  assert(E && "valid EnumDecl* is expected");
   if (const ExplodedNode *N = C.generateNonFatalErrorNode()) {
 if (!EnumValueCastOutOfRange)
   EnumValueCastOutOfRange.reset(
   new BugType(this, "Enum cast out of range"));
-constexpr llvm::StringLiteral Msg =
-"The value provided to the cast expression is not in the valid range"
-" of values for the enum";
-C.emitReport(std::make_unique(
-*EnumValueCastOutOfRange, Msg, N));
+
+llvm::SmallString<128> Msg{"The value provided to the cast expression is "
+   "not in the valid range of values for "};
+StringRef EnumName{E->getName()};
+if (EnumName.empty()) {
+  Msg += "the enum";
+} else {
+  Msg += '\'';
+  Msg += EnumName;
+  Msg += '\'';
+}
+
+auto BR = 
std::make_unique(*EnumValueCastOutOfRange,
+   Msg, N);
+BR->addNote("enum declared here",
+PathDiagnosticLocation::create(E, C.getSourceManager()),
+{E->getSourceRange()});
+C.emitReport(std::move(BR));
   }
 }
 
@@ -144,7 +159,7 @@ void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr 
*CE,
   // If there is no value that can possibly match any of the enum values, then
   // warn.
   if (!PossibleValueMatch)
-reportWarning(C);
+reportWarning(C, ED);
 }
 
 void ento::registerEnumCastOutOfRangeChecker(CheckerManager &mgr) {
diff --git a/clang/test/Analysis/enum-cast-out-of-range.c 
b/clang/test/Analysis/enum-cast-out-of-range.c
index 3282cba653d7125..6d3afa3fcf9885f 100644
--- a/clang/test/Analysis/enum-cast-out-of-range.c
+++ b/clang/test/Analysis/enum-cast-out-of-range.c
@@ -2,6 +2,7 @@
 // RUN:   -analyzer-checker=core,alpha.cplusplus.EnumCastOutOfRange \
 // RUN:   -verify %s
 
+// expected-note@+1 6 {{enum declared here}}
 enum En_t {
   En_0 = -4,
   En_1,
@@ -11,17 +12,17 @@ enum En_t {
 };
 
 void unscopedUnspecifiedCStyle(void) {
-  enum En_t Below = (enum En_t)(-5);// expected-warning {{not in the valid 
range}}
+  enum En_t Below = (enum En_t)(-5);// expected-warning {{not in the valid 
range of values for 'En_t'}}
   enum En_t NegVal1 = (enum En_t)(-4);  // OK.
   enum En_t NegVal2 = (enum En_t)(-3);  // OK.
-  enum En_t InRange1 = (enum En_t)(-2); // expected-warning {{not in the valid 
range}}
-  enum En_t InRange2 = (enum En_t)(-1); // expected-warning {{not in the valid 
range}}
-  enum En_t InRange3 = (enum En_t)(0);  // expected-warning {{not in the valid 
range}}
+  enum En_t InRange1 = (enum En_t)(-2); // expected-warning {{not in the valid 
range of values for 'En_t'}}
+  enum En_t InRange2 = (enum En_t)(-1); // expected-warning {{not in the valid 
range of values for 'En_t'}}
+  enum En_t InRange3 = (enum En_t)(0);  // expected-warning {{not in the valid 
range of values for 'En_t'}}
   enum En_t PosVal1 = (enum En_t)(

[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/70306

Implement handling for new/delete/new[]/delete[] expressions via a new 
`DynamicAllocator` class.

This introduces four new opcodes:
 - `Alloc` - Allocates one element (`new int(14)`)
 - `AllocN` - Allocates N elements of the given primitive (`new int[100]`)
 - `AllocCN` - Allocates N elements of the given (composite) descriptor (`new 
S[100]`)
 - `Free` - de-allocates memory allocates using any of the above.


This patch currently has a few NFC changes (like adding `const` in some places) 
that I will push to `main` later today. Some other changes I just noticed are 
in `tests/`, which I will just remove.

>From af781eac608a41349bfdd6da094df1248d9730ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH] [clang][Interp] Implement dynamic memory allocation handling

---
 clang/lib/AST/CMakeLists.txt  |   1 +
 clang/lib/AST/ExprConstant.cpp|   2 +-
 clang/lib/AST/Interp/ByteCodeExprGen.cpp  |  76 +++
 clang/lib/AST/Interp/ByteCodeExprGen.h|   2 +
 clang/lib/AST/Interp/Context.cpp  |   3 +-
 clang/lib/AST/Interp/Descriptor.cpp   |   2 +-
 clang/lib/AST/Interp/Descriptor.h |   6 +-
 clang/lib/AST/Interp/DynamicAllocator.cpp |  91 
 clang/lib/AST/Interp/DynamicAllocator.h   |  90 
 clang/lib/AST/Interp/EvalEmitter.cpp  |   5 +-
 clang/lib/AST/Interp/Interp.cpp   |  37 
 clang/lib/AST/Interp/Interp.h |  94 
 clang/lib/AST/Interp/InterpBlock.h|  10 +-
 clang/lib/AST/Interp/InterpState.cpp  |  17 ++
 clang/lib/AST/Interp/InterpState.h|  10 +
 clang/lib/AST/Interp/Opcodes.td   |  25 +++
 clang/lib/AST/Interp/Pointer.cpp  |   2 +-
 clang/lib/AST/Interp/Pointer.h|   7 +-
 clang/test/AST/Interp/new-delete.cpp  | 247 ++
 clang/test/SemaCXX/cxx2a-consteval.cpp|  43 +---
 20 files changed, 712 insertions(+), 58 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index fe3f8c485ec1c56..1423623fb038cab 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -75,6 +75,7 @@ add_clang_library(clangAST
   Interp/Function.cpp
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6b47b8a1256477d..0a95259821466e2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6860,8 +6860,8 @@ static std::optional CheckDeleteKind(EvalInfo 
&Info, const Expr *E,
 return std::nullopt;
   }
 
-  QualType AllocType = Pointer.Base.getDynamicAllocType();
   if (DeallocKind != (*Alloc)->getKind()) {
+QualType AllocType = Pointer.Base.getDynamicAllocType();
 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
 << DeallocKind << (*Alloc)->getKind() << AllocType;
 NoteLValueLocation(Info, Pointer.Base);
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 1b33c69b93aa4b9..c42fcabe3b075ba 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1617,6 +1617,82 @@ bool 
ByteCodeExprGen::VisitCXXScalarValueInitExpr(
   return this->visitZeroInitializer(classifyPrim(Ty), Ty, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+assert(E->getArraySize());
+PrimType SizeT = classifyPrim((*E->getArraySize())->getType());
+
+if (!this->visit(*E->getArraySize()))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, E))
+return false;
+}
+
+  } else {
+//

[clang] [RISCV] Add processor definition for XiangShan-NanHu (PR #70294)

2023-10-26 Thread Yingwei Zheng via cfe-commits

https://github.com/dtcxzyw updated 
https://github.com/llvm/llvm-project/pull/70294

>From a4e46c81c5235754bf7b4e0b3dd3ff8805b3e56d Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Thu, 26 Oct 2023 13:47:39 +0800
Subject: [PATCH 1/2] [RISCV] Add processor definition for XiangShan-NanHu

Co-authored-by: SForeKeeper 
---
 clang/test/Driver/riscv-cpus.c| 14 ++
 clang/test/Misc/target-invalid-cpu-note.c |  4 ++--
 llvm/lib/Target/RISCV/RISCVProcessors.td  | 21 +
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
index 3eaceedce685fc6..70f0a63336bd478 100644
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -20,6 +20,17 @@
 // MCPU-SYNTACORE-SCR1-MAX: "-target-feature" "+zicsr" "-target-feature" 
"+zifencei"
 // MCPU-SYNTACORE-SCR1-MAX: "-target-abi" "ilp32"
 
+// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=xiangshan-nanhu | 
FileCheck -check-prefix=MCPU-XIANGSHAN-NANHU %s
+// MCPU-XIANGSHAN-NANHU: "-nostdsysteminc" "-target-cpu" "xiangshan-nanhu"
+// MCPU-XIANGSHAN-NANHU: "-target-feature" "+m" "-target-feature" "+a" 
"-target-feature" "+f" "-target-feature" "+d"
+// MCPU-XIANGSHAN-NANHU: "-target-feature" "+c"
+// MCPU-XIANGSHAN-NANHU: "-target-feature" "+zicbom" "-target-feature" 
"+zicboz" "-target-feature" "+zicsr" "-target-feature" "+zifencei"
+// MCPU-XIANGSHAN-NANHU: "-target-feature" "+zba" "-target-feature" "+zbb" 
"-target-feature" "+zbc"
+// MCPU-XIANGSHAN-NANHU: "-target-feature" "+zbkb" "-target-feature" "+zbkc" 
"-target-feature" "+zbkx" "-target-feature" "+zbs"
+// MCPU-XIANGSHAN-NANHU: "-target-feature" "+zkn" "-target-feature" "+zknd" 
"-target-feature" "+zkne" "-target-feature" "+zknh"
+// MCPU-XIANGSHAN-NANHU: "-target-feature" "+zks" "-target-feature" "+zksed" 
"-target-feature" "+zksh" "-target-feature" "+svinval"
+// MCPU-XIANGSHAN-NANHU: "-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
@@ -62,6 +73,9 @@
 // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=veyron-v1 | FileCheck 
-check-prefix=MTUNE-VEYRON-V1 %s
 // MTUNE-VEYRON-V1: "-tune-cpu" "veyron-v1"
 
+// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=xiangshan-nanhu | 
FileCheck -check-prefix=MTUNE-XIANGSHAN-NANHU %s
+// MTUNE-XIANGSHAN-NANHU: "-tune-cpu" "xiangshan-nanhu"
+
 // Check mtune alias CPU has resolved to the right CPU according XLEN.
 // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=generic | FileCheck 
-check-prefix=MTUNE-GENERIC-32 %s
 // MTUNE-GENERIC-32: "-tune-cpu" "generic"
diff --git a/clang/test/Misc/target-invalid-cpu-note.c 
b/clang/test/Misc/target-invalid-cpu-note.c
index b2a04ebdbce628f..8e91eb4c62dd259 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-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, sifive-u74, 
sifive-x280, veyron-v1{{$}}
+// RISCV64-NEXT: note: valid target CPU values are: generic-rv64, rocket-rv64, 
sifive-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, sifive-u74, 
sifive-x280, 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-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, 
sifive-u74, sifive-x280, veyron-v1, generic, rocket, sifive-7-series{{$}}
+// TUNE-RISCV64-NEXT: note: valid target CPU values are: generic-rv64, 
rocket-rv64, sifive-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, 
sifive-u74, sifive-x280, 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 e4008d145ffa572..427e15bea2f8dce 100644
--- a/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -243,3 +243,24 @@ def VENTANA_VEYRON_V1 : RISCVProcessorModel<"veyron-v1",
  FeatureStdExtZicbop,
  FeatureStdExtZicboz,
  FeatureVendorXVentanaCondOps]>;
+
+def XIANGSH

[clang] [clang] Emit bad shift warnings (PR #70307)

2023-10-26 Thread Budimir Aranđelović via cfe-commits

https://github.com/budimirarandjelovicsyrmia created 
https://github.com/llvm/llvm-project/pull/70307

Diagnose bad shifts and emit warnings

From 894d6503b0e1ced73bab65b0454abfc65d5b8a99 Mon Sep 17 00:00:00 2001
From: budimirarandjelovicsyrmia 
Date: Thu, 26 Oct 2023 10:39:52 +0200
Subject: [PATCH] [clang] Emit bad shift warnings

---
 clang/lib/AST/ExprConstant.cpp | 11 ++--
 clang/lib/Sema/SemaExpr.cpp| 59 +-
 clang/test/AST/Interp/shifts.cpp   |  7 +--
 clang/test/C/drs/dr0xx.c   |  2 +-
 clang/test/Sema/shift-count-negative.c |  8 +++
 clang/test/Sema/shift-count-overflow.c |  6 +++
 clang/test/Sema/shift-negative-value.c |  8 +++
 clang/test/Sema/vla-2.c|  9 ++--
 clang/test/SemaCXX/cxx2a-explicit-bool.cpp |  2 +-
 clang/test/SemaCXX/shift.cpp   |  1 -
 10 files changed, 84 insertions(+), 29 deletions(-)
 create mode 100644 clang/test/Sema/shift-count-negative.c
 create mode 100644 clang/test/Sema/shift-count-overflow.c
 create mode 100644 clang/test/Sema/shift-negative-value.c

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 78cfecbec9fd363..52ee2655c18f994 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -2803,9 +2803,10 @@ static bool handleIntIntBinOp(EvalInfo &Info, const Expr 
*E, const APSInt &LHS,
 // C++11 [expr.shift]p1: Shift width must be less than the bit width of
 // the shifted type.
 unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
-if (SA != RHS) {
+if (SA != RHS && Info.getLangOpts().CPlusPlus11) {
   Info.CCEDiag(E, diag::note_constexpr_large_shift)
-<< RHS << E->getType() << LHS.getBitWidth();
+  << RHS << E->getType() << LHS.getBitWidth();
+  return false;
 } else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
   // C++11 [expr.shift]p2: A signed left shift must have a non-negative
   // operand, and must not overflow the corresponding unsigned type.
@@ -2836,9 +2837,11 @@ static bool handleIntIntBinOp(EvalInfo &Info, const Expr 
*E, const APSInt &LHS,
 // C++11 [expr.shift]p1: Shift width must be less than the bit width of the
 // shifted type.
 unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
-if (SA != RHS)
+if (SA != RHS && Info.getLangOpts().CPlusPlus11) {
   Info.CCEDiag(E, diag::note_constexpr_large_shift)
-<< RHS << E->getType() << LHS.getBitWidth();
+  << RHS << E->getType() << LHS.getBitWidth();
+  return false;
+}
 Result = LHS >> SA;
 return true;
   }
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 94f52004cf6c27a..8d3768c06915ce9 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11428,26 +11428,35 @@ static bool isScopedEnumerationType(QualType T) {
   return false;
 }
 
-static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
-   SourceLocation Loc, BinaryOperatorKind Opc,
-   QualType LHSType) {
+enum BadShiftValueKind {
+  BSV_Ok,
+  BSV_ShiftIsNegative,
+  BSV_ShiftLHSIsNegative,
+  BSV_ShiftSizeGTTypeWidth,
+};
+
+static BadShiftValueKind DiagnoseBadShiftValues(Sema &S, ExprResult &LHS,
+ExprResult &RHS,
+SourceLocation Loc,
+BinaryOperatorKind Opc,
+QualType LHSType) {
   // OpenCL 6.3j: shift values are effectively % word size of LHS (more 
defined),
   // so skip remaining warnings as we don't want to modify values within Sema.
   if (S.getLangOpts().OpenCL)
-return;
+return BSV_Ok;
 
   // Check right/shifter operand
   Expr::EvalResult RHSResult;
   if (RHS.get()->isValueDependent() ||
   !RHS.get()->EvaluateAsInt(RHSResult, S.Context))
-return;
+return BSV_Ok;
   llvm::APSInt Right = RHSResult.Val.getInt();
 
   if (Right.isNegative()) {
 S.DiagRuntimeBehavior(Loc, RHS.get(),
   S.PDiag(diag::warn_shift_negative)
 << RHS.get()->getSourceRange());
-return;
+return BSV_ShiftIsNegative;
   }
 
   QualType LHSExprType = LHS.get()->getType();
@@ -11463,12 +11472,12 @@ static void DiagnoseBadShiftValues(Sema& S, 
ExprResult &LHS, ExprResult &RHS,
 S.DiagRuntimeBehavior(Loc, RHS.get(),
   S.PDiag(diag::warn_shift_gt_typewidth)
 << RHS.get()->getSourceRange());
-return;
+return BSV_ShiftSizeGTTypeWidth;
   }
 
   // FIXME: We probably need to handle fixed point types specially here.
   if (Opc != BO_Shl || LHSExprType->isFixedPointType())
-return;
+return BSV_Ok;
 
   // When left shifting an ICE which is signed, we can check for overflow whi

[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

Implement handling for new/delete/new[]/delete[] expressions via a new 
`DynamicAllocator` class.

This introduces four new opcodes:
 - `Alloc` - Allocates one element (`new int(14)`)
 - `AllocN` - Allocates N elements of the given primitive (`new int[100]`)
 - `AllocCN` - Allocates N elements of the given (composite) descriptor (`new 
S[100]`)
 - `Free` - de-allocates memory allocates using any of the above.


This patch currently has a few NFC changes (like adding `const` in some places) 
that I will push to `main` later today. Some other changes I just noticed are 
in `tests/`, which I will just remove.

---

Patch is 41.19 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/70306.diff


20 Files Affected:

- (modified) clang/lib/AST/CMakeLists.txt (+1) 
- (modified) clang/lib/AST/ExprConstant.cpp (+1-1) 
- (modified) clang/lib/AST/Interp/ByteCodeExprGen.cpp (+76) 
- (modified) clang/lib/AST/Interp/ByteCodeExprGen.h (+2) 
- (modified) clang/lib/AST/Interp/Context.cpp (+2-1) 
- (modified) clang/lib/AST/Interp/Descriptor.cpp (+1-1) 
- (modified) clang/lib/AST/Interp/Descriptor.h (+3-3) 
- (added) clang/lib/AST/Interp/DynamicAllocator.cpp (+91) 
- (added) clang/lib/AST/Interp/DynamicAllocator.h (+90) 
- (modified) clang/lib/AST/Interp/EvalEmitter.cpp (+3-2) 
- (modified) clang/lib/AST/Interp/Interp.cpp (+37) 
- (modified) clang/lib/AST/Interp/Interp.h (+94) 
- (modified) clang/lib/AST/Interp/InterpBlock.h (+5-5) 
- (modified) clang/lib/AST/Interp/InterpState.cpp (+17) 
- (modified) clang/lib/AST/Interp/InterpState.h (+10) 
- (modified) clang/lib/AST/Interp/Opcodes.td (+25) 
- (modified) clang/lib/AST/Interp/Pointer.cpp (+1-1) 
- (modified) clang/lib/AST/Interp/Pointer.h (+4-3) 
- (added) clang/test/AST/Interp/new-delete.cpp (+247) 
- (modified) clang/test/SemaCXX/cxx2a-consteval.cpp (+2-41) 


``diff
diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index fe3f8c485ec1c56..1423623fb038cab 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -75,6 +75,7 @@ add_clang_library(clangAST
   Interp/Function.cpp
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6b47b8a1256477d..0a95259821466e2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6860,8 +6860,8 @@ static std::optional CheckDeleteKind(EvalInfo 
&Info, const Expr *E,
 return std::nullopt;
   }
 
-  QualType AllocType = Pointer.Base.getDynamicAllocType();
   if (DeallocKind != (*Alloc)->getKind()) {
+QualType AllocType = Pointer.Base.getDynamicAllocType();
 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
 << DeallocKind << (*Alloc)->getKind() << AllocType;
 NoteLValueLocation(Info, Pointer.Base);
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 1b33c69b93aa4b9..c42fcabe3b075ba 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1617,6 +1617,82 @@ bool 
ByteCodeExprGen::VisitCXXScalarValueInitExpr(
   return this->visitZeroInitializer(classifyPrim(Ty), Ty, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+assert(E->getArraySize());
+PrimType SizeT = classifyPrim((*E->getArraySize())->getType());
+
+if (!this->visit(*E->getArraySize()))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, E))
+return false;
+}
+
+  } else {
+// Allocate just one element.
+if (!this->emitAlloc(Desc, E))
+  return false;
+
+if (Init) {
+  if (ElemT) {
+if (!this->visit(Init))
+  return false;
+
+if (!this->emitInit(*ElemT, E))
+  return false;
+  } else {
+// Com

[clang] [RISCV] Add sched model for XiangShan-NanHu (PR #70232)

2023-10-26 Thread Yingwei Zheng via cfe-commits


@@ -20,6 +20,17 @@
 // MCPU-SYNTACORE-SCR1-MAX: "-target-feature" "+zicsr" "-target-feature" 
"+zifencei"
 // MCPU-SYNTACORE-SCR1-MAX: "-target-abi" "ilp32"
 
+// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=xiangshan-nanhu | 
FileCheck -check-prefix=MCPU-XIANGSHAN-NANHU %s
+// MCPU-XIANGSHAN-NANHU: "-nostdsysteminc" "-target-cpu" "xiangshan-nanhu"
+// MCPU-XIANGSHAN-NANHU: "-target-feature" "+m" "-target-feature" "+a" 
"-target-feature" "+f" "-target-feature" "+d"

dtcxzyw wrote:

Fixed. Please move to #70294 to review the processor definition part.

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


[PATCH] D141192: [Clang] Fix warnings on bad shifts.

2023-10-26 Thread Budimir Aranđelović via Phabricator via cfe-commits
budimirarandjelovicsyrmia added a comment.

Created Pull Request . 
Addressed all coments except ones addressing target architecture and 
considering emitting error instead of warning.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141192/new/

https://reviews.llvm.org/D141192

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


[clang] [Clang] Diagnose defaulted assignment operator with incompatible object parameter (PR #70176)

2023-10-26 Thread via cfe-commits


@@ -7748,6 +7748,24 @@ bool 
Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
 HadError = true;
   }
 }
+// [C++23][dcl.fct.def.default]/p2.2
+// if F2 has an implicit object parameter of type “reference to C”,
+// F1 may be an explicit object member function whose explicit object
+// parameter is of (possibly different) type “reference to C”,
+// in which case the type of F1 would differ from the type of F2
+// in that the type of F1 has an additional parameter;
+if (!Context.hasSameType(
+ThisType.getNonReferenceType().getUnqualifiedType(),
+Context.getRecordType(RD))) {
+  if (DeleteOnTypeMismatch)
+ShouldDeleteForTypeMismatch = true;
+  else {
+Diag(MD->getLocation(),
+ diag::err_defaulted_special_member_explicit_object_mismatch)
+<< (CSM == CXXMoveAssignment) << RD;

cor3ntin wrote:

What do you have in mind? the first parameter? I am not sure how useful it is 
though - we certainly don't do it for other warnings here.

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


[clang] [RISCV] Add processor definition for XiangShan-NanHu (PR #70294)

2023-10-26 Thread Yingwei Zheng via cfe-commits

dtcxzyw wrote:

> LGTM in general, except one question: will zicbom and zicboz be in the final 
> RTL?

You can find the full implementation of `zicbom` and `zicboz` here: 
https://github.com/OpenXiangShan/XiangShan/commit/ca18a0b47b0e4089fd0dd1c085091cb90bf98f25.
cc @poemonsense


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


[clang] [analyzer] Extend EnumCastOutOfRange diagnostics (PR #68191)

2023-10-26 Thread Endre Fülöp via cfe-commits

gamesh411 wrote:

@Xazax-hun Thanks for the review!
I have modified the tracking a bit, because seeing the other usecases, and also 
just thinking through, the *subexpression* of the cast is what we are 
interested in upstream in the bugpath.
I have added a very minimal test as well, and rebased.

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread via cfe-commits


@@ -1990,6 +2011,79 @@ inline bool OffsetOf(InterpState &S, CodePtr OpPC, const 
OffsetOfExpr *E) {
   return true;
 }
 
+inline bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
+  assert(Desc);
+
+  if (!CheckDynamicMemoryAllocation(S, OpPC))
+return false;
+
+  DynamicAllocator &Allocator = S.getAllocator();
+  Block *B = Allocator.allocate(Desc);
+
+  S.Stk.push(B, sizeof(InlineDescriptor));
+
+  return true;
+}
+
+template ::T>
+inline bool AllocN(InterpState &S, CodePtr OpPC, PrimType T,
+   const Expr *Source) {
+  if (!CheckDynamicMemoryAllocation(S, OpPC))
+return false;
+
+  SizeT NumElements = S.Stk.pop();
+
+  DynamicAllocator &Allocator = S.getAllocator();
+  Block *B = Allocator.allocate(Source, T, static_cast(NumElements));
+

cor3ntin wrote:

can we add an assert `B != null` here?

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread via cfe-commits


@@ -0,0 +1,91 @@
+//== DynamicAllocator.cpp - Types for the constexpr VM ---*- 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 "DynamicAllocator.h"
+#include "InterpBlock.h"
+#include "InterpState.h"
+
+using namespace clang;
+using namespace clang::interp;
+
+Block *DynamicAllocator::allocate(const Expr *Source, PrimType T,
+  size_t NumElements) {
+  assert(NumElements > 0);
+  // Create a new descriptor for an array of the specified size and
+  // element type.
+  const Descriptor *D = allocateDescriptor(
+  Source, T, Descriptor::InlineDescMD, NumElements, /*IsConst=*/false,
+  /*IsTemporary=*/false, /*IsMutable=*/false);
+  return allocate(D);
+}
+
+Block *DynamicAllocator::allocate(const Descriptor *ElementDesc,
+  size_t NumElements) {
+  assert(NumElements > 0);
+  // Create a new descriptor for an array of the specified size and
+  // element type.
+  const Descriptor *D = allocateDescriptor(
+  ElementDesc->asExpr(), ElementDesc, Descriptor::InlineDescMD, 
NumElements,
+  /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false);
+  return allocate(D);
+}
+
+Block *DynamicAllocator::allocate(const Descriptor *D) {
+  assert(D->asExpr());
+
+  auto Memory =
+  std::make_unique(sizeof(Block) + D->getAllocSize());
+  auto *B = new (Memory.get()) Block(D, /*isStatic=*/false);
+  B->invokeCtor();
+
+  InlineDescriptor *ID = reinterpret_cast(B->rawData());
+  ID->Desc = const_cast(D);
+  ID->IsActive = true;
+  ID->Offset = sizeof(InlineDescriptor);
+  ID->IsBase = false;
+  ID->IsFieldMutable = false;
+  ID->IsConst = false;
+  ID->IsInitialized = false;
+  assert(ID->Desc);
+
+  if (auto It = AllocationSites.find(D->asExpr()); It != AllocationSites.end())
+It->second.Allocations.emplace_back(std::move(Memory));
+  else
+AllocationSites.insert(
+{D->asExpr(), AllocationSite(std::move(Memory), D->isArray())});
+  return B;
+}
+
+void DynamicAllocator::deallocate(const Expr *Source,
+  const Block *BlockToDelete, InterpState &S) {
+  assert(AllocationSites.contains(Source));
+
+  auto It = AllocationSites.find(Source);
+  assert(It != AllocationSites.end());
+
+  auto &Site = It->second;
+  assert(Site.size() > 0);
+
+  // Find the Block to delete.
+  size_t I = 0;
+  [[maybe_unused]] bool Found = false;
+  for (auto &A : Site.Allocations) {
+Block *B = reinterpret_cast(A.Memory.get());
+if (B == BlockToDelete) {
+  S.deallocate(B);
+  B->invokeDtor();
+  Site.Allocations.erase(Site.Allocations.begin() + I);

cor3ntin wrote:

`I` is never incremented. Can we use std::find_if instead here?

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread via cfe-commits


@@ -1990,6 +2011,79 @@ inline bool OffsetOf(InterpState &S, CodePtr OpPC, const 
OffsetOfExpr *E) {
   return true;
 }
 
+inline bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
+  assert(Desc);
+
+  if (!CheckDynamicMemoryAllocation(S, OpPC))
+return false;
+
+  DynamicAllocator &Allocator = S.getAllocator();
+  Block *B = Allocator.allocate(Desc);
+
+  S.Stk.push(B, sizeof(InlineDescriptor));
+
+  return true;
+}
+
+template ::T>
+inline bool AllocN(InterpState &S, CodePtr OpPC, PrimType T,
+   const Expr *Source) {
+  if (!CheckDynamicMemoryAllocation(S, OpPC))
+return false;

cor3ntin wrote:

I think we want similar diagnostics as we have in `EvalInfo::CheckArraySize` 
here - ie for some large `NumElements` we should fail

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread via cfe-commits


@@ -0,0 +1,91 @@
+//== DynamicAllocator.cpp - Types for the constexpr VM ---*- 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 "DynamicAllocator.h"
+#include "InterpBlock.h"
+#include "InterpState.h"
+
+using namespace clang;
+using namespace clang::interp;
+
+Block *DynamicAllocator::allocate(const Expr *Source, PrimType T,
+  size_t NumElements) {
+  assert(NumElements > 0);
+  // Create a new descriptor for an array of the specified size and
+  // element type.
+  const Descriptor *D = allocateDescriptor(
+  Source, T, Descriptor::InlineDescMD, NumElements, /*IsConst=*/false,
+  /*IsTemporary=*/false, /*IsMutable=*/false);
+  return allocate(D);
+}
+
+Block *DynamicAllocator::allocate(const Descriptor *ElementDesc,
+  size_t NumElements) {
+  assert(NumElements > 0);
+  // Create a new descriptor for an array of the specified size and
+  // element type.
+  const Descriptor *D = allocateDescriptor(
+  ElementDesc->asExpr(), ElementDesc, Descriptor::InlineDescMD, 
NumElements,
+  /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false);
+  return allocate(D);
+}
+
+Block *DynamicAllocator::allocate(const Descriptor *D) {
+  assert(D->asExpr());
+
+  auto Memory =
+  std::make_unique(sizeof(Block) + D->getAllocSize());
+  auto *B = new (Memory.get()) Block(D, /*isStatic=*/false);
+  B->invokeCtor();
+
+  InlineDescriptor *ID = reinterpret_cast(B->rawData());
+  ID->Desc = const_cast(D);
+  ID->IsActive = true;
+  ID->Offset = sizeof(InlineDescriptor);
+  ID->IsBase = false;
+  ID->IsFieldMutable = false;
+  ID->IsConst = false;
+  ID->IsInitialized = false;
+  assert(ID->Desc);
+
+  if (auto It = AllocationSites.find(D->asExpr()); It != AllocationSites.end())
+It->second.Allocations.emplace_back(std::move(Memory));
+  else
+AllocationSites.insert(
+{D->asExpr(), AllocationSite(std::move(Memory), D->isArray())});
+  return B;
+}
+
+void DynamicAllocator::deallocate(const Expr *Source,
+  const Block *BlockToDelete, InterpState &S) {
+  assert(AllocationSites.contains(Source));
+
+  auto It = AllocationSites.find(Source);
+  assert(It != AllocationSites.end());
+
+  auto &Site = It->second;
+  assert(Site.size() > 0);
+
+  // Find the Block to delete.
+  size_t I = 0;
+  [[maybe_unused]] bool Found = false;
+  for (auto &A : Site.Allocations) {
+Block *B = reinterpret_cast(A.Memory.get());
+if (B == BlockToDelete) {
+  S.deallocate(B);
+  B->invokeDtor();

cor3ntin wrote:

Shouldn't these be swapped?

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread via cfe-commits


@@ -1990,6 +2011,79 @@ inline bool OffsetOf(InterpState &S, CodePtr OpPC, const 
OffsetOfExpr *E) {
   return true;
 }
 
+inline bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
+  assert(Desc);
+
+  if (!CheckDynamicMemoryAllocation(S, OpPC))
+return false;
+
+  DynamicAllocator &Allocator = S.getAllocator();
+  Block *B = Allocator.allocate(Desc);
+
+  S.Stk.push(B, sizeof(InlineDescriptor));
+
+  return true;
+}
+
+template ::T>
+inline bool AllocN(InterpState &S, CodePtr OpPC, PrimType T,
+   const Expr *Source) {
+  if (!CheckDynamicMemoryAllocation(S, OpPC))
+return false;
+
+  SizeT NumElements = S.Stk.pop();
+
+  DynamicAllocator &Allocator = S.getAllocator();
+  Block *B = Allocator.allocate(Source, T, static_cast(NumElements));
+
+  S.Stk.push(B, sizeof(InlineDescriptor));
+
+  return true;
+}
+
+template ::T>
+inline bool AllocCN(InterpState &S, CodePtr OpPC,
+const Descriptor *ElementDesc) {
+  if (!CheckDynamicMemoryAllocation(S, OpPC))
+return false;
+
+  SizeT NumElements = S.Stk.pop();
+
+  DynamicAllocator &Allocator = S.getAllocator();
+  Block *B = Allocator.allocate(ElementDesc, static_cast(NumElements));

cor3ntin wrote:

can we add an assert `B != null` here?

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread Timm Baeder via cfe-commits


@@ -0,0 +1,91 @@
+//== DynamicAllocator.cpp - Types for the constexpr VM ---*- 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 "DynamicAllocator.h"
+#include "InterpBlock.h"
+#include "InterpState.h"
+
+using namespace clang;
+using namespace clang::interp;
+
+Block *DynamicAllocator::allocate(const Expr *Source, PrimType T,
+  size_t NumElements) {
+  assert(NumElements > 0);
+  // Create a new descriptor for an array of the specified size and
+  // element type.
+  const Descriptor *D = allocateDescriptor(
+  Source, T, Descriptor::InlineDescMD, NumElements, /*IsConst=*/false,
+  /*IsTemporary=*/false, /*IsMutable=*/false);
+  return allocate(D);
+}
+
+Block *DynamicAllocator::allocate(const Descriptor *ElementDesc,
+  size_t NumElements) {
+  assert(NumElements > 0);
+  // Create a new descriptor for an array of the specified size and
+  // element type.
+  const Descriptor *D = allocateDescriptor(
+  ElementDesc->asExpr(), ElementDesc, Descriptor::InlineDescMD, 
NumElements,
+  /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false);
+  return allocate(D);
+}
+
+Block *DynamicAllocator::allocate(const Descriptor *D) {
+  assert(D->asExpr());
+
+  auto Memory =
+  std::make_unique(sizeof(Block) + D->getAllocSize());
+  auto *B = new (Memory.get()) Block(D, /*isStatic=*/false);
+  B->invokeCtor();
+
+  InlineDescriptor *ID = reinterpret_cast(B->rawData());
+  ID->Desc = const_cast(D);
+  ID->IsActive = true;
+  ID->Offset = sizeof(InlineDescriptor);
+  ID->IsBase = false;
+  ID->IsFieldMutable = false;
+  ID->IsConst = false;
+  ID->IsInitialized = false;
+  assert(ID->Desc);
+
+  if (auto It = AllocationSites.find(D->asExpr()); It != AllocationSites.end())
+It->second.Allocations.emplace_back(std::move(Memory));
+  else
+AllocationSites.insert(
+{D->asExpr(), AllocationSite(std::move(Memory), D->isArray())});
+  return B;
+}
+
+void DynamicAllocator::deallocate(const Expr *Source,
+  const Block *BlockToDelete, InterpState &S) {
+  assert(AllocationSites.contains(Source));
+
+  auto It = AllocationSites.find(Source);
+  assert(It != AllocationSites.end());
+
+  auto &Site = It->second;
+  assert(Site.size() > 0);
+
+  // Find the Block to delete.
+  size_t I = 0;
+  [[maybe_unused]] bool Found = false;
+  for (auto &A : Site.Allocations) {
+Block *B = reinterpret_cast(A.Memory.get());
+if (B == BlockToDelete) {
+  S.deallocate(B);
+  B->invokeDtor();
+  Site.Allocations.erase(Site.Allocations.begin() + I);

tbaederr wrote:

> I is never incremented.

lol, nice testing on my side.

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


[clang] [NFC] [Serializer] Pack information in serializer (PR #69287)

2023-10-26 Thread Chuanqi Xu via cfe-commits

https://github.com/ChuanqiXu9 updated 
https://github.com/llvm/llvm-project/pull/69287

>From 5a1f32f156801da271486dbb0fd37007adb4901c Mon Sep 17 00:00:00 2001
From: Chuanqi Xu 
Date: Mon, 16 Oct 2023 16:41:31 +0800
Subject: [PATCH 1/4] [NFC] [Serializer] Pack information in serializer

Previously, the boolean values will occupy spaces that can contain
integers. It wastes the spaces especially if the boolean values are
serialized consecutively. The patch tries to pack such consecutive
boolean values (and enum values) so that we can save more spaces and so
the times.

Before the patch, we need 4.478s (in my machine) to build the std module
(https://libcxx.llvm.org/Modules.html) with 28712 bytes. After the
patch, the time becomes to 4.374s and the size becomes to 27568 bytes.

This is intended to be a NFC patch.

This patch doesn't optimize all such cases. We can do it later after we
have consensus on this.
---
 clang/include/clang/AST/Decl.h|   2 +-
 clang/include/clang/AST/DeclBase.h|   2 +-
 clang/lib/Serialization/ASTReaderDecl.cpp | 229 +-
 clang/lib/Serialization/ASTWriter.cpp |  41 +-
 clang/lib/Serialization/ASTWriterDecl.cpp | 396 +++---
 clang/test/Modules/decl-params-determinisim.m |  16 +-
 6 files changed, 330 insertions(+), 356 deletions(-)

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 7f076cc77ea82cb..cd9a830dbaaf426 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -4073,7 +4073,7 @@ class RecordDecl : public TagDecl {
   /// returned from function calls. This takes into account the target-specific
   /// and version-specific rules along with the rules determined by the
   /// language.
-  enum ArgPassingKind : unsigned {
+  enum ArgPassingKind : unsigned char {
 /// The argument of this type can be passed directly in registers.
 APK_CanPassInRegs,
 
diff --git a/clang/include/clang/AST/DeclBase.h 
b/clang/include/clang/AST/DeclBase.h
index d383e46e22e16f4..7a30529f1f73d74 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -211,7 +211,7 @@ class alignas(8) Decl {
   /// The kind of ownership a declaration has, for visibility purposes.
   /// This enumeration is designed such that higher values represent higher
   /// levels of name hiding.
-  enum class ModuleOwnershipKind : unsigned {
+  enum class ModuleOwnershipKind : unsigned char {
 /// This declaration is not owned by a module.
 Unowned,
 
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp 
b/clang/lib/Serialization/ASTReaderDecl.cpp
index 3a3477c39efae25..2a6f142ec0e87c8 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -617,24 +617,27 @@ void ASTDeclReader::VisitDecl(Decl *D) {
Reader.getContext());
   }
   D->setLocation(ThisDeclLoc);
-  D->InvalidDecl = Record.readInt();
-  if (Record.readInt()) { // hasAttrs
+
+  uint64_t DeclBits = Record.readInt();
+  D->InvalidDecl = DeclBits & 0x1;
+  D->setImplicit(DeclBits & (1 << 2));
+  D->Used = (DeclBits >> 3) & 0x1;
+  IsDeclMarkedUsed |= D->Used;
+  D->setReferenced(DeclBits & (1 << 4));
+  D->setTopLevelDeclInObjCContainer(DeclBits & (1 << 5));
+  D->setAccess((AccessSpecifier)((DeclBits >> 6) & 0x3));
+  D->FromASTFile = true;
+  auto ModuleOwnership = (Decl::ModuleOwnershipKind)((DeclBits >> 8) & 0x7);
+  bool ModulePrivate =
+  (ModuleOwnership == Decl::ModuleOwnershipKind::ModulePrivate);
+
+  if (DeclBits & (0x1 << 1)) { // hasAttrs
 AttrVec Attrs;
 Record.readAttributes(Attrs);
 // Avoid calling setAttrs() directly because it uses Decl::getASTContext()
 // internally which is unsafe during derialization.
 D->setAttrsImpl(Attrs, Reader.getContext());
   }
-  D->setImplicit(Record.readInt());
-  D->Used = Record.readInt();
-  IsDeclMarkedUsed |= D->Used;
-  D->setReferenced(Record.readInt());
-  D->setTopLevelDeclInObjCContainer(Record.readInt());
-  D->setAccess((AccessSpecifier)Record.readInt());
-  D->FromASTFile = true;
-  auto ModuleOwnership = (Decl::ModuleOwnershipKind)Record.readInt();
-  bool ModulePrivate =
-  (ModuleOwnership == Decl::ModuleOwnershipKind::ModulePrivate);
 
   // Determine whether this declaration is part of a (sub)module. If so, it
   // may not yet be visible.
@@ -750,12 +753,14 @@ ASTDeclReader::RedeclarableResult 
ASTDeclReader::VisitTagDecl(TagDecl *TD) {
   VisitTypeDecl(TD);
 
   TD->IdentifierNamespace = Record.readInt();
-  TD->setTagKind((TagDecl::TagKind)Record.readInt());
+
+  uint32_t TagDeclBits = Record.readInt();
+  TD->setTagKind((TagDecl::TagKind)(TagDeclBits & 0x7));
   if (!isa(TD))
-TD->setCompleteDefinition(Record.readInt());
-  TD->setEmbeddedInDeclarator(Record.readInt());
-  TD->setFreeStanding(Record.readInt());
-  TD->setCompleteDefinitionRequired(Record.readInt());
+TD->setCompleteDefinition(TagDeclBits & (0x1 << 3)

[clang] [NFC] [Serializer] Pack information in serializer (PR #69287)

2023-10-26 Thread Chuanqi Xu via cfe-commits

https://github.com/ChuanqiXu9 updated 
https://github.com/llvm/llvm-project/pull/69287

>From e99fc1ab1e609d8e69c5d60b4c5df3f5563273e3 Mon Sep 17 00:00:00 2001
From: Chuanqi Xu 
Date: Mon, 16 Oct 2023 16:41:31 +0800
Subject: [PATCH] [Serializer] Pack bits into integers

Previously, the boolean values will occupy spaces that can contain
integers. It wastes the spaces especially if the boolean values are
serialized consecutively. The patch tries to pack such consecutive
boolean values (and enum values) so that we can save more spaces and so
the times.

Before the patch, we need 4.478s (in my machine) to build the std module
(https://libcxx.llvm.org/Modules.html) with 28712 bytes. After the
patch, the time becomes to 4.374s and the size becomes to 27568 bytes.

This is intended to be a NFC patch.

This patch doesn't optimize all such cases. We can do it later after we
have consensus on this.
---
 clang/include/clang/AST/Decl.h|   2 +-
 clang/include/clang/AST/DeclBase.h|   2 +-
 clang/include/clang/Serialization/ASTReader.h |  50 +++
 clang/include/clang/Serialization/ASTWriter.h |  53 +++
 clang/lib/Serialization/ASTReaderDecl.cpp | 225 ++-
 clang/lib/Serialization/ASTWriter.cpp |  32 +-
 clang/lib/Serialization/ASTWriterDecl.cpp | 381 +++---
 clang/test/Modules/decl-params-determinisim.m |  16 +-
 8 files changed, 403 insertions(+), 358 deletions(-)

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 7f076cc77ea82cb..cd9a830dbaaf426 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -4073,7 +4073,7 @@ class RecordDecl : public TagDecl {
   /// returned from function calls. This takes into account the target-specific
   /// and version-specific rules along with the rules determined by the
   /// language.
-  enum ArgPassingKind : unsigned {
+  enum ArgPassingKind : unsigned char {
 /// The argument of this type can be passed directly in registers.
 APK_CanPassInRegs,
 
diff --git a/clang/include/clang/AST/DeclBase.h 
b/clang/include/clang/AST/DeclBase.h
index d383e46e22e16f4..7a30529f1f73d74 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -211,7 +211,7 @@ class alignas(8) Decl {
   /// The kind of ownership a declaration has, for visibility purposes.
   /// This enumeration is designed such that higher values represent higher
   /// levels of name hiding.
-  enum class ModuleOwnershipKind : unsigned {
+  enum class ModuleOwnershipKind : unsigned char {
 /// This declaration is not owned by a module.
 Unowned,
 
diff --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index 531ad94f0906ac0..1a5d308aba97ff0 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -2407,6 +2407,56 @@ class ASTReader
   bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
 };
 
+/// A simple helper class to unpack an integer to bits and consuming
+/// the bits in order.
+class BitsUnpacker {
+  constexpr static uint32_t BitsIndexUpbound = 32;
+public:
+  BitsUnpacker(uint32_t V) {
+updateValue(V);
+  }
+  BitsUnpacker(const BitsUnpacker &) = delete;
+  BitsUnpacker(BitsUnpacker &&) = delete;
+  BitsUnpacker operator=(const BitsUnpacker &) = delete;
+  BitsUnpacker operator=(BitsUnpacker &&) = delete;
+  ~BitsUnpacker() {
+#ifndef NDEBUG
+while(isValid())
+  assert(!getNextBit() && "There are bits failed to read!");
+#endif
+  }
+
+  void updateValue(uint32_t V) {
+Value = V;
+CurrentBitsIndex = 0;
+  }
+
+  bool getNextBit() {
+assert(isValid());
+return Value & (1 << CurrentBitsIndex++);
+  }
+
+  uint32_t getNextBits(uint32_t Width) {
+assert(isValid());
+assert(Width < BitsIndexUpbound);
+uint32_t Ret = (Value >> CurrentBitsIndex) & ((1 << Width) - 1);
+CurrentBitsIndex += Width;
+return Ret;
+  }
+
+  bool isValidToGetNextNBits(uint32_t Width) const {
+return CurrentBitsIndex + Width < BitsIndexUpbound;
+  }
+
+private:
+  bool isValid() const {
+return CurrentBitsIndex < BitsIndexUpbound; 
+  }
+
+  uint32_t Value;
+  uint32_t CurrentBitsIndex = ~0;
+};
+
 } // namespace clang
 
 #endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H
diff --git a/clang/include/clang/Serialization/ASTWriter.h 
b/clang/include/clang/Serialization/ASTWriter.h
index 98445d40ebd82c3..bf1af1db579caea 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -830,6 +830,59 @@ class PCHGenerator : public SemaConsumer {
   bool hasEmittedPCH() const { return Buffer->IsComplete; }
 };
 
+/// A simple helper class to pack several bits in order into (a) 32 bit 
integer(s).
+class BitsPacker {
+  constexpr static uint32_t BitIndexUpbound = 32u;
+public:
+  BitsPacker() = default;
+  BitsPacker(const BitsPacker &) = delete;
+  BitsPacker(BitsPa

[clang] [NFC] [Serializer] Pack information in serializer (PR #69287)

2023-10-26 Thread Chuanqi Xu via cfe-commits


@@ -617,24 +617,27 @@ void ASTDeclReader::VisitDecl(Decl *D) {
Reader.getContext());
   }
   D->setLocation(ThisDeclLoc);
-  D->InvalidDecl = Record.readInt();
-  if (Record.readInt()) { // hasAttrs
+
+  uint64_t DeclBits = Record.readInt();
+  D->InvalidDecl = DeclBits & 0x1;
+  D->setImplicit(DeclBits & (1 << 2));
+  D->Used = (DeclBits >> 3) & 0x1;
+  IsDeclMarkedUsed |= D->Used;
+  D->setReferenced(DeclBits & (1 << 4));
+  D->setTopLevelDeclInObjCContainer(DeclBits & (1 << 5));
+  D->setAccess((AccessSpecifier)((DeclBits >> 6) & 0x3));
+  D->FromASTFile = true;
+  auto ModuleOwnership = (Decl::ModuleOwnershipKind)((DeclBits >> 8) & 0x7);

ChuanqiXu9 wrote:

Done 

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


[clang-tools-extra] [AMDGPU] Rematerialize scalar loads (PR #68778)

2023-10-26 Thread Piotr Sobczak via cfe-commits

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


[clang] [RISCV] Add processor definition for XiangShan-NanHu (PR #70294)

2023-10-26 Thread Wang Pengcheng via cfe-commits

https://github.com/wangpc-pp approved this pull request.

LGTM

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


[clang] [RISCV] Add processor definition for XiangShan-NanHu (PR #70294)

2023-10-26 Thread Wang Pengcheng via cfe-commits


@@ -20,6 +20,17 @@
 // MCPU-SYNTACORE-SCR1-MAX: "-target-feature" "+zicsr" "-target-feature" 
"+zifencei"
 // MCPU-SYNTACORE-SCR1-MAX: "-target-abi" "ilp32"
 
+// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=xiangshan-nanhu | 
FileCheck -check-prefix=MCPU-XIANGSHAN-NANHU %s

wangpc-pp wrote:

I prefer to one CHECK line for one feature, but it's OK since other processors 
aren't in this form. 

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


[clang] [RISCV] Add processor definition for XiangShan-NanHu (PR #70294)

2023-10-26 Thread Wang Pengcheng via cfe-commits

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


[clang] [RISCV] Add processor definition for XiangShan-NanHu (PR #70294)

2023-10-26 Thread Wang Pengcheng via cfe-commits

wangpc-pp wrote:

> > LGTM in general, except one question: will zicbom and zicboz be in the 
> > final RTL?
> 
> You can find the full implementation of `zicbom` and `zicboz` here: 
> [OpenXiangShan/XiangShan@ca18a0b](https://github.com/OpenXiangShan/XiangShan/commit/ca18a0b47b0e4089fd0dd1c085091cb90bf98f25).
>  cc @poemonsense

Please update the official document then. :-)

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


[clang] 1217a54 - [clang][Interp][NFC] Make InlineDescriptor::Desc const

2023-10-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-10-26T11:38:32+02:00
New Revision: 1217a54be9a194137c776c692a2fad2ba80a8ee8

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

LOG: [clang][Interp][NFC] Make InlineDescriptor::Desc const

Added: 


Modified: 
clang/lib/AST/Interp/Descriptor.cpp
clang/lib/AST/Interp/Descriptor.h
clang/lib/AST/Interp/Pointer.cpp
clang/lib/AST/Interp/Pointer.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Descriptor.cpp 
b/clang/lib/AST/Interp/Descriptor.cpp
index abd75a8d67bbd3f..2a21f60588d46cd 100644
--- a/clang/lib/AST/Interp/Descriptor.cpp
+++ b/clang/lib/AST/Interp/Descriptor.cpp
@@ -262,7 +262,7 @@ Descriptor::Descriptor(const DeclTy &D, PrimType Type, bool 
IsTemporary,
 }
 
 /// Arrays of composite elements.
-Descriptor::Descriptor(const DeclTy &D, Descriptor *Elem, MetadataSize MD,
+Descriptor::Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize 
MD,
unsigned NumElems, bool IsConst, bool IsTemporary,
bool IsMutable)
 : Source(D), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),

diff  --git a/clang/lib/AST/Interp/Descriptor.h 
b/clang/lib/AST/Interp/Descriptor.h
index be9a380138a7b11..2fd4e9208264525 100644
--- a/clang/lib/AST/Interp/Descriptor.h
+++ b/clang/lib/AST/Interp/Descriptor.h
@@ -72,7 +72,7 @@ struct InlineDescriptor {
   /// Flag indicating if the field is mutable (if in a record).
   unsigned IsFieldMutable : 1;
 
-  Descriptor *Desc;
+  const Descriptor *Desc;
 };
 
 /// Describes a memory block created by an allocation site.
@@ -102,7 +102,7 @@ struct Descriptor final {
   /// Pointer to the record, if block contains records.
   Record *const ElemRecord = nullptr;
   /// Descriptor of the array element.
-  Descriptor *const ElemDesc = nullptr;
+  const Descriptor *const ElemDesc = nullptr;
   /// Flag indicating if the block is mutable.
   const bool IsConst = false;
   /// Flag indicating if a field is mutable.
@@ -129,7 +129,7 @@ struct Descriptor final {
   Descriptor(const DeclTy &D, PrimType Type, bool IsTemporary, UnknownSize);
 
   /// Allocates a descriptor for an array of composites.
-  Descriptor(const DeclTy &D, Descriptor *Elem, MetadataSize MD,
+  Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize MD,
  unsigned NumElems, bool IsConst, bool IsTemporary, bool 
IsMutable);
 
   /// Allocates a descriptor for an array of composites of unknown size.

diff  --git a/clang/lib/AST/Interp/Pointer.cpp 
b/clang/lib/AST/Interp/Pointer.cpp
index d1af58203bec64d..e979b99b0fdd0a0 100644
--- a/clang/lib/AST/Interp/Pointer.cpp
+++ b/clang/lib/AST/Interp/Pointer.cpp
@@ -94,7 +94,7 @@ APValue Pointer::toAPValue() const {
 Offset = CharUnits::Zero();
   } else {
 // Build the lvalue base from the block.
-Descriptor *Desc = getDeclDesc();
+const Descriptor *Desc = getDeclDesc();
 if (auto *VD = Desc->asValueDecl())
   Base = VD;
 else if (auto *E = Desc->asExpr())

diff  --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h
index 3b21290332a9d2f..65d710077fd1cbb 100644
--- a/clang/lib/AST/Interp/Pointer.h
+++ b/clang/lib/AST/Interp/Pointer.h
@@ -184,7 +184,8 @@ class Pointer {
 
 // Step into the containing array, if inside one.
 unsigned Next = Base - getInlineDesc()->Offset;
-Descriptor *Desc = Next == 0 ? getDeclDesc() : getDescriptor(Next)->Desc;
+const Descriptor *Desc =
+Next == 0 ? getDeclDesc() : getDescriptor(Next)->Desc;
 if (!Desc->IsArray)
   return *this;
 return Pointer(Pointee, Next, Offset);
@@ -198,7 +199,7 @@ class Pointer {
   bool isField() const { return Base != 0 && Base != RootPtrMark; }
 
   /// Accessor for information about the declaration site.
-  Descriptor *getDeclDesc() const { return Pointee->Desc; }
+  const Descriptor *getDeclDesc() const { return Pointee->Desc; }
   SourceLocation getDeclLoc() const { return getDeclDesc()->getLocation(); }
 
   /// Returns a pointer to the object of which this pointer is a field.
@@ -222,7 +223,7 @@ class Pointer {
   }
 
   /// Accessors for information about the innermost field.
-  Descriptor *getFieldDesc() const {
+  const Descriptor *getFieldDesc() const {
 if (Base == 0 || Base == RootPtrMark)
   return getDeclDesc();
 return getInlineDesc()->Desc;



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


[clang] [OpenMP] Pass min/max thread and team count to the OMPIRBuilder (PR #70247)

2023-10-26 Thread Matt Arsenault via cfe-commits


@@ -9,6 +9,7 @@
 #include "ABIInfoImpl.h"
 #include "TargetInfo.h"
 #include "llvm/IR/IntrinsicsNVPTX.h"
+#include 

arsenm wrote:

probably not, and if it is I believe there's an llvm wrapper header you're 
supposed to use instead 

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


[clang] [OpenMP] Pass min/max thread and team count to the OMPIRBuilder (PR #70247)

2023-10-26 Thread Matt Arsenault via cfe-commits


@@ -607,8 +608,13 @@ void CodeGenModule::handleAMDGPUFlatWorkGroupSizeAttr(
   if (Min != 0) {
 assert(Min <= Max && "Min must be less than or equal Max");
 
+if (MinThreadsVal)
+  *MinThreadsVal = Min;
+if (MaxThreadsVal)
+  *MaxThreadsVal = Max;
 std::string AttrVal = llvm::utostr(Min) + "," + llvm::utostr(Max);
-F->addFnAttr("amdgpu-flat-work-group-size", AttrVal);
+if (F)

arsenm wrote:

When would this ever be null?

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


[clang] f8b7506 - [clang][NFC] Move a variable into the closest scope

2023-10-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-10-26T11:40:43+02:00
New Revision: f8b7506e2db2a162deec8343d6942258484be233

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

LOG: [clang][NFC] Move a variable into the closest scope

AllocType is not used anywhere else.

Added: 


Modified: 
clang/lib/AST/ExprConstant.cpp

Removed: 




diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index eea0827d6f7a8a1..320e2ef12c38db3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6867,8 +6867,8 @@ static std::optional CheckDeleteKind(EvalInfo 
&Info, const Expr *E,
 return std::nullopt;
   }
 
-  QualType AllocType = Pointer.Base.getDynamicAllocType();
   if (DeallocKind != (*Alloc)->getKind()) {
+QualType AllocType = Pointer.Base.getDynamicAllocType();
 Info.FFDiag(E, diag::note_constexpr_new_delete_mismatch)
 << DeallocKind << (*Alloc)->getKind() << AllocType;
 NoteLValueLocation(Info, Pointer.Base);



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


[clang] [clang][Analyzer] Move checker 'alpha.unix.Errno' to 'unix.Errno'. (PR #69469)

2023-10-26 Thread via cfe-commits

DonatNagyE wrote:

This [report from 
vim](https://codechecker-demo.eastus.cloudapp.azure.com/Default/report-detail?run=vim_v8.2.1920_errno_alpha_unix&newcheck=vim_v8.2.1920_errno_unix&is-unique=on&diff-type=New&report-id=3214372&report-hash=9582050be3f26e8ebf9dcf4c5b0f82b3&report-filepath=%2amemline.c)
 seems to be a false positive:

![image](https://github.com/llvm/llvm-project/assets/43410265/14bfd4b2-686b-452c-b417-465cdb43f11b)

Readlink returns either -1 (failure, errno is set) or the number of characters 
read from the symlink entry (i.e. the filename the symlink points to). I don't 
think that it's possible to create a "symlink to emptystring", so the the 
checkers should recognize that if the return value is `<= 0`, then it's a 
failure.


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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/70306

>From 8ec689511d266576bd792ee8731baff9ec0e7143 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH] [clang][Interp] Implement dynamic memory allocation handling

---
 clang/lib/AST/CMakeLists.txt  |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp  |  76 +++
 clang/lib/AST/Interp/ByteCodeExprGen.h|   2 +
 clang/lib/AST/Interp/Context.cpp  |   2 +-
 clang/lib/AST/Interp/DynamicAllocator.cpp |  91 
 clang/lib/AST/Interp/DynamicAllocator.h   |  90 
 clang/lib/AST/Interp/EvalEmitter.cpp  |   4 +-
 clang/lib/AST/Interp/Interp.cpp   |  37 
 clang/lib/AST/Interp/Interp.h |  94 
 clang/lib/AST/Interp/InterpBlock.h|  10 +-
 clang/lib/AST/Interp/InterpState.cpp  |  15 ++
 clang/lib/AST/Interp/InterpState.h|  10 +
 clang/lib/AST/Interp/Opcodes.td   |  24 +++
 clang/test/AST/Interp/new-delete.cpp  | 247 ++
 14 files changed, 695 insertions(+), 8 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index fe3f8c485ec1c56..1423623fb038cab 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -75,6 +75,7 @@ add_clang_library(clangAST
   Interp/Function.cpp
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 1b33c69b93aa4b9..c42fcabe3b075ba 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1617,6 +1617,82 @@ bool 
ByteCodeExprGen::VisitCXXScalarValueInitExpr(
   return this->visitZeroInitializer(classifyPrim(Ty), Ty, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+assert(E->getArraySize());
+PrimType SizeT = classifyPrim((*E->getArraySize())->getType());
+
+if (!this->visit(*E->getArraySize()))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, E))
+return false;
+}
+
+  } else {
+// Allocate just one element.
+if (!this->emitAlloc(Desc, E))
+  return false;
+
+if (Init) {
+  if (ElemT) {
+if (!this->visit(Init))
+  return false;
+
+if (!this->emitInit(*ElemT, E))
+  return false;
+  } else {
+// Composite.
+if (!this->visitInitializer(Init))
+  return false;
+  }
+}
+  }
+
+  if (DiscardResult)
+return this->emitPopPtr(E);
+
+  return true;
+}
+
+template 
+bool ByteCodeExprGen::VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
+  const Expr *Arg = E->getArgument();
+
+  // Arg must be an lvalue.
+  if (!this->visit(Arg))
+return false;
+
+  return this->emitFree(E->isArrayForm(), E);
+}
+
 template  bool ByteCodeExprGen::discard(const Expr *E) 
{
   if (E->containsErrors())
 return false;
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 83986d3dd579ed6..f65dc9494db36ef 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -107,6 +107,8 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitSourceLocExpr(const SourceLocExpr *E);
   bool VisitOffsetOfExpr(const OffsetOfExpr *E);
   bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
+  bool VisitCXXNewExpr(const CXXNewExpr *E);
+  bool VisitCXXDeleteExpr(const CXXDeleteExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;
diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index cb96e56fb5e1ad8..ede14de30419d0b 100644
--- a/clang/

[clang] [NFC] [Serializer] Pack information in serializer (PR #69287)

2023-10-26 Thread Chuanqi Xu via cfe-commits

https://github.com/ChuanqiXu9 updated 
https://github.com/llvm/llvm-project/pull/69287

>From ae4ee482f5b6b5d2487ed642b92e513ffd269781 Mon Sep 17 00:00:00 2001
From: Chuanqi Xu 
Date: Mon, 16 Oct 2023 16:41:31 +0800
Subject: [PATCH] [Serializer] Pack bits into integers

Previously, the boolean values will occupy spaces that can contain
integers. It wastes the spaces especially if the boolean values are
serialized consecutively. The patch tries to pack such consecutive
boolean values (and enum values) so that we can save more spaces and so
the times.

Before the patch, we need 4.478s (in my machine) to build the std module
(https://libcxx.llvm.org/Modules.html) with 28712 bytes. After the
patch, the time becomes to 4.374s and the size becomes to 27568 bytes.

This is intended to be a NFC patch.

This patch doesn't optimize all such cases. We can do it later after we
have consensus on this.

fmt
---
 clang/include/clang/AST/Decl.h|   2 +-
 clang/include/clang/AST/DeclBase.h|   2 +-
 clang/include/clang/Serialization/ASTReader.h |  47 +++
 clang/include/clang/Serialization/ASTWriter.h |  53 +++
 clang/lib/Serialization/ASTReaderDecl.cpp | 230 ++-
 clang/lib/Serialization/ASTWriter.cpp |  32 +-
 clang/lib/Serialization/ASTWriterDecl.cpp | 381 +++---
 clang/test/Modules/decl-params-determinisim.m |  16 +-
 8 files changed, 405 insertions(+), 358 deletions(-)

diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 7f076cc77ea82cb..cd9a830dbaaf426 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -4073,7 +4073,7 @@ class RecordDecl : public TagDecl {
   /// returned from function calls. This takes into account the target-specific
   /// and version-specific rules along with the rules determined by the
   /// language.
-  enum ArgPassingKind : unsigned {
+  enum ArgPassingKind : unsigned char {
 /// The argument of this type can be passed directly in registers.
 APK_CanPassInRegs,
 
diff --git a/clang/include/clang/AST/DeclBase.h 
b/clang/include/clang/AST/DeclBase.h
index d383e46e22e16f4..7a30529f1f73d74 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -211,7 +211,7 @@ class alignas(8) Decl {
   /// The kind of ownership a declaration has, for visibility purposes.
   /// This enumeration is designed such that higher values represent higher
   /// levels of name hiding.
-  enum class ModuleOwnershipKind : unsigned {
+  enum class ModuleOwnershipKind : unsigned char {
 /// This declaration is not owned by a module.
 Unowned,
 
diff --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index 531ad94f0906ac0..f54ebe2913786c9 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -2407,6 +2407,53 @@ class ASTReader
   bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
 };
 
+/// A simple helper class to unpack an integer to bits and consuming
+/// the bits in order.
+class BitsUnpacker {
+  constexpr static uint32_t BitsIndexUpbound = 32;
+
+public:
+  BitsUnpacker(uint32_t V) { updateValue(V); }
+  BitsUnpacker(const BitsUnpacker &) = delete;
+  BitsUnpacker(BitsUnpacker &&) = delete;
+  BitsUnpacker operator=(const BitsUnpacker &) = delete;
+  BitsUnpacker operator=(BitsUnpacker &&) = delete;
+  ~BitsUnpacker() {
+#ifndef NDEBUG
+while (isValid())
+  assert(!getNextBit() && "There are bits failed to read!");
+#endif
+  }
+
+  void updateValue(uint32_t V) {
+Value = V;
+CurrentBitsIndex = 0;
+  }
+
+  bool getNextBit() {
+assert(isValid());
+return Value & (1 << CurrentBitsIndex++);
+  }
+
+  uint32_t getNextBits(uint32_t Width) {
+assert(isValid());
+assert(Width < BitsIndexUpbound);
+uint32_t Ret = (Value >> CurrentBitsIndex) & ((1 << Width) - 1);
+CurrentBitsIndex += Width;
+return Ret;
+  }
+
+  bool isValidToGetNextNBits(uint32_t Width) const {
+return CurrentBitsIndex + Width < BitsIndexUpbound;
+  }
+
+private:
+  bool isValid() const { return CurrentBitsIndex < BitsIndexUpbound; }
+
+  uint32_t Value;
+  uint32_t CurrentBitsIndex = ~0;
+};
+
 } // namespace clang
 
 #endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H
diff --git a/clang/include/clang/Serialization/ASTWriter.h 
b/clang/include/clang/Serialization/ASTWriter.h
index 98445d40ebd82c3..96e218149dd4d17 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -830,6 +830,59 @@ class PCHGenerator : public SemaConsumer {
   bool hasEmittedPCH() const { return Buffer->IsComplete; }
 };
 
+/// A simple helper class to pack several bits in order into (a) 32 bit
+/// integer(s).
+class BitsPacker {
+  constexpr static uint32_t BitIndexUpbound = 32u;
+
+public:
+  BitsPacker() = default;
+  BitsPacker(const BitsPacker &) = delete;
+  BitsPacker(BitsPacke

[clang] [Clang] Diagnose defaulted assignment operator with incompatible object parameter (PR #70176)

2023-10-26 Thread Timm Baeder via cfe-commits


@@ -7748,6 +7748,24 @@ bool 
Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
 HadError = true;
   }
 }
+// [C++23][dcl.fct.def.default]/p2.2
+// if F2 has an implicit object parameter of type “reference to C”,
+// F1 may be an explicit object member function whose explicit object
+// parameter is of (possibly different) type “reference to C”,
+// in which case the type of F1 would differ from the type of F2
+// in that the type of F1 has an additional parameter;
+if (!Context.hasSameType(
+ThisType.getNonReferenceType().getUnqualifiedType(),
+Context.getRecordType(RD))) {
+  if (DeleteOnTypeMismatch)
+ShouldDeleteForTypeMismatch = true;
+  else {
+Diag(MD->getLocation(),
+ diag::err_defaulted_special_member_explicit_object_mismatch)
+<< (CSM == CXXMoveAssignment) << RD;

tbaederr wrote:

Nothing specific. In line 7709 above, we pass `MD->getSourceRange()`.

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


[clang] 737d2ac - [clang][Interp][NFC] Make Block::Desc const

2023-10-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-10-26T11:47:46+02:00
New Revision: 737d2acd6863ca7012a75575c1a52fd807ed44ba

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

LOG: [clang][Interp][NFC] Make Block::Desc const

Added: 


Modified: 
clang/lib/AST/Interp/InterpBlock.h

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpBlock.h 
b/clang/lib/AST/Interp/InterpBlock.h
index 89f937b588fb678..4ab67ebb9eaafcc 100644
--- a/clang/lib/AST/Interp/InterpBlock.h
+++ b/clang/lib/AST/Interp/InterpBlock.h
@@ -53,7 +53,7 @@ class Block final {
 bool IsStatic = false, bool IsExtern = false)
   : DeclID(DeclID), IsStatic(IsStatic), IsExtern(IsExtern), Desc(Desc) {}
 
-  Block(Descriptor *Desc, bool IsStatic = false, bool IsExtern = false)
+  Block(const Descriptor *Desc, bool IsStatic = false, bool IsExtern = false)
   : DeclID((unsigned)-1), IsStatic(IsStatic), IsExtern(IsExtern),
 Desc(Desc) {}
 
@@ -120,8 +120,8 @@ class Block final {
   friend class DeadBlock;
   friend class InterpState;
 
-  Block(Descriptor *Desc, bool IsExtern, bool IsStatic, bool IsDead)
-: IsStatic(IsStatic), IsExtern(IsExtern), IsDead(true), Desc(Desc) {}
+  Block(const Descriptor *Desc, bool IsExtern, bool IsStatic, bool IsDead)
+  : IsStatic(IsStatic), IsExtern(IsExtern), IsDead(true), Desc(Desc) {}
 
   /// Deletes a dead block at the end of its lifetime.
   void cleanup();
@@ -149,7 +149,7 @@ class Block final {
   /// via invokeCtor.
   bool IsInitialized = false;
   /// Pointer to the stack slot descriptor.
-  Descriptor *Desc;
+  const Descriptor *Desc;
 };
 
 /// Descriptor for a dead block.



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


[clang] [NFC][Clang] Fix potential deref of end iterator (PR #70193)

2023-10-26 Thread Nathan Gauër via cfe-commits

Keenuts wrote:

CI seems OK, except clang format which complains about an unrelated line. 
Marking as ready.

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


[clang] [NFC][Clang] Fix potential deref of end iterator (PR #70193)

2023-10-26 Thread Nathan Gauër via cfe-commits

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


[clang] [AArch64] Stack probing for function prologues (PR #66524)

2023-10-26 Thread Momchil Velikov via cfe-commits

momchil-velikov wrote:

> Apologies for still not being able to create a reproducible example I can 
> share but what I am seeing is the stack probe write overwriting the value at 
> the tip of the stack when I step debug execution:

Can you spot a place where the probe instruction is *not* immediately after a 
decrement of the stack (disregarding some random register-to-register 
arithmetic that may appear)?

If you can't (and you should not find such a case), perhaps some instruction 
writes below the `sp`? That would be against the AArch64.

Is redzone enabled (`--aarch64-redzone=true|false`) "? If it is on, can you 
check if it makes a difference if you disable it? 

> > All the stack probing should have already finished before the call to 
> > `malloc`.

> Only for the containing function, the functions which have their stack probes 
> inlined will be in the middle of the function which then results in this 
> null-deref.

The stack probes (except `alloca` ones)  are emitted by the 
PrologEpilogInsertion pass, which is very late in the pipeline.
I didn't think inlining could happen after that pass. Can you share yous 
compilation pipeline (`-- debug-pass=Structure`)?


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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread Timm Baeder via cfe-commits


@@ -0,0 +1,91 @@
+//== DynamicAllocator.cpp - Types for the constexpr VM ---*- 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 "DynamicAllocator.h"
+#include "InterpBlock.h"
+#include "InterpState.h"
+
+using namespace clang;
+using namespace clang::interp;
+
+Block *DynamicAllocator::allocate(const Expr *Source, PrimType T,
+  size_t NumElements) {
+  assert(NumElements > 0);
+  // Create a new descriptor for an array of the specified size and
+  // element type.
+  const Descriptor *D = allocateDescriptor(
+  Source, T, Descriptor::InlineDescMD, NumElements, /*IsConst=*/false,
+  /*IsTemporary=*/false, /*IsMutable=*/false);
+  return allocate(D);
+}
+
+Block *DynamicAllocator::allocate(const Descriptor *ElementDesc,
+  size_t NumElements) {
+  assert(NumElements > 0);
+  // Create a new descriptor for an array of the specified size and
+  // element type.
+  const Descriptor *D = allocateDescriptor(
+  ElementDesc->asExpr(), ElementDesc, Descriptor::InlineDescMD, 
NumElements,
+  /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false);
+  return allocate(D);
+}
+
+Block *DynamicAllocator::allocate(const Descriptor *D) {
+  assert(D->asExpr());
+
+  auto Memory =
+  std::make_unique(sizeof(Block) + D->getAllocSize());
+  auto *B = new (Memory.get()) Block(D, /*isStatic=*/false);
+  B->invokeCtor();
+
+  InlineDescriptor *ID = reinterpret_cast(B->rawData());
+  ID->Desc = const_cast(D);
+  ID->IsActive = true;
+  ID->Offset = sizeof(InlineDescriptor);
+  ID->IsBase = false;
+  ID->IsFieldMutable = false;
+  ID->IsConst = false;
+  ID->IsInitialized = false;
+  assert(ID->Desc);
+
+  if (auto It = AllocationSites.find(D->asExpr()); It != AllocationSites.end())
+It->second.Allocations.emplace_back(std::move(Memory));
+  else
+AllocationSites.insert(
+{D->asExpr(), AllocationSite(std::move(Memory), D->isArray())});
+  return B;
+}
+
+void DynamicAllocator::deallocate(const Expr *Source,
+  const Block *BlockToDelete, InterpState &S) {
+  assert(AllocationSites.contains(Source));
+
+  auto It = AllocationSites.find(Source);
+  assert(It != AllocationSites.end());
+
+  auto &Site = It->second;
+  assert(Site.size() > 0);
+
+  // Find the Block to delete.
+  size_t I = 0;
+  [[maybe_unused]] bool Found = false;
+  for (auto &A : Site.Allocations) {
+Block *B = reinterpret_cast(A.Memory.get());
+if (B == BlockToDelete) {
+  S.deallocate(B);
+  B->invokeDtor();

tbaederr wrote:

It doesn't matter but yes, that does indeed look better.

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


[clang] [NFC][Clang] Fix potential deref of end iterator (PR #70193)

2023-10-26 Thread Nathan Gauër via cfe-commits

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


[clang] [NFC][Clang] Fix potential deref of end iterator (PR #70193)

2023-10-26 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Nathan Gauër (Keenuts)


Changes

This was found by doing bound-checking on SmallVector iterator usage. When the 
count is 0, the end iterator is dereferenced to get its address. This doesn't 
seem to be an issue in practice as most of the time we should be allowed to 
deref this address, but I don't think this is correct.

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


1 Files Affected:

- (modified) clang/include/clang/Sema/CXXFieldCollector.h (+1-1) 


``diff
diff --git a/clang/include/clang/Sema/CXXFieldCollector.h 
b/clang/include/clang/Sema/CXXFieldCollector.h
index f6ecd9f46e5ebdb..ce066581c93fda7 100644
--- a/clang/include/clang/Sema/CXXFieldCollector.h
+++ b/clang/include/clang/Sema/CXXFieldCollector.h
@@ -65,7 +65,7 @@ class CXXFieldCollector {
 
   /// getCurFields - Pointer to array of fields added to the currently parsed
   /// class.
-  FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
+  FieldDecl **getCurFields() { return Fields.end() - getCurNumFields(); }
 
   /// FinishClass - Called by Sema::ActOnFinishCXXClassDef.
   void FinishClass() {

``




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


[clang] [clang][Sema] Resolving Inconsistent Arguments Panic in Variadic Template Variables (PR #70280)

2023-10-26 Thread via cfe-commits

knightXun wrote:

i will add test case for it

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


[clang-tools-extra] [Clang][Sema] Skip RecordDecl when checking scope of declarations (PR #69432)

2023-10-26 Thread Qiu Chaofan via cfe-commits

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

>From f97807afc177ab04c97d0c346081fc92d3e79e6c Mon Sep 17 00:00:00 2001
From: Qiu Chaofan 
Date: Wed, 18 Oct 2023 16:02:02 +0800
Subject: [PATCH 1/3] [Clang][Sema] Skip RecordDecl when checking scope of
 declarations

---
 clang/lib/Sema/IdentifierResolver.cpp | 4 +++-
 clang/test/Sema/nested-redef.c| 6 +-
 clang/test/SemaObjC/ivar-lookup.m | 4 ++--
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/IdentifierResolver.cpp 
b/clang/lib/Sema/IdentifierResolver.cpp
index 98a6f3b45089b3a..2213c3c837243ad 100644
--- a/clang/lib/Sema/IdentifierResolver.cpp
+++ b/clang/lib/Sema/IdentifierResolver.cpp
@@ -109,7 +109,9 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext 
*Ctx, Scope *S,
 return false;
   if (Ctx->isFunctionOrMethod() || (S && S->isFunctionPrototypeScope())) {
 // Ignore the scopes associated within transparent declaration contexts.
-while (S->getEntity() && S->getEntity()->isTransparentContext())
+while (S->getEntity() &&
+   (S->getEntity()->isTransparentContext() ||
+(!LangOpt.CPlusPlus && isa(S->getEntity()
   S = S->getParent();
 
 if (S->isDeclScope(D))
diff --git a/clang/test/Sema/nested-redef.c b/clang/test/Sema/nested-redef.c
index bbc485936770478..c5a726c30422f98 100644
--- a/clang/test/Sema/nested-redef.c
+++ b/clang/test/Sema/nested-redef.c
@@ -19,4 +19,8 @@ void f2(void) {
   struct U u;
 }
 
-
+void f3(void) {
+  struct G { // expected-note{{previous definition is here}}
+struct G {}; // expected-error{{nested redefinition of 'G'}}
+  };
+}
diff --git a/clang/test/SemaObjC/ivar-lookup.m 
b/clang/test/SemaObjC/ivar-lookup.m
index 898ffac99692ced..d88299e58e0f594 100644
--- a/clang/test/SemaObjC/ivar-lookup.m
+++ b/clang/test/SemaObjC/ivar-lookup.m
@@ -95,11 +95,11 @@ - (int) test
   union U {
 __typeof(myStatus) __in;  // fails.
   };
-  struct S {
+  struct S { // expected-note{{previous definition is here}}
 __typeof(myStatus) __in;  // fails.
 struct S1 { // expected-warning {{declaration does not declare anything}}
   __typeof(myStatus) __in;  // fails.
-  struct S { // expected-warning {{declaration does not declare anything}}
+  struct S { // expected-error {{nested redefinition of 'S'}}
 __typeof(myStatus) __in;  // fails.
   };
 };

>From 48c50ddc4380a6e28c81b5270d602c30d71843e0 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan 
Date: Thu, 26 Oct 2023 16:47:33 +0800
Subject: [PATCH 2/3] Add original case

---
 clang/test/Sema/nested-redef.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/clang/test/Sema/nested-redef.c b/clang/test/Sema/nested-redef.c
index c5a726c30422f98..adc57ff4e04ab29 100644
--- a/clang/test/Sema/nested-redef.c
+++ b/clang/test/Sema/nested-redef.c
@@ -24,3 +24,11 @@ void f3(void) {
 struct G {}; // expected-error{{nested redefinition of 'G'}}
   };
 }
+
+void f4(void) {
+  struct G { // expected-note 2{{previous definition is here}}
+struct G {}; // expected-error{{nested redefinition of 'G'}}
+  };
+
+  struct G {}; // expected-error{{redefinition of 'G'}}
+}

>From 4d3e00b36608ddeb80e3c92186f504e299baf7a8 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan 
Date: Thu, 26 Oct 2023 18:00:00 +0800
Subject: [PATCH 3/3] Add releasenotes

---
 clang/docs/ReleaseNotes.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 074116d2edf9f99..3e94544166552d1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -667,6 +667,8 @@ Miscellaneous Clang Crashes Fixed
   `Issue 64564 `_
 - Fixed a crash when an ObjC ivar has an invalid type. See
   (`#68001 `_)
+- Fixed a crash in C when redefined struct is another nested redefinition.
+  `Issue 41302 `_
 
 Target Specific Changes
 ---

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


[clang] 85f6b2f - [OpenMP] Patch for Support to loop bind clause : Checking Parent Region

2023-10-26 Thread Sandeep Kosuri via cfe-commits

Author: Sunil Kuravinakop
Date: 2023-10-26T05:08:41-05:00
New Revision: 85f6b2fac9a367337e43ca288c45ea783981cc16

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

LOG: [OpenMP] Patch for Support to loop bind clause : Checking Parent Region

Differential revision: https://reviews.llvm.org/D158266

Added: 


Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaOpenMP.cpp
clang/test/OpenMP/loop_bind_messages.cpp
clang/test/PCH/pragma-loop.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1e9752345ffd173..18ac85011aa752a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11307,6 +11307,7 @@ class Sema final {
   /// on the parameter of the bind clause. In the methods for the
   /// mapped directives, check the parameters of the lastprivate clause.
   bool checkLastPrivateForMappedDirectives(ArrayRef Clauses);
+
   /// Depending on the bind clause of OMPD_loop map the directive to new
   /// directives.
   ///1) loop bind(parallel) --> OMPD_for
@@ -11316,9 +11317,12 @@ class Sema final {
   /// rigorous semantic checking in the new mapped directives.
   bool mapLoopConstruct(llvm::SmallVector &ClausesWithoutBind,
 ArrayRef Clauses,
-OpenMPBindClauseKind BindKind,
+OpenMPBindClauseKind &BindKind,
 OpenMPDirectiveKind &Kind,
-OpenMPDirectiveKind &PrevMappedDirective);
+OpenMPDirectiveKind &PrevMappedDirective,
+SourceLocation StartLoc, SourceLocation EndLoc,
+const DeclarationNameInfo &DirName,
+OpenMPDirectiveKind CancelRegion);
 
 public:
   /// The declarator \p D defines a function in the scope \p S which is nested

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 75f9e152dca9297..f28e0f2693080c1 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5062,6 +5062,18 @@ static bool checkNestingOfRegions(Sema &SemaRef, const 
DSAStackTy *Stack,
 CurrentRegion != OMPD_cancellation_point &&
 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
   return false;
+// Checks needed for mapping "loop" construct. Please check 
mapLoopConstruct
+// for a detailed explanation
+if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
+((BindKind == OMPC_BIND_parallel) || (BindKind == OMPC_BIND_teams)) &&
+(isOpenMPWorksharingDirective(ParentRegion) ||
+ ParentRegion == OMPD_loop)) {
+  int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
+  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
+  << true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
+  << getOpenMPDirectiveName(CurrentRegion);
+  return true;
+}
 if (CurrentRegion == OMPD_cancellation_point ||
 CurrentRegion == OMPD_cancel) {
   // OpenMP [2.16, Nesting of Regions]
@@ -6114,35 +6126,40 @@ processImplicitMapsWithDefaultMappers(Sema &S, 
DSAStackTy *Stack,
 
 bool Sema::mapLoopConstruct(llvm::SmallVector &ClausesWithoutBind,
 ArrayRef Clauses,
-OpenMPBindClauseKind BindKind,
+OpenMPBindClauseKind &BindKind,
 OpenMPDirectiveKind &Kind,
-OpenMPDirectiveKind &PrevMappedDirective) {
+OpenMPDirectiveKind &PrevMappedDirective,
+SourceLocation StartLoc, SourceLocation EndLoc,
+const DeclarationNameInfo &DirName,
+OpenMPDirectiveKind CancelRegion) {
 
   bool UseClausesWithoutBind = false;
 
   // Restricting to "#pragma omp loop bind"
   if (getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) {
+
+const OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
+
 if (BindKind == OMPC_BIND_unknown) {
   // Setting the enclosing teams or parallel construct for the loop
   // directive without bind clause.
   BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is 
unknown
 
-  const OpenMPDirectiveKind ParentDirective =
-  DSAStack->getParentDirective();
   if (ParentDirective == OMPD_unknown) {
 Diag(DSAStack->getDefaultDSALocation(),
  diag::err_omp_bind_required_on_loop);
-  } else if (ParentDirective == OMPD_parallel ||
- ParentDirective == OMPD_target_parallel) {
+  } else if (isOpenMPParallelDirective(ParentDirective) &&
+ !isOpenMPTeamsDirect

[PATCH] D158266: [OpenMP] Patch for Support to loop bind clause : Checking Parent Region

2023-10-26 Thread Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG85f6b2fac9a3: [OpenMP] Patch for Support to loop bind clause 
: Checking Parent Region (authored by koops, committed by Sandeep Kosuri 
).

Changed prior to commit:
  https://reviews.llvm.org/D158266?vs=557877&id=557890#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158266/new/

https://reviews.llvm.org/D158266

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOpenMP.cpp
  clang/test/OpenMP/loop_bind_messages.cpp
  clang/test/PCH/pragma-loop.cpp

Index: clang/test/PCH/pragma-loop.cpp
===
--- clang/test/PCH/pragma-loop.cpp
+++ clang/test/PCH/pragma-loop.cpp
@@ -116,9 +116,13 @@
 
   inline void run10(int *List, int Length) {
 int i = 0;
-#pragma omp loop bind(teams)
+int j = 0;
+#pragma omp teams
 for (int i = 0; i < Length; i++) {
-  List[i] = i;
+  #pragma omp loop bind(teams)
+  for (int j = 0; j < Length; j++) {
+List[i] = i+j;
+  }
 }
   }
 
Index: clang/test/OpenMP/loop_bind_messages.cpp
===
--- clang/test/OpenMP/loop_bind_messages.cpp
+++ clang/test/OpenMP/loop_bind_messages.cpp
@@ -4,6 +4,7 @@
 
 #define NNN 50
 int aaa[NNN];
+int aaa2[NNN][NNN];
 
 void parallel_loop() {
   #pragma omp parallel
@@ -15,6 +16,91 @@
}
 }
 
+void parallel_for_AND_loop_bind() {
+  #pragma omp parallel for
+  for (int i = 0 ; i < NNN ; i++) {
+#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
+for (int j = 0 ; j < NNN ; j++) {
+  aaa2[i][j] = i+j;
+}
+  }
+}
+
+void parallel_nowait() {
+  #pragma omp parallel
+  #pragma omp for nowait
+  for (int i = 0 ; i < NNN ; i++) {
+#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
+for (int j = 0 ; j < NNN ; j++) {
+  aaa2[i][j] = i+j;
+}
+  }
+}
+
+void parallel_for_with_nothing() {
+  #pragma omp parallel for
+  for (int i = 0 ; i < NNN ; i++) {
+#pragma omp nothing
+#pragma omp loop // expected-error{{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
+for (int j = 0 ; j < NNN ; j++) {
+  aaa2[i][j] = i+j;
+}
+  }
+}
+
+void parallel_targetfor_with_loop_bind() {
+  #pragma omp target teams distribute parallel for 
+  for (int i = 0 ; i < NNN ; i++) {
+#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'target teams distribute parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
+for (int j = 0 ; j < NNN ; j++) {
+  aaa2[i][j] = i+j;
+}
+  }
+}
+
+void parallel_targetparallel_with_loop() {
+  #pragma omp target parallel
+  for (int i = 0 ; i < NNN ; i++) {
+#pragma omp loop bind(parallel)
+for (int j = 0 ; j < NNN ; j++) {
+  aaa2[i][j] = i+j;
+}
+  }
+}
+
+void loop_bind_AND_loop_bind() {
+  #pragma omp parallel for
+  for (int i = 0; i < 100; ++i) {
+#pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}} 
+for (int i = 0 ; i < NNN ; i++) {
+  #pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'loop' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}} 
+  for (int j = 0 ; j < NNN ; j++) {
+aaa[j] = j*NNN;
+  }
+}
+  }
+}
+
+void parallel_with_sections_loop() {
+  #pragma omp parallel
+  {
+ #pragma omp sections
+ {
+for (int i = 0 ; i < NNN ; i++) {
+  #pragma omp loop bind(parallel) // expected-error{{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp loop' directive into a parallel region?}}
+  for (int j = 0 ; j < NNN ; j++) {
+aaa2[i][j] = i+j;
+  }
+}
+
+#pragma omp section
+	{
+  aaa[NNN-1] = NNN;
+}
+ }
+  }
+}
+
 void teams_loop() {
   int var1, var2;
 
@@ -34,17 +120,23 @@
}
 }
 
-void orphan_loop_with_bind() {
-  #pragma omp loop bind(parallel) 
-  for (int j = 0 ; j < NNN ; j++) {
-aaa[j] = j*NNN;
+void teams_targetteams_with_loop() {
+  #pragma omp target teams
+  for (int i = 0 ; i < NNN ; i++) {
+#pragma omp loop bind(teams)
+for (int j = 0 ; j < NNN ; j++) {
+  aaa2[i][j] = i+j;
+}
   }
 }
 
-void orphan_loop_no_bind() {
-  #pragma omp loop  // expected-error{{expected 'bind' clause for 'loop' construct 

[clang-tools-extra] [MLIR] Add SyclRuntimeWrapper (PR #69648)

2023-10-26 Thread Guray Ozen via cfe-commits


@@ -0,0 +1,222 @@
+//===- SyclRuntimeWrappers.cpp - MLIR SYCL wrapper library ===//
+//
+// 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
+//
+//===--===//
+//
+// Implements C wrappers around the sycl runtime library.
+//
+//===--===//
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef _WIN32
+#define SYCL_RUNTIME_EXPORT __declspec(dllexport)
+#else
+#define SYCL_RUNTIME_EXPORT
+#endif // _WIN32
+
+namespace {
+
+template 
+auto catchAll(F &&func) {
+  try {
+return func();
+  } catch (const std::exception &e) {
+fprintf(stdout, "An exception was thrown: %s\n", e.what());
+fflush(stdout);
+abort();
+  } catch (...) {
+fprintf(stdout, "An unknown exception was thrown\n");
+fflush(stdout);
+abort();
+  }
+}
+
+#define L0_SAFE_CALL(call) 
\
+  {
\
+ze_result_t status = (call);   
\
+if (status != ZE_RESULT_SUCCESS) { 
\
+  fprintf(stdout, "L0 error %d\n", status);
\
+  fflush(stdout);  
\
+  abort(); 
\
+}  
\
+  }
+
+} // namespace
+
+static sycl::device getDefaultDevice() {
+  static sycl::device syclDevice;
+  static bool isDeviceInitialised = false; 
+  if(!isDeviceInitialised) {
+  auto platformList = sycl::platform::get_platforms();
+  for (const auto &platform : platformList) {
+auto platformName = platform.get_info();
+bool isLevelZero = platformName.find("Level-Zero") != std::string::npos;
+if (!isLevelZero)
+  continue;
+
+syclDevice = platform.get_devices()[0];
+isDeviceInitialised = true;
+return syclDevice;
+  }
+throw std::runtime_error("getDefaultDevice failed");

grypp wrote:

Thanks a lot for the explanation! In this case, using `throw std::runtime ` 
makes perfect sense to me. It aligns the behavior of this small runtime with 
SYCL. 

I was wondering if you truly needed exceptions here, and it turns out that yes, 
you do want them. 

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


[clang-tools-extra] [MLIR] Add SyclRuntimeWrapper (PR #69648)

2023-10-26 Thread Guray Ozen via cfe-commits

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

This looks good to me! I'm not a SYCL expert, but maybe someone with more 
expertise could take a quick look here. @Hardcode84 ?

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


[clang-tools-extra] [clang-tidy]Fix PreferMemberInitializer false positive for reassignment (PR #70316)

2023-10-26 Thread Congcong Cai via cfe-commits

https://github.com/HerrCai0907 created 
https://github.com/llvm/llvm-project/pull/70316

- assignment twice cannot be simplified to once when assigning to reference type
- safe assignment cannot be advanced before unsafe assignment

>From 41278ca046ae5d4be4ac4ac1bc673b5010668d9c Mon Sep 17 00:00:00 2001
From: Congcong Cai 
Date: Thu, 26 Oct 2023 18:54:05 +0800
Subject: [PATCH] [clang-tidy]Fix PreferMemberInitializer false positive for
 reassignment

- assignment twice cannot be simplified to once when assigning to reference type
- Original design doesn't consider safe assignment cannot be advanced before 
unsafe assignment
---
 .../PreferMemberInitializerCheck.cpp  | 46 +++
 clang-tools-extra/docs/ReleaseNotes.rst   |  3 +-
 .../prefer-member-initializer.cpp | 16 +++
 3 files changed, 54 insertions(+), 11 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp
 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp
index 0ef13ae29803325..ae91ae22612c40b 100644
--- 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp
+++ 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp
@@ -8,8 +8,10 @@
 
 #include "PreferMemberInitializerCheck.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
+#include 
 
 using namespace clang::ast_matchers;
 
@@ -54,9 +56,13 @@ static bool shouldBeDefaultMemberInitializer(const Expr 
*Value) {
 }
 
 namespace {
+
 AST_MATCHER_P(FieldDecl, indexNotLessThan, unsigned, Index) {
   return Node.getFieldIndex() >= Index;
 }
+
+enum class AssignedLevel { None, Assigned, UnsafetyAssigned };
+
 } // namespace
 
 // Checks if Field is initialised using a field that will be initialised after
@@ -64,13 +70,19 @@ AST_MATCHER_P(FieldDecl, indexNotLessThan, unsigned, Index) 
{
 // TODO: Probably should guard against function calls that could have side
 // effects or if they do reference another field that's initialized before this
 // field, but is modified before the assignment.
-static bool isSafeAssignment(const FieldDecl *Field, const Expr *Init,
- const CXXConstructorDecl *Context) {
+static AssignedLevel isSafeAssignment(const FieldDecl *Field, const Expr *Init,
+  const CXXConstructorDecl *Context,
+  AssignedLevel HistoryLevel) {
+  if (HistoryLevel == AssignedLevel::UnsafetyAssigned)
+return AssignedLevel::UnsafetyAssigned;
+  if (Field->getType()->isReferenceType() &&
+  HistoryLevel == AssignedLevel::Assigned)
+// assign to reference type twice cannot be simplified to once.
+return AssignedLevel::UnsafetyAssigned;
 
   auto MemberMatcher =
   memberExpr(hasObjectExpression(cxxThisExpr()),
  member(fieldDecl(indexNotLessThan(Field->getFieldIndex();
-
   auto DeclMatcher = declRefExpr(
   to(varDecl(unless(parmVarDecl()), hasDeclContext(equalsNode(Context);
 
@@ -78,7 +90,9 @@ static bool isSafeAssignment(const FieldDecl *Field, const 
Expr *Init,
   hasDescendant(MemberMatcher),
   hasDescendant(DeclMatcher))),
*Init, Field->getASTContext())
-  .empty();
+ .empty()
+ ? AssignedLevel::Assigned
+ : AssignedLevel::UnsafetyAssigned;
 }
 
 static std::pair
@@ -99,9 +113,9 @@ isAssignmentToMemberOf(const CXXRecordDecl *Rec, const Stmt 
*S,
 if (!isa(ME->getBase()))
   return std::make_pair(nullptr, nullptr);
 const Expr *Init = BO->getRHS()->IgnoreParenImpCasts();
-if (isSafeAssignment(Field, Init, Ctor))
-  return std::make_pair(Field, Init);
-  } else if (const auto *COCE = dyn_cast(S)) {
+return std::make_pair(Field, Init);
+  }
+  if (const auto *COCE = dyn_cast(S)) {
 if (COCE->getOperator() != OO_Equal)
   return std::make_pair(nullptr, nullptr);
 
@@ -117,10 +131,8 @@ isAssignmentToMemberOf(const CXXRecordDecl *Rec, const 
Stmt *S,
 if (!isa(ME->getBase()))
   return std::make_pair(nullptr, nullptr);
 const Expr *Init = COCE->getArg(1)->IgnoreParenImpCasts();
-if (isSafeAssignment(Field, Init, Ctor))
-  return std::make_pair(Field, Init);
+return std::make_pair(Field, Init);
   }
-
   return std::make_pair(nullptr, nullptr);
 }
 
@@ -156,6 +168,12 @@ void PreferMemberInitializerCheck::check(
   const CXXRecordDecl *Class = Ctor->getParent();
   bool FirstToCtorInits = true;
 
+  std::map AssignedFields{};
+
+  for (const CXXCtorInitializer *Init : Ctor->inits())
+if (FieldDecl *Field = Init->getMember())
+  AssignedFields.insert({Field, AssignedLevel::Assigned});
+
   for (const Stmt *S : Body->body()) {
 if (S->getBeginLoc().isMacroID()) {
   StringRef MacroName = Lexer::getImmediateMacroName

[clang-tools-extra] [clang-tidy]Fix PreferMemberInitializer false positive for reassignment (PR #70316)

2023-10-26 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-tidy

Author: Congcong Cai (HerrCai0907)


Changes

- assignment twice cannot be simplified to once when assigning to reference type
- safe assignment cannot be advanced before unsafe assignment

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


3 Files Affected:

- (modified) 
clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp 
(+36-10) 
- (modified) clang-tools-extra/docs/ReleaseNotes.rst (+2-1) 
- (modified) 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/prefer-member-initializer.cpp
 (+16) 


``diff
diff --git 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp
 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp
index 0ef13ae29803325..ae91ae22612c40b 100644
--- 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp
+++ 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp
@@ -8,8 +8,10 @@
 
 #include "PreferMemberInitializerCheck.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
+#include 
 
 using namespace clang::ast_matchers;
 
@@ -54,9 +56,13 @@ static bool shouldBeDefaultMemberInitializer(const Expr 
*Value) {
 }
 
 namespace {
+
 AST_MATCHER_P(FieldDecl, indexNotLessThan, unsigned, Index) {
   return Node.getFieldIndex() >= Index;
 }
+
+enum class AssignedLevel { None, Assigned, UnsafetyAssigned };
+
 } // namespace
 
 // Checks if Field is initialised using a field that will be initialised after
@@ -64,13 +70,19 @@ AST_MATCHER_P(FieldDecl, indexNotLessThan, unsigned, Index) 
{
 // TODO: Probably should guard against function calls that could have side
 // effects or if they do reference another field that's initialized before this
 // field, but is modified before the assignment.
-static bool isSafeAssignment(const FieldDecl *Field, const Expr *Init,
- const CXXConstructorDecl *Context) {
+static AssignedLevel isSafeAssignment(const FieldDecl *Field, const Expr *Init,
+  const CXXConstructorDecl *Context,
+  AssignedLevel HistoryLevel) {
+  if (HistoryLevel == AssignedLevel::UnsafetyAssigned)
+return AssignedLevel::UnsafetyAssigned;
+  if (Field->getType()->isReferenceType() &&
+  HistoryLevel == AssignedLevel::Assigned)
+// assign to reference type twice cannot be simplified to once.
+return AssignedLevel::UnsafetyAssigned;
 
   auto MemberMatcher =
   memberExpr(hasObjectExpression(cxxThisExpr()),
  member(fieldDecl(indexNotLessThan(Field->getFieldIndex();
-
   auto DeclMatcher = declRefExpr(
   to(varDecl(unless(parmVarDecl()), hasDeclContext(equalsNode(Context);
 
@@ -78,7 +90,9 @@ static bool isSafeAssignment(const FieldDecl *Field, const 
Expr *Init,
   hasDescendant(MemberMatcher),
   hasDescendant(DeclMatcher))),
*Init, Field->getASTContext())
-  .empty();
+ .empty()
+ ? AssignedLevel::Assigned
+ : AssignedLevel::UnsafetyAssigned;
 }
 
 static std::pair
@@ -99,9 +113,9 @@ isAssignmentToMemberOf(const CXXRecordDecl *Rec, const Stmt 
*S,
 if (!isa(ME->getBase()))
   return std::make_pair(nullptr, nullptr);
 const Expr *Init = BO->getRHS()->IgnoreParenImpCasts();
-if (isSafeAssignment(Field, Init, Ctor))
-  return std::make_pair(Field, Init);
-  } else if (const auto *COCE = dyn_cast(S)) {
+return std::make_pair(Field, Init);
+  }
+  if (const auto *COCE = dyn_cast(S)) {
 if (COCE->getOperator() != OO_Equal)
   return std::make_pair(nullptr, nullptr);
 
@@ -117,10 +131,8 @@ isAssignmentToMemberOf(const CXXRecordDecl *Rec, const 
Stmt *S,
 if (!isa(ME->getBase()))
   return std::make_pair(nullptr, nullptr);
 const Expr *Init = COCE->getArg(1)->IgnoreParenImpCasts();
-if (isSafeAssignment(Field, Init, Ctor))
-  return std::make_pair(Field, Init);
+return std::make_pair(Field, Init);
   }
-
   return std::make_pair(nullptr, nullptr);
 }
 
@@ -156,6 +168,12 @@ void PreferMemberInitializerCheck::check(
   const CXXRecordDecl *Class = Ctor->getParent();
   bool FirstToCtorInits = true;
 
+  std::map AssignedFields{};
+
+  for (const CXXCtorInitializer *Init : Ctor->inits())
+if (FieldDecl *Field = Init->getMember())
+  AssignedFields.insert({Field, AssignedLevel::Assigned});
+
   for (const Stmt *S : Body->body()) {
 if (S->getBeginLoc().isMacroID()) {
   StringRef MacroName = Lexer::getImmediateMacroName(
@@ -180,6 +198,14 @@ void PreferMemberInitializerCheck::check(
 std::tie(Field, InitValue) = isAssignmentToMemberOf(Class, S, Ctor);
 if (!Field)
   continue;
+const auto It = AssignedFields.find(Field);
+AssignedLevel Level =

[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/70306

>From abc2a0b7c5beefc28e6d88f9718c5aefe1fbf044 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement dynamic memory allocation
 handling

---
 clang/lib/AST/CMakeLists.txt  |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp  |  76 +++
 clang/lib/AST/Interp/ByteCodeExprGen.h|   2 +
 clang/lib/AST/Interp/Context.cpp  |   2 +-
 clang/lib/AST/Interp/DynamicAllocator.cpp |  91 
 clang/lib/AST/Interp/DynamicAllocator.h   |  90 
 clang/lib/AST/Interp/EvalEmitter.cpp  |   4 +-
 clang/lib/AST/Interp/Interp.cpp   |  37 
 clang/lib/AST/Interp/Interp.h |  94 
 clang/lib/AST/Interp/InterpBlock.h|   2 +-
 clang/lib/AST/Interp/InterpState.cpp  |  15 ++
 clang/lib/AST/Interp/InterpState.h|  10 +
 clang/lib/AST/Interp/Opcodes.td   |  24 +++
 clang/test/AST/Interp/new-delete.cpp  | 247 ++
 14 files changed, 691 insertions(+), 4 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index fe3f8c485ec1c56..1423623fb038cab 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -75,6 +75,7 @@ add_clang_library(clangAST
   Interp/Function.cpp
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 1b33c69b93aa4b9..c42fcabe3b075ba 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1617,6 +1617,82 @@ bool 
ByteCodeExprGen::VisitCXXScalarValueInitExpr(
   return this->visitZeroInitializer(classifyPrim(Ty), Ty, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+assert(E->getArraySize());
+PrimType SizeT = classifyPrim((*E->getArraySize())->getType());
+
+if (!this->visit(*E->getArraySize()))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, E))
+return false;
+}
+
+  } else {
+// Allocate just one element.
+if (!this->emitAlloc(Desc, E))
+  return false;
+
+if (Init) {
+  if (ElemT) {
+if (!this->visit(Init))
+  return false;
+
+if (!this->emitInit(*ElemT, E))
+  return false;
+  } else {
+// Composite.
+if (!this->visitInitializer(Init))
+  return false;
+  }
+}
+  }
+
+  if (DiscardResult)
+return this->emitPopPtr(E);
+
+  return true;
+}
+
+template 
+bool ByteCodeExprGen::VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
+  const Expr *Arg = E->getArgument();
+
+  // Arg must be an lvalue.
+  if (!this->visit(Arg))
+return false;
+
+  return this->emitFree(E->isArrayForm(), E);
+}
+
 template  bool ByteCodeExprGen::discard(const Expr *E) 
{
   if (E->containsErrors())
 return false;
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 83986d3dd579ed6..f65dc9494db36ef 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -107,6 +107,8 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitSourceLocExpr(const SourceLocExpr *E);
   bool VisitOffsetOfExpr(const OffsetOfExpr *E);
   bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
+  bool VisitCXXNewExpr(const CXXNewExpr *E);
+  bool VisitCXXDeleteExpr(const CXXDeleteExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;
diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
in

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

2023-10-26 Thread Sam McCall via cfe-commits

https://github.com/sam-mccall edited 
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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -104,6 +107,8 @@ struct PreambleData {
   IncludeStructure Includes;
   // Captures #include-mapping information in #included headers.
   std::shared_ptr Pragmas;
+  // Information about module files for this preamble.
+  std::optional DependentModulesInfo;

sam-mccall wrote:

hmm, I think the adjective "dependent" in "dependent modules" would refer to 
modules that depend on this, not modules that this depends on.

Maybe `UsedModules`, `RequiredModules` or just `Modules`?

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -104,6 +107,8 @@ struct PreambleData {
   IncludeStructure Includes;
   // Captures #include-mapping information in #included headers.
   std::shared_ptr Pragmas;
+  // Information about module files for this preamble.
+  std::optional DependentModulesInfo;

sam-mccall wrote:

nit: drop `Info` here too

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,78 @@
+//=== 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"
+
+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 P1689Result =

sam-mccall wrote:

nit: again, drop P1689 from the var name?
We can't do anything about the function being misnamed, but...

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,78 @@
+//=== 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"
+
+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));

sam-mccall wrote:

is ScanningTool designed for one instance to be reused across invocations of 
`getP1689ModuleDependencyFile`, and share caches?
Should we try to do that here, since almost all the time we're calling scan() 
in a sequential loop?

I get that ultimately we want to have a shared cache across all module scanning 
happening in the project and this may conflict a little, this just seems like 
really low-hanging fruit.

Up to you though.

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,55 @@
+//===-- ProjectModules.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_PROJECTMODULES_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PROJECTMODULES_H
+
+#include "ModuleDependencyScanner.h"
+
+namespace clang {
+namespace clangd {
+
+/// An interface to query the modules information in the project.
+/// This should be obtained by
+/// `GlobalCompilationDatabase::getProjectModules(PathRef)`.
+///
+/// TODO: The existing `ScanningAllProjectModules` is not efficient. See the
+/// comments in ModuleDependencyScanner for detail.
+class ProjectModules {
+public:
+  virtual std::vector getRequiredModules(PathRef File) = 0;
+  virtual PathRef getSourceForModuleName(StringRef ModuleName) = 0;
+};
+
+class ScanningAllProjectModules : public ProjectModules {

sam-mccall wrote:

nit: this class only implements an interface, we could just expose a factory 
function from the header instead

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,78 @@
+//=== 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"
+
+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 P1689Result =
+  ScanningTool.getP1689ModuleDependencyFile(*Cmd, Cmd->Directory);
+
+  if (auto E = P1689Result.takeError()) {
+// Ignore any error.

sam-mccall wrote:

at least while experimental we may want to `vlog()` these instead

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,90 @@
+//===-- ModuleDependencyScanner.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_MODULEDEPENDENCYSCANNER_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULEDEPENDENCYSCANNER_H
+
+#include "GlobalCompilationDatabase.h"
+#include "support/Path.h"
+#include "support/ThreadsafeFS.h"
+
+#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
+#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace clang {
+namespace clangd {
+
+/// A scanner to query the dependency information for C++20 Modules.
+///
+/// The scanner can scan a single file with `scan(PathRef)` member function
+/// or scan the whole project with `globalScan(PathRef)` member function. See
+/// the comments of `globalScan` to see the details.
+class ModuleDependencyScanner {
+public:
+  ModuleDependencyScanner(const GlobalCompilationDatabase &CDB,
+  const ThreadsafeFS &TFS)
+  : CDB(CDB), TFS(TFS),
+Service(tooling::dependencies::ScanningMode::CanonicalPreprocessing,
+tooling::dependencies::ScanningOutputFormat::P1689) {}
+
+  // The scanned modules dependency information for a specific source file.
+  struct ModuleDependencyInfo {
+// The name of the module if the file is a module unit.
+std::optional ModuleName;
+// A list of names for the modules that the file directly depends.
+std::vector RequiredModules;
+  };
+
+  /// Scanning the single file specified by \param FilePath.
+  /// NOTE: This is only used by unittests for external uses.
+  std::optional scan(PathRef FilePath);
+
+  /// Scanning every source file in the current project to get the
+  ///  to  map.
+  /// It looks unefficiency to scan the whole project especially for
+  /// every version of every file!
+  /// TODO: We should find an efficient method to get the 
+  /// to  map. We can make it either by providing
+  /// a global module dependency scanner to monitor every file. Or we
+  /// can simply require the build systems (or even if the end users)
+  /// to provide the map.
+  void globalScan(const std::vector &AllFiles);
+  bool isGlobalScanned() const { return GlobalScanned; }
+
+  /// Get the source file from the module name. Note that the language
+  /// guarantees all the module names are unique in a valid program.
+  /// This function should only be called after globalScan.
+  /// FIXME: Maybe we should handle the corner cases.

sam-mccall wrote:

this FIXME isn't descriptive enough to be useful

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,278 @@
+//===- PrerequisiteModules.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 "PrerequisiteModules.h"
+#include "ProjectModules.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 {
+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;
+}
+} // namespace
+
+PrerequisiteModules::PrerequisiteModules(PathRef MainFile,
+ const GlobalCompilationDatabase &CDB) 
{
+  std::optional PI = CDB.getProjectInfo(MainFile);
+  if (!PI)
+return;
+
+  llvm::SmallString<128> Result(PI->SourceRoot);

sam-mccall wrote:

PI->SourceRoot can be empty, depending on the CDB strategy. For now it's OK to 
bail out in this case, but we need a FIXME

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)

2023-10-26 Thread Sam McCall via cfe-commits

https://github.com/sam-mccall commented:

Thanks, this looks really close to me!
Tried to focus on how the components fit together, the details of module 
building and reuse can easily be tweaked later if needed.

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,141 @@
+//===- 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
+//
+//===--===//
+//
+// 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.
+//
+// FIXME: Supporting reusing module files across different versions and
+// different source files.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREREQUISITEMODULES_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREREQUISITEMODULES_H
+
+#include "Compiler.h"
+#include "GlobalCompilationDatabase.h"
+#include "ModuleDependencyScanner.h"
+#include "support/Path.h"
+
+#include "clang/Lex/HeaderSearchOptions.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace clang {
+namespace clangd {
+
+/// Build and 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 build and store
+/// the module files for `a.cppm` and `b.cppm`. But the module file for 
`c.cppm`
+/// won't be built. Since it is not needed to parse `c.cppm`.
+///
+/// All the built module files won't be shared with other instances of the
+/// class. So that we can avoid worrying thread safety.
+///
+/// A PrerequisiteModules instace should only be initialized by
+/// `PrerequisiteModules::buildPrerequisiteModulesFor(...)`.
+///
+/// Users can detect whether the PrerequisiteModules is still up to date by
+/// calling the `CanReuse()` member function.
+///
+/// The users should call `adjustHeaderSearchOptions(...)` or
+/// `adjustCompileCommands(CompileCommand&)` member function to update the
+/// compilation commands to select the built module files first.
+struct PrerequisiteModules {

sam-mccall wrote:

this class has a bunch of responsibilities and state transitions. e.g. it has 
an "invalid" state. modules can be built, not built yet, not buildable, etc.

I think it can be simpler if decomposed into:
 - `struct ModuleFile`, which has a module name, a filename, and deletes the 
file in its destructor
 - `class PrerequisiteModules` which owns a set of `ModuleFiles` for a 
particular TU, and knows how to adjust the compile commands etc to use them
 - a function to build `PrerequisiteModules` for a TU. This is currently 
`static PrerequisiteModules::buildPrerequisiteModulesFor` which is OK, but it 
can really just create a bunch of `ModuleFile`s and pass it to the 
PrerequisiteModules constructor. 

(As I mention elsewhere: I think buildPrerquisiteModulesFor should really be a 
method on a different `ModuleBuilder` object, as it will eventually need to 
deal with caching and other things)

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,78 @@
+//=== 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"
+
+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 P1689Result =
+  ScanningTool.getP1689ModuleDependencyFile(*Cmd, Cmd->Directory);
+
+  if (auto E = P1689Result.takeError()) {
+// Ignore any error.
+llvm::consumeError(std::move(E));
+return std::nullopt;
+  }
+
+  ModuleDependencyInfo Result;
+
+  if (P1689Result->Provides) {
+ModuleNameToSource[P1689Result->Provides->ModuleName] = FilePath;
+Result.ModuleName = P1689Result->Provides->ModuleName;
+  }
+
+  for (auto &Required : P1689Result->Requires)
+Result.RequiredModules.push_back(Required.ModuleName);
+
+  return Result;
+}
+
+void ModuleDependencyScanner::globalScan(
+const std::vector &AllFiles) {
+  for (auto &File : AllFiles)
+scan(File);
+
+  GlobalScanned = true;
+}
+
+PathRef ModuleDependencyScanner::getSourceForModuleName(StringRef ModuleName) 
const {
+  assert(
+  GlobalScanned &&
+  "We should only call getSourceForModuleName after calling globalScan()");
+
+  if (!ModuleNameToSource.count(ModuleName))

sam-mccall wrote:

nit: rather `if (auto It = find(); It != end())` to avoid the double-lookup?

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,78 @@
+//=== 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"
+
+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 P1689Result =
+  ScanningTool.getP1689ModuleDependencyFile(*Cmd, Cmd->Directory);
+
+  if (auto E = P1689Result.takeError()) {
+// Ignore any error.
+llvm::consumeError(std::move(E));
+return std::nullopt;
+  }
+
+  ModuleDependencyInfo Result;
+
+  if (P1689Result->Provides) {
+ModuleNameToSource[P1689Result->Provides->ModuleName] = FilePath;
+Result.ModuleName = P1689Result->Provides->ModuleName;
+  }
+
+  for (auto &Required : P1689Result->Requires)
+Result.RequiredModules.push_back(Required.ModuleName);
+
+  return Result;
+}
+
+void ModuleDependencyScanner::globalScan(
+const std::vector &AllFiles) {
+  for (auto &File : AllFiles)
+scan(File);
+
+  GlobalScanned = true;
+}
+
+PathRef ModuleDependencyScanner::getSourceForModuleName(StringRef ModuleName) 
const {
+  assert(

sam-mccall wrote:

the only caller of this does `if (!isGlobalScanned()) globalScan()`
might as well put that here instead of the assert, simplify the contract, 
simplify the callers, delete `isGlobalScanned()`, etc

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,278 @@
+//===- PrerequisiteModules.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 "PrerequisiteModules.h"
+#include "ProjectModules.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 {
+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;
+}
+} // namespace
+
+PrerequisiteModules::PrerequisiteModules(PathRef MainFile,
+ const GlobalCompilationDatabase &CDB) 
{
+  std::optional PI = CDB.getProjectInfo(MainFile);
+  if (!PI)
+return;
+
+  llvm::SmallString<128> Result(PI->SourceRoot);
+  llvm::sys::path::append(Result, ".cache");
+  llvm::sys::path::append(Result, "clangd");
+  llvm::sys::path::append(Result, "module_files");
+  llvm::sys::fs::create_directories(Result, /*IgnoreExisting=*/true);
+
+  llvm::sys::path::append(Result, llvm::sys::path::filename(MainFile));
+  llvm::sys::fs::createUniqueDirectory(Result, UniqueModuleFilesPathPrefix);
+
+  log("Initialized module files to {0}", UniqueModuleFilesPathPrefix.str());
+}
+
+PrerequisiteModules::~PrerequisiteModules() {
+  DependentModuleNames.clear();
+
+  if (UniqueModuleFilesPathPrefix.empty())
+return;
+
+  llvm::sys::fs::remove_directories(UniqueModuleFilesPathPrefix);
+  UniqueModuleFilesPathPrefix.clear();
+}
+
+llvm::SmallString<256>
+PrerequisiteModules::getModuleFilePath(StringRef ModuleName) const {
+  llvm::SmallString<256> ModuleFilePath;
+
+  ModuleFilePath = UniqueModuleFilesPathPrefix;
+  auto [PrimaryModuleName, PartitionName] = ModuleName.split(':');
+  llvm::sys::path::append(ModuleFilePath, PrimaryModuleName);
+  if (!PartitionName.empty()) {
+ModuleFilePath.append("-");
+ModuleFilePath.append(PartitionName);
+  }
+  ModuleFilePath.append(".pcm");
+
+  return ModuleFilePath;
+}
+
+bool PrerequisiteModules::isModuleUnitBuilt(StringRef ModuleName) const {
+  if (!DependentModuleNames.count(ModuleName))
+return false;
+
+  auto BMIPath = getModuleFilePath(ModuleName);
+  if (llvm::sys::fs::exists(BMIPath))
+return true;
+
+  DependentModuleNames.erase(ModuleName);
+  return false;
+}
+
+void PrerequisiteModules::adjustHeaderSearchOptions(
+HeaderSearchOptions &Options) const {
+  if (!IsInited())
+return;
+
+  Options.PrebuiltModulePaths.insert(Options.PrebuiltModulePaths.begin(),
+ UniqueModuleFilesPathPrefix.str().str());
+
+  for (auto Iter = Options.PrebuiltModuleFiles.begin();
+   Iter != Options.PrebuiltModuleFiles.end();) {
+if (isModuleUnitBuilt(Iter->first)) {
+  Iter = Options.PrebuiltModuleFiles.erase(Iter);
+  continue;
+}
+
+Iter++;
+  }
+}
+
+void PrerequisiteModules::adjustCompileCommands(
+tooling::CompileCommand &Cmd) const {
+  if (!IsInited())
+return;
+
+  std::vector CommandLine(std::move(Cmd.CommandLine));
+
+  Cmd.CommandLine.emplace_back(CommandLine[0]);
+  Cmd.CommandLine.emplace_back(

sam-mccall wrote:

why do we need this line? we should be passing all paths explicitly with 
-fmodule-file=, no?

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,141 @@
+//===- 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
+//
+//===--===//
+//
+// 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.
+//
+// FIXME: Supporting reusing module files across different versions and
+// different source files.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREREQUISITEMODULES_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREREQUISITEMODULES_H
+
+#include "Compiler.h"
+#include "GlobalCompilationDatabase.h"
+#include "ModuleDependencyScanner.h"
+#include "support/Path.h"
+
+#include "clang/Lex/HeaderSearchOptions.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace clang {
+namespace clangd {
+
+/// Build and 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 build and store
+/// the module files for `a.cppm` and `b.cppm`. But the module file for 
`c.cppm`
+/// won't be built. Since it is not needed to parse `c.cppm`.
+///
+/// All the built module files won't be shared with other instances of the
+/// class. So that we can avoid worrying thread safety.
+///
+/// A PrerequisiteModules instace should only be initialized by
+/// `PrerequisiteModules::buildPrerequisiteModulesFor(...)`.
+///
+/// Users can detect whether the PrerequisiteModules is still up to date by
+/// calling the `CanReuse()` member function.
+///
+/// The users should call `adjustHeaderSearchOptions(...)` or
+/// `adjustCompileCommands(CompileCommand&)` member function to update the
+/// compilation commands to select the built module files first.
+struct PrerequisiteModules {
+  ~PrerequisiteModules();
+
+  PrerequisiteModules(const PrerequisiteModules &) = delete;
+  PrerequisiteModules operator=(const PrerequisiteModules &) = delete;
+
+  PrerequisiteModules(PrerequisiteModules &&Other)

sam-mccall wrote:

shouldn't go to any trouble to make this movable.
if it's not movable "for free" then we can just store it by `unique_ptr`.

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,90 @@
+//===-- ModuleDependencyScanner.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_MODULEDEPENDENCYSCANNER_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_MODULEDEPENDENCYSCANNER_H
+
+#include "GlobalCompilationDatabase.h"
+#include "support/Path.h"
+#include "support/ThreadsafeFS.h"
+
+#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
+#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace clang {
+namespace clangd {
+
+/// A scanner to query the dependency information for C++20 Modules.
+///
+/// The scanner can scan a single file with `scan(PathRef)` member function
+/// or scan the whole project with `globalScan(PathRef)` member function. See
+/// the comments of `globalScan` to see the details.
+class ModuleDependencyScanner {
+public:
+  ModuleDependencyScanner(const GlobalCompilationDatabase &CDB,
+  const ThreadsafeFS &TFS)
+  : CDB(CDB), TFS(TFS),
+Service(tooling::dependencies::ScanningMode::CanonicalPreprocessing,
+tooling::dependencies::ScanningOutputFormat::P1689) {}
+
+  // The scanned modules dependency information for a specific source file.
+  struct ModuleDependencyInfo {
+// The name of the module if the file is a module unit.
+std::optional ModuleName;
+// A list of names for the modules that the file directly depends.
+std::vector RequiredModules;
+  };
+
+  /// Scanning the single file specified by \param FilePath.
+  /// NOTE: This is only used by unittests for external uses.
+  std::optional scan(PathRef FilePath);
+
+  /// Scanning every source file in the current project to get the
+  ///  to  map.
+  /// It looks unefficiency to scan the whole project especially for
+  /// every version of every file!
+  /// TODO: We should find an efficient method to get the 
+  /// to  map. We can make it either by providing
+  /// a global module dependency scanner to monitor every file. Or we
+  /// can simply require the build systems (or even if the end users)
+  /// to provide the map.
+  void globalScan(const std::vector &AllFiles);
+  bool isGlobalScanned() const { return GlobalScanned; }
+
+  /// Get the source file from the module name. Note that the language
+  /// guarantees all the module names are unique in a valid program.
+  /// This function should only be called after globalScan.
+  /// FIXME: Maybe we should handle the corner cases.
+  PathRef getSourceForModuleName(StringRef ModuleName) const;
+
+  /// Return the direct required modules. Indirect required modules are not
+  /// included.
+  std::vector getRequiredModules(PathRef File);
+
+private:
+  const GlobalCompilationDatabase &CDB;
+  const ThreadsafeFS &TFS;
+
+  // Whether the scanner has scanned the project globally.
+  bool GlobalScanned = false;
+
+  clang::tooling::dependencies::DependencyScanningService Service;
+
+  // TODO: Add a scanning cache.
+
+  // Map module name to source file path.

sam-mccall wrote:

somewhere (either here or on the public interface), please describe how this 
works for modules that are defined by multiple source files

(AIUI these "module names" may also include the partition, and the "source 
file" is only the module interface, not implementation units. This is fine and 
I think it's ok to say "module name" and "source file", just we should spell it 
out somewhere)

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)

2023-10-26 Thread Sam McCall via cfe-commits


@@ -0,0 +1,278 @@
+//===- PrerequisiteModules.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 "PrerequisiteModules.h"
+#include "ProjectModules.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 {
+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;
+}
+} // namespace
+
+PrerequisiteModules::PrerequisiteModules(PathRef MainFile,
+ const GlobalCompilationDatabase &CDB) 
{
+  std::optional PI = CDB.getProjectInfo(MainFile);
+  if (!PI)
+return;
+
+  llvm::SmallString<128> Result(PI->SourceRoot);
+  llvm::sys::path::append(Result, ".cache");
+  llvm::sys::path::append(Result, "clangd");
+  llvm::sys::path::append(Result, "module_files");

sam-mccall wrote:

nit: just `modules` I think

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] Recognize friend operator != to fix ambiguity with operator== (PR #70217)

2023-10-26 Thread Utkarsh Saxena via cfe-commits

https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/70217

>From 26b9570fadf428e2f55efe0f2d9433cf18305239 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 25 Oct 2023 16:55:15 +0200
Subject: [PATCH 1/4] friend operator!=

---
 clang/lib/Sema/SemaOverload.cpp   | 11 +
 .../over.match.oper/p3-2a.cpp | 23 +++
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index db386fef0661c05..ce7503162ef3ba3 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -960,15 +960,18 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation 
OpLoc,
   if (FunctionsCorrespond(S.Context, EqFD, Op->getAsFunction()))
 return false;
 return true;
-  }
+  } 
   // Otherwise the search scope is the namespace scope of which F is a member.
-  for (NamedDecl *Op : EqFD->getEnclosingNamespaceContext()->lookup(NotEqOp)) {
+  DeclContext *EqDC = EqFD->getEnclosingNamespaceContext();
+  for (NamedDecl *Op : EqDC->lookup(NotEqOp)) {
 auto *NotEqFD = Op->getAsFunction();
+DeclContext *NotEqDC = Op->getFriendObjectKind()
+   ? NotEqFD->getEnclosingNamespaceContext()
+   : Op->getLexicalDeclContext();
 if (auto *UD = dyn_cast(Op))
   NotEqFD = UD->getUnderlyingDecl()->getAsFunction();
 if (FunctionsCorrespond(S.Context, EqFD, NotEqFD) && S.isVisible(NotEqFD) 
&&
-declaresSameEntity(cast(EqFD->getEnclosingNamespaceContext()),
-   cast(Op->getLexicalDeclContext(
+declaresSameEntity(cast(EqDC), cast(NotEqDC)))
   return false;
   }
   return true;
diff --git 
a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp 
b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
index d83a176ec07eec9..603c91bd535f434 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
@@ -324,6 +324,29 @@ bool x = X() == X(); // expected-warning {{ambiguous}}
 }
 } // namespace P2468R2
 
+namespace friend_opNE_GH{
+namespace test1 {
+struct S {
+operator int();
+friend bool operator==(const S &, int); // expected-note {{reversed}}
+};
+struct A : S {};
+struct B : S {};
+bool x = A{} == B{}; // expected-warning {{ambiguous}}
+} // namespace test1
+
+namespace test2 {
+struct S {
+operator int();
+friend bool operator==(const S &, int);
+friend bool operator!=(const S &, int);
+};
+struct A : public P {};
+struct B : public P {};
+bool check(A a, B b) { return a == b; } // expected-warning {{use of 
overloaded operator '==' (with operand types 'A' and 'B') to be ambiguous}}
+} // namespace test2
+} // namespace friend_opNE_GH
+
 namespace ADL_GH68901{
 namespace test1 {
 namespace A {

>From 538c4e2d0244b2da4f0023bc17768448d728b6ce Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 25 Oct 2023 16:57:01 +0200
Subject: [PATCH 2/4] remove space

---
 clang/lib/Sema/SemaOverload.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index ce7503162ef3ba3..3b6b474886340eb 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -960,7 +960,7 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation 
OpLoc,
   if (FunctionsCorrespond(S.Context, EqFD, Op->getAsFunction()))
 return false;
 return true;
-  } 
+  }
   // Otherwise the search scope is the namespace scope of which F is a member.
   DeclContext *EqDC = EqFD->getEnclosingNamespaceContext();
   for (NamedDecl *Op : EqDC->lookup(NotEqOp)) {

>From a78d5b4b8d8a04741f0ca090625179b254e10ef5 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena 
Date: Wed, 25 Oct 2023 16:59:19 +0200
Subject: [PATCH 3/4] rename namespaces

---
 .../over.match.funcs/over.match.oper/p3-2a.cpp | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git 
a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp 
b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
index 603c91bd535f434..fb354087189cc2f 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
@@ -325,7 +325,7 @@ bool x = X() == X(); // expected-warning {{ambiguous}}
 } // namespace P2468R2
 
 namespace friend_opNE_GH{
-namespace test1 {
+namespace opNENotFound {
 struct S {
 operator int();
 friend bool operator==(const S &, int); // expected-note {{reversed}}
@@ -333,9 +333,9 @@ struct S {
 struct A : S {};
 struct B : S {};
 bool x = A{} == B{}; // expected-warning {{ambiguous}}
-} // namespace test1
+} // namespace opNENotFound
 
-namespace test2 {
+namespace opNEFou

[clang] [clang][Interp] Handle unknown-size arrays better (PR #68868)

2023-10-26 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/68868

>From 85f045fc4a84ef308bd7e2ca3e51889b37e48333 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 12 Oct 2023 11:50:16 +0200
Subject: [PATCH] [clang][Interp] Handle unknown-size arrays better

We unfortunately actually need to do some checks for array-to-pointer
decays it seems.
---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 14 +++-
 clang/lib/AST/Interp/EvalEmitter.cpp |  6 
 clang/lib/AST/Interp/Interp.cpp  |  2 ++
 clang/lib/AST/Interp/Interp.h| 20 +++
 clang/lib/AST/Interp/Opcodes.td  |  2 ++
 clang/test/AST/Interp/arrays.cpp | 42 
 6 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 1b33c69b93aa4b9..1e508f8998abefb 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -168,7 +168,16 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 return this->emitCastPointerIntegral(T, CE);
   }
 
-  case CK_ArrayToPointerDecay:
+  case CK_ArrayToPointerDecay: {
+if (!this->visit(SubExpr))
+  return false;
+if (!this->emitArrayDecay(CE))
+  return false;
+if (DiscardResult)
+  return this->emitPopPtr(CE);
+return true;
+  }
+
   case CK_AtomicToNonAtomic:
   case CK_ConstructorConversion:
   case CK_FunctionToPointerDecay:
@@ -505,6 +514,9 @@ bool 
ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueIni
   if (QT->isRecordType())
 return false;
 
+  if (QT->isIncompleteArrayType())
+return true;
+
   if (QT->isArrayType()) {
 const ArrayType *AT = QT->getAsArrayTypeUnsafe();
 assert(AT);
diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp 
b/clang/lib/AST/Interp/EvalEmitter.cpp
index f8942291b3b162d..9bc42057c5f5782 100644
--- a/clang/lib/AST/Interp/EvalEmitter.cpp
+++ b/clang/lib/AST/Interp/EvalEmitter.cpp
@@ -185,6 +185,12 @@ bool EvalEmitter::emitRetValue(const SourceInfo &Info) {
   }
   return Ok;
 }
+
+if (Ty->isIncompleteArrayType()) {
+  R = APValue(APValue::UninitArray(), 0, 0);
+  return true;
+}
+
 if (const auto *AT = Ty->getAsArrayTypeUnsafe()) {
   const size_t NumElems = Ptr.getNumElems();
   QualType ElemTy = AT->getElementType();
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index c87bb2fa6b02f16..4a4c0922758c915 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -483,6 +483,8 @@ static bool CheckFieldsInitialized(InterpState &S, CodePtr 
OpPC,
 
 if (FieldType->isRecordType()) {
   Result &= CheckFieldsInitialized(S, OpPC, FieldPtr, 
FieldPtr.getRecord());
+} else if (FieldType->isIncompleteArrayType()) {
+  // Nothing to do here.
 } else if (FieldType->isArrayType()) {
   const auto *CAT =
   cast(FieldType->getAsArrayTypeUnsafe());
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 2132e8b0a8cfa29..86cc26765295118 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1802,17 +1802,37 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) {
   const T &Offset = S.Stk.pop();
   const Pointer &Ptr = S.Stk.peek();
 
+  if (!CheckArray(S, OpPC, Ptr))
+return false;
+
   if (!OffsetHelper(S, OpPC, Offset, Ptr))
 return false;
 
   return NarrowPtr(S, OpPC);
 }
 
+/// Just takes a pointer and checks if its' an incomplete
+/// array type.
+inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {
+  const Pointer &Ptr = S.Stk.peek();
+
+  if (!Ptr.isUnknownSizeArray())
+return true;
+
+  const SourceInfo &E = S.Current->getSource(OpPC);
+  S.FFDiag(E, diag::note_constexpr_unsupported_unsized_array);
+
+  return false;
+}
+
 template ::T>
 inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) {
   const T &Offset = S.Stk.pop();
   const Pointer &Ptr = S.Stk.pop();
 
+  if (!CheckArray(S, OpPC, Ptr))
+return false;
+
   if (!OffsetHelper(S, OpPC, Offset, Ptr))
 return false;
 
diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index e1e7e5e2efbb059..69068e87d5720ab 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -687,3 +687,5 @@ def InvalidCast : Opcode {
 def InvalidDeclRef : Opcode {
   let Args = [ArgDeclRef];
 }
+
+def ArrayDecay : Opcode;
diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp
index 7110785ea4c662a..d1673094c26606a 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -455,3 +455,45 @@ namespace NoInitMapLeak {
// ref-error {{not an integral constant 
expression}} \
// ref-note {{in call to}}
 }
+
+namespace Incomplete {
+  struct Foo {
+char c;
+int a[];
+  };
+
+  co

[clang] eb737d6 - [clang][Interp][NFC] Make another Descriptor param const

2023-10-26 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-10-26T13:17:25+02:00
New Revision: eb737d6a7644d66ae57b0b4b8a30c6d2d2d961dc

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

LOG: [clang][Interp][NFC] Make another Descriptor param const

Added: 


Modified: 
clang/lib/AST/Interp/InterpBlock.h

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpBlock.h 
b/clang/lib/AST/Interp/InterpBlock.h
index 4ab67ebb9eaafcc..9d0c4859fd06c15 100644
--- a/clang/lib/AST/Interp/InterpBlock.h
+++ b/clang/lib/AST/Interp/InterpBlock.h
@@ -49,7 +49,7 @@ enum PrimType : unsigned;
 class Block final {
 public:
   /// Creates a new block.
-  Block(const std::optional &DeclID, Descriptor *Desc,
+  Block(const std::optional &DeclID, const Descriptor *Desc,
 bool IsStatic = false, bool IsExtern = false)
   : DeclID(DeclID), IsStatic(IsStatic), IsExtern(IsExtern), Desc(Desc) {}
 



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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/70306

>From 33d24cd22642d2a6f9b00aaa3826472381e93d33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement dynamic memory allocation
 handling

---
 clang/lib/AST/CMakeLists.txt  |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp  |  76 +++
 clang/lib/AST/Interp/ByteCodeExprGen.h|   2 +
 clang/lib/AST/Interp/Context.cpp  |   2 +-
 clang/lib/AST/Interp/DynamicAllocator.cpp |  91 
 clang/lib/AST/Interp/DynamicAllocator.h   |  90 
 clang/lib/AST/Interp/EvalEmitter.cpp  |   4 +-
 clang/lib/AST/Interp/Interp.cpp   |  37 
 clang/lib/AST/Interp/Interp.h |  94 
 clang/lib/AST/Interp/InterpState.cpp  |  15 ++
 clang/lib/AST/Interp/InterpState.h|  10 +
 clang/lib/AST/Interp/Opcodes.td   |  24 +++
 clang/test/AST/Interp/new-delete.cpp  | 247 ++
 13 files changed, 690 insertions(+), 3 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index fe3f8c485ec1c56..1423623fb038cab 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -75,6 +75,7 @@ add_clang_library(clangAST
   Interp/Function.cpp
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 1b33c69b93aa4b9..c42fcabe3b075ba 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1617,6 +1617,82 @@ bool 
ByteCodeExprGen::VisitCXXScalarValueInitExpr(
   return this->visitZeroInitializer(classifyPrim(Ty), Ty, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+assert(E->getArraySize());
+PrimType SizeT = classifyPrim((*E->getArraySize())->getType());
+
+if (!this->visit(*E->getArraySize()))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, E))
+return false;
+}
+
+  } else {
+// Allocate just one element.
+if (!this->emitAlloc(Desc, E))
+  return false;
+
+if (Init) {
+  if (ElemT) {
+if (!this->visit(Init))
+  return false;
+
+if (!this->emitInit(*ElemT, E))
+  return false;
+  } else {
+// Composite.
+if (!this->visitInitializer(Init))
+  return false;
+  }
+}
+  }
+
+  if (DiscardResult)
+return this->emitPopPtr(E);
+
+  return true;
+}
+
+template 
+bool ByteCodeExprGen::VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
+  const Expr *Arg = E->getArgument();
+
+  // Arg must be an lvalue.
+  if (!this->visit(Arg))
+return false;
+
+  return this->emitFree(E->isArrayForm(), E);
+}
+
 template  bool ByteCodeExprGen::discard(const Expr *E) 
{
   if (E->containsErrors())
 return false;
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 83986d3dd579ed6..f65dc9494db36ef 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -107,6 +107,8 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitSourceLocExpr(const SourceLocExpr *E);
   bool VisitOffsetOfExpr(const OffsetOfExpr *E);
   bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
+  bool VisitCXXNewExpr(const CXXNewExpr *E);
+  bool VisitCXXDeleteExpr(const CXXDeleteExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;
diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index cb96e56fb5e1ad8..ede14de30419d0b 100644
--- a/cl

[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 



@@ -1990,6 +2011,79 @@ inline bool OffsetOf(InterpState &S, CodePtr OpPC, const 
OffsetOfExpr *E) {
   return true;
 }
 
+inline bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
+  assert(Desc);
+
+  if (!CheckDynamicMemoryAllocation(S, OpPC))
+return false;
+
+  DynamicAllocator &Allocator = S.getAllocator();
+  Block *B = Allocator.allocate(Desc);
+
+  S.Stk.push(B, sizeof(InlineDescriptor));
+
+  return true;
+}
+
+template ::T>
+inline bool AllocN(InterpState &S, CodePtr OpPC, PrimType T,
+   const Expr *Source) {
+  if (!CheckDynamicMemoryAllocation(S, OpPC))
+return false;

tbaederr wrote:

I need to do that for stack allocated arrays as well. Noted.

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


[clang] 8149066 - [LoongArch][test] Add some ABI regression tests for empty struct. NFC

2023-10-26 Thread Weining Lu via cfe-commits

Author: Weining Lu
Date: 2023-10-26T19:48:37+08:00
New Revision: 8149066fa532d82ff62a0629d5a9fab6bd4da768

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

LOG: [LoongArch][test] Add some ABI regression tests for empty struct. NFC

How empty structs (not as fields of container struct) are passed in C++
is not explicitly documented in psABI. This patch adds some tests
showing the current handing of clang. Some of the results are different
from gcc. Following patch(es) will try to fix the mismatch.

Added: 


Modified: 
clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c

Removed: 




diff  --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c 
b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c
index fb90bf556c19b27..d0daafac336ec0c 100644
--- a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c
+++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c
@@ -81,9 +81,62 @@ struct s8 test_s8(struct s8 a) {
   return a;
 }
 
+/// Note: Below tests check how empty structs are passed while above tests 
check
+/// empty structs as fields of container struct are ignored when flattening
+/// structs to examine whether the container structs can be passed via FARs.
+
 // CHECK-C: define{{.*}} void @test_s9()
 // CHECK-CXX: define{{.*}} i64 @_Z7test_s92s9(i64 {{.*}})
 struct s9 { struct empty e; };
 struct s9 test_s9(struct s9 a) {
   return a;
 }
+
+// CHECK-C: define{{.*}} void @test_s10()
+// CHECK-CXX: define{{.*}} void @_Z8test_s103s10()
+struct s10 { };
+struct s10 test_s10(struct s10 a) {
+  return a;
+}
+
+// CHECK-C: define{{.*}} void @test_s11()
+// CHECK-CXX: define{{.*}} i64 @_Z8test_s113s11(i64 {{.*}})
+struct s11 { struct { } s; };
+struct s11 test_s11(struct s11 a) {
+  return a;
+}
+
+// CHECK-C: define{{.*}} void @test_s12()
+// CHECK-CXX: define{{.*}} void @_Z8test_s123s12()
+struct s12 { int i[0]; };
+struct s12 test_s12(struct s12 a) {
+  return a;
+}
+
+// CHECK-C: define{{.*}} void @test_s13()
+// CHECK-CXX: define{{.*}} void @_Z8test_s133s13()
+struct s13 { struct { } s[0]; };
+struct s13 test_s13(struct s13 a) {
+  return a;
+}
+
+// CHECK-C: define{{.*}} void @test_s14()
+// CHECK-CXX: define{{.*}} i64 @_Z8test_s143s14(i64 {{.*}})
+struct s14 { struct { } s[1]; };
+struct s14 test_s14(struct s14 a) {
+  return a;
+}
+
+// CHECK-C: define{{.*}} void @test_s15()
+// CHECK-CXX: define{{.*}} void @_Z8test_s153s15()
+struct s15 { int : 0; };
+struct s15 test_s15(struct s15 a) {
+  return a;
+}
+
+// CHECK-C: define{{.*}} void @test_s16()
+// CHECK-CXX: define{{.*}} void @_Z8test_s163s16()
+struct s16 { int : 1; };
+struct s16 test_s16(struct s16 a) {
+  return a;
+}



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


[clang] [LoongArch] Fix ABI mismatch with gcc/g++ about empty structs passing (PR #70320)

2023-10-26 Thread Lu Weining via cfe-commits

https://github.com/SixWeining created 
https://github.com/llvm/llvm-project/pull/70320

How empty structs (not as fields of container struct) are passed in C++ is not 
explicitly documented in psABI. However, this patch fixes the mismatch with g++.

Note that the unnamed bitfield case `struct { int : 1; }` in C is also fixed. 
Previously clang regards it as an empty struct and then ignores it when 
passing. Now size of the struct is counted; since it's size is not 0, clang 
will not ignore it even in C.

While https://reviews.llvm.org/D156116 fixed the handling of empty struct when 
considering eligibility of the container struct for the FP calling convention 
('flattening'), this patch fixes the handling of passing the empty struct 
itself.

Fix https://github.com/llvm/llvm-project/issues/70319

>From 3ed0605126e2cfd94e58dd38c2f58764e32e2057 Mon Sep 17 00:00:00 2001
From: Weining Lu 
Date: Thu, 26 Oct 2023 13:40:27 +0800
Subject: [PATCH] [LoongArch] Fix ABI mismatch with gcc/g++ about empty structs
 passing

How empty structs (not as fields of container struct) are passed in C++
is not explicitly documented in psABI. However, this patch fixes the
mismatch with g++.

Note that the unnamed bitfield case `struct { int : 1; }` in C is also
fixed. Previously clang regards it as an empty struct and then ignores
it when passing. Now size of the struct is counted; since it's size is
not 0, clang will not ignore it even in C.

While https://reviews.llvm.org/D156116 fixed the handling of empty
struct when considering eligibility of the container struct for the FP
calling convention ('flattening'), this patch fixes the handling of
passing the empty struct itself.

Fix https://github.com/llvm/llvm-project/issues/70319
---
 clang/lib/CodeGen/Targets/LoongArch.cpp| 10 ++
 clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c |  8 
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp 
b/clang/lib/CodeGen/Targets/LoongArch.cpp
index 7483bf6d6d1e8e2..bc508a99da9cedf 100644
--- a/clang/lib/CodeGen/Targets/LoongArch.cpp
+++ b/clang/lib/CodeGen/Targets/LoongArch.cpp
@@ -308,12 +308,14 @@ ABIArgInfo 
LoongArchABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
CGCXXABI::RAA_DirectInMemory);
   }
 
-  // Ignore empty structs/unions.
-  if (isEmptyRecord(getContext(), Ty, true))
-return ABIArgInfo::getIgnore();
-
   uint64_t Size = getContext().getTypeSize(Ty);
 
+  // Ignore empty struct or union whose size is zero, e.g. `struct { }` in C or
+  // `struct { int a[0]; }` in C++. In C++, `struct { }` is empty but it's size
+  // is 1 byte and g++ doesn't ignore it; clang++ matches this behaviour.
+  if (isEmptyRecord(getContext(), Ty, true) && Size == 0)
+return ABIArgInfo::getIgnore();
+
   // Pass floating point values via FARs if possible.
   if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
   FRLen >= Size && FARsLeft) {
diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c 
b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c
index d0daafac336ec0c..281b7b15841a999 100644
--- a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c
+++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c
@@ -93,7 +93,7 @@ struct s9 test_s9(struct s9 a) {
 }
 
 // CHECK-C: define{{.*}} void @test_s10()
-// CHECK-CXX: define{{.*}} void @_Z8test_s103s10()
+// CHECK-CXX: define{{.*}} i64 @_Z8test_s103s10(i64 {{.*}})
 struct s10 { };
 struct s10 test_s10(struct s10 a) {
   return a;
@@ -128,14 +128,14 @@ struct s14 test_s14(struct s14 a) {
 }
 
 // CHECK-C: define{{.*}} void @test_s15()
-// CHECK-CXX: define{{.*}} void @_Z8test_s153s15()
+// CHECK-CXX: define{{.*}} i64 @_Z8test_s153s15(i64 {{.*}})
 struct s15 { int : 0; };
 struct s15 test_s15(struct s15 a) {
   return a;
 }
 
-// CHECK-C: define{{.*}} void @test_s16()
-// CHECK-CXX: define{{.*}} void @_Z8test_s163s16()
+// CHECK-C: define{{.*}} i64 @test_s16(i64 {{.*}})
+// CHECK-CXX: define{{.*}} i64 @_Z8test_s163s16(i64 {{.*}})
 struct s16 { int : 1; };
 struct s16 test_s16(struct s16 a) {
   return a;

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


[clang] [clang][Interp] Implement dynamic memory allocation handling (PR #70306)

2023-10-26 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/70306

>From 33d24cd22642d2a6f9b00aaa3826472381e93d33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 25 Oct 2023 08:33:30 +0200
Subject: [PATCH 1/3] [clang][Interp] Implement dynamic memory allocation
 handling

---
 clang/lib/AST/CMakeLists.txt  |   1 +
 clang/lib/AST/Interp/ByteCodeExprGen.cpp  |  76 +++
 clang/lib/AST/Interp/ByteCodeExprGen.h|   2 +
 clang/lib/AST/Interp/Context.cpp  |   2 +-
 clang/lib/AST/Interp/DynamicAllocator.cpp |  91 
 clang/lib/AST/Interp/DynamicAllocator.h   |  90 
 clang/lib/AST/Interp/EvalEmitter.cpp  |   4 +-
 clang/lib/AST/Interp/Interp.cpp   |  37 
 clang/lib/AST/Interp/Interp.h |  94 
 clang/lib/AST/Interp/InterpState.cpp  |  15 ++
 clang/lib/AST/Interp/InterpState.h|  10 +
 clang/lib/AST/Interp/Opcodes.td   |  24 +++
 clang/test/AST/Interp/new-delete.cpp  | 247 ++
 13 files changed, 690 insertions(+), 3 deletions(-)
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.cpp
 create mode 100644 clang/lib/AST/Interp/DynamicAllocator.h
 create mode 100644 clang/test/AST/Interp/new-delete.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index fe3f8c485ec1c56..1423623fb038cab 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -75,6 +75,7 @@ add_clang_library(clangAST
   Interp/Function.cpp
   Interp/InterpBuiltin.cpp
   Interp/Floating.cpp
+  Interp/DynamicAllocator.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
   Interp/InterpFrame.cpp
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 1b33c69b93aa4b9..c42fcabe3b075ba 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1617,6 +1617,82 @@ bool 
ByteCodeExprGen::VisitCXXScalarValueInitExpr(
   return this->visitZeroInitializer(classifyPrim(Ty), Ty, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXNewExpr(const CXXNewExpr *E) {
+  assert(classifyPrim(E->getType()) == PT_Ptr);
+  const Expr *Init = E->getInitializer();
+  QualType ElementType = E->getAllocatedType();
+  std::optional ElemT = classify(ElementType);
+
+  const Descriptor *Desc;
+  if (ElemT) {
+if (E->isArray())
+  Desc = nullptr; // We're not going to use it in this case.
+else
+  Desc = P.createDescriptor(E, *ElemT, Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false,
+/*IsMutable=*/false);
+  } else {
+Desc = P.createDescriptor(
+E, ElementType.getTypePtr(),
+E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
+/*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false, Init);
+  }
+
+  if (E->isArray()) {
+assert(E->getArraySize());
+PrimType SizeT = classifyPrim((*E->getArraySize())->getType());
+
+if (!this->visit(*E->getArraySize()))
+  return false;
+
+if (ElemT) {
+  // N primitive elements.
+  if (!this->emitAllocN(SizeT, *ElemT, E, E))
+return false;
+} else {
+  // N Composite elements.
+  if (!this->emitAllocCN(SizeT, Desc, E))
+return false;
+}
+
+  } else {
+// Allocate just one element.
+if (!this->emitAlloc(Desc, E))
+  return false;
+
+if (Init) {
+  if (ElemT) {
+if (!this->visit(Init))
+  return false;
+
+if (!this->emitInit(*ElemT, E))
+  return false;
+  } else {
+// Composite.
+if (!this->visitInitializer(Init))
+  return false;
+  }
+}
+  }
+
+  if (DiscardResult)
+return this->emitPopPtr(E);
+
+  return true;
+}
+
+template 
+bool ByteCodeExprGen::VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
+  const Expr *Arg = E->getArgument();
+
+  // Arg must be an lvalue.
+  if (!this->visit(Arg))
+return false;
+
+  return this->emitFree(E->isArrayForm(), E);
+}
+
 template  bool ByteCodeExprGen::discard(const Expr *E) 
{
   if (E->containsErrors())
 return false;
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 83986d3dd579ed6..f65dc9494db36ef 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -107,6 +107,8 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitSourceLocExpr(const SourceLocExpr *E);
   bool VisitOffsetOfExpr(const OffsetOfExpr *E);
   bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
+  bool VisitCXXNewExpr(const CXXNewExpr *E);
+  bool VisitCXXDeleteExpr(const CXXDeleteExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;
diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index cb96e56fb5e1ad8..ede14d

[clang] [LoongArch] Fix ABI mismatch with gcc/g++ about empty structs passing (PR #70320)

2023-10-26 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Lu Weining (SixWeining)


Changes

How empty structs (not as fields of container struct) are passed in C++ is not 
explicitly documented in psABI. However, this patch fixes the mismatch with g++.

Note that the unnamed bitfield case `struct { int : 1; }` in C is also fixed. 
Previously clang regards it as an empty struct and then ignores it when 
passing. Now size of the struct is counted; since it's size is not 0, clang 
will not ignore it even in C.

While https://reviews.llvm.org/D156116 fixed the handling of empty struct when 
considering eligibility of the container struct for the FP calling convention 
('flattening'), this patch fixes the handling of passing the empty struct 
itself.

Fix https://github.com/llvm/llvm-project/issues/70319

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


2 Files Affected:

- (modified) clang/lib/CodeGen/Targets/LoongArch.cpp (+6-4) 
- (modified) clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c (+4-4) 


``diff
diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp 
b/clang/lib/CodeGen/Targets/LoongArch.cpp
index 7483bf6d6d1e8e2..bc508a99da9cedf 100644
--- a/clang/lib/CodeGen/Targets/LoongArch.cpp
+++ b/clang/lib/CodeGen/Targets/LoongArch.cpp
@@ -308,12 +308,14 @@ ABIArgInfo 
LoongArchABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
CGCXXABI::RAA_DirectInMemory);
   }
 
-  // Ignore empty structs/unions.
-  if (isEmptyRecord(getContext(), Ty, true))
-return ABIArgInfo::getIgnore();
-
   uint64_t Size = getContext().getTypeSize(Ty);
 
+  // Ignore empty struct or union whose size is zero, e.g. `struct { }` in C or
+  // `struct { int a[0]; }` in C++. In C++, `struct { }` is empty but it's size
+  // is 1 byte and g++ doesn't ignore it; clang++ matches this behaviour.
+  if (isEmptyRecord(getContext(), Ty, true) && Size == 0)
+return ABIArgInfo::getIgnore();
+
   // Pass floating point values via FARs if possible.
   if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
   FRLen >= Size && FARsLeft) {
diff --git a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c 
b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c
index d0daafac336ec0c..281b7b15841a999 100644
--- a/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c
+++ b/clang/test/CodeGen/LoongArch/abi-lp64d-empty-structs.c
@@ -93,7 +93,7 @@ struct s9 test_s9(struct s9 a) {
 }
 
 // CHECK-C: define{{.*}} void @test_s10()
-// CHECK-CXX: define{{.*}} void @_Z8test_s103s10()
+// CHECK-CXX: define{{.*}} i64 @_Z8test_s103s10(i64 {{.*}})
 struct s10 { };
 struct s10 test_s10(struct s10 a) {
   return a;
@@ -128,14 +128,14 @@ struct s14 test_s14(struct s14 a) {
 }
 
 // CHECK-C: define{{.*}} void @test_s15()
-// CHECK-CXX: define{{.*}} void @_Z8test_s153s15()
+// CHECK-CXX: define{{.*}} i64 @_Z8test_s153s15(i64 {{.*}})
 struct s15 { int : 0; };
 struct s15 test_s15(struct s15 a) {
   return a;
 }
 
-// CHECK-C: define{{.*}} void @test_s16()
-// CHECK-CXX: define{{.*}} void @_Z8test_s163s16()
+// CHECK-C: define{{.*}} i64 @test_s16(i64 {{.*}})
+// CHECK-CXX: define{{.*}} i64 @_Z8test_s163s16(i64 {{.*}})
 struct s16 { int : 1; };
 struct s16 test_s16(struct s16 a) {
   return a;

``




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


[clang] 658874e - [clang][Interp] Handle unknown-size arrays better (#68868)

2023-10-26 Thread via cfe-commits

Author: Timm Baeder
Date: 2023-10-26T13:53:54+02:00
New Revision: 658874e084e594f9881d5f1d004fba54d0a44d85

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

LOG: [clang][Interp] Handle unknown-size arrays better (#68868)

We unfortunately actually need to do some checks for array-to-pointer
decays it seems.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/EvalEmitter.cpp
clang/lib/AST/Interp/Interp.cpp
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Opcodes.td
clang/test/AST/Interp/arrays.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 1b33c69b93aa4b9..1e508f8998abefb 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -168,7 +168,16 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 return this->emitCastPointerIntegral(T, CE);
   }
 
-  case CK_ArrayToPointerDecay:
+  case CK_ArrayToPointerDecay: {
+if (!this->visit(SubExpr))
+  return false;
+if (!this->emitArrayDecay(CE))
+  return false;
+if (DiscardResult)
+  return this->emitPopPtr(CE);
+return true;
+  }
+
   case CK_AtomicToNonAtomic:
   case CK_ConstructorConversion:
   case CK_FunctionToPointerDecay:
@@ -505,6 +514,9 @@ bool 
ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueIni
   if (QT->isRecordType())
 return false;
 
+  if (QT->isIncompleteArrayType())
+return true;
+
   if (QT->isArrayType()) {
 const ArrayType *AT = QT->getAsArrayTypeUnsafe();
 assert(AT);

diff  --git a/clang/lib/AST/Interp/EvalEmitter.cpp 
b/clang/lib/AST/Interp/EvalEmitter.cpp
index f8942291b3b162d..9bc42057c5f5782 100644
--- a/clang/lib/AST/Interp/EvalEmitter.cpp
+++ b/clang/lib/AST/Interp/EvalEmitter.cpp
@@ -185,6 +185,12 @@ bool EvalEmitter::emitRetValue(const SourceInfo &Info) {
   }
   return Ok;
 }
+
+if (Ty->isIncompleteArrayType()) {
+  R = APValue(APValue::UninitArray(), 0, 0);
+  return true;
+}
+
 if (const auto *AT = Ty->getAsArrayTypeUnsafe()) {
   const size_t NumElems = Ptr.getNumElems();
   QualType ElemTy = AT->getElementType();

diff  --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index c87bb2fa6b02f16..4a4c0922758c915 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -483,6 +483,8 @@ static bool CheckFieldsInitialized(InterpState &S, CodePtr 
OpPC,
 
 if (FieldType->isRecordType()) {
   Result &= CheckFieldsInitialized(S, OpPC, FieldPtr, 
FieldPtr.getRecord());
+} else if (FieldType->isIncompleteArrayType()) {
+  // Nothing to do here.
 } else if (FieldType->isArrayType()) {
   const auto *CAT =
   cast(FieldType->getAsArrayTypeUnsafe());

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 2132e8b0a8cfa29..86cc26765295118 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1802,17 +1802,37 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) {
   const T &Offset = S.Stk.pop();
   const Pointer &Ptr = S.Stk.peek();
 
+  if (!CheckArray(S, OpPC, Ptr))
+return false;
+
   if (!OffsetHelper(S, OpPC, Offset, Ptr))
 return false;
 
   return NarrowPtr(S, OpPC);
 }
 
+/// Just takes a pointer and checks if its' an incomplete
+/// array type.
+inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {
+  const Pointer &Ptr = S.Stk.peek();
+
+  if (!Ptr.isUnknownSizeArray())
+return true;
+
+  const SourceInfo &E = S.Current->getSource(OpPC);
+  S.FFDiag(E, diag::note_constexpr_unsupported_unsized_array);
+
+  return false;
+}
+
 template ::T>
 inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) {
   const T &Offset = S.Stk.pop();
   const Pointer &Ptr = S.Stk.pop();
 
+  if (!CheckArray(S, OpPC, Ptr))
+return false;
+
   if (!OffsetHelper(S, OpPC, Offset, Ptr))
 return false;
 

diff  --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index e1e7e5e2efbb059..69068e87d5720ab 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -687,3 +687,5 @@ def InvalidCast : Opcode {
 def InvalidDeclRef : Opcode {
   let Args = [ArgDeclRef];
 }
+
+def ArrayDecay : Opcode;

diff  --git a/clang/test/AST/Interp/arrays.cpp 
b/clang/test/AST/Interp/arrays.cpp
index 7110785ea4c662a..d1673094c26606a 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -455,3 +455,45 @@ namespace NoInitMapLeak {
// ref-error {{not an integral constant 
expression}} \
// ref-note {{in call to}}
 }
+
+namespace Incomplete {
+  struct Foo {
+ch

[clang] [clang][Interp] Handle unknown-size arrays better (PR #68868)

2023-10-26 Thread Timm Baeder via cfe-commits

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


[clang] [LoongArch] Fix ABI mismatch with gcc/g++ about empty structs passing (PR #70320)

2023-10-26 Thread Lu Weining via cfe-commits

SixWeining wrote:

Hi @xen0n @xry111, what do you think about this change? If it is ok, I'd like 
to checrry-pick to release/17.x (hope it's not too late...).

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


[clang] [clang][Interp] Only diagnose null field access in constant contexts (PR #69223)

2023-10-26 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/69223

>From f75f7683f59a81dba1c58a8bb9706b2c12d9a261 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 16 Oct 2023 17:51:44 +0200
Subject: [PATCH 1/3] [clang][Interp] Only diagnose null field access in
 constant contexts

---
 clang/lib/AST/Interp/Interp.h |  2 +-
 clang/lib/AST/Interp/Pointer.h|  4 +++-
 clang/test/AST/Interp/c.c | 12 +++
 clang/test/AST/Interp/records.cpp | 33 +++
 4 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 2132e8b0a8cfa29..11085c85cd88b42 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1151,7 +1151,7 @@ inline bool GetPtrGlobal(InterpState &S, CodePtr OpPC, 
uint32_t I) {
 /// 2) Pushes Pointer.atField(Off) on the stack
 inline bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off) {
   const Pointer &Ptr = S.Stk.pop();
-  if (!CheckNull(S, OpPC, Ptr, CSK_Field))
+  if (S.inConstantContext() && !CheckNull(S, OpPC, Ptr, CSK_Field))
 return false;
   if (!CheckExtern(S, OpPC, Ptr))
 return false;
diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h
index 65d710077fd1cbb..8815f7f8d9ed88e 100644
--- a/clang/lib/AST/Interp/Pointer.h
+++ b/clang/lib/AST/Interp/Pointer.h
@@ -296,7 +296,7 @@ class Pointer {
   bool isUnion() const;
 
   /// Checks if the storage is extern.
-  bool isExtern() const { return Pointee->isExtern(); }
+  bool isExtern() const { return Pointee && Pointee->isExtern(); }
   /// Checks if the storage is static.
   bool isStatic() const { return Pointee->isStatic(); }
   /// Checks if the storage is temporary.
@@ -349,6 +349,8 @@ class Pointer {
 
   /// Checks if the index is one past end.
   bool isOnePastEnd() const {
+if (!Pointee)
+  return false;
 return isElementPastEnd() || getSize() == getOffset();
   }
 
diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c
index 974ca72702f7dd0..637915328576af1 100644
--- a/clang/test/AST/Interp/c.c
+++ b/clang/test/AST/Interp/c.c
@@ -47,3 +47,15 @@ _Static_assert(&a != 0, ""); // ref-warning {{always true}} \
  // expected-warning {{always true}} \
  // pedantic-expected-warning {{always true}} \
  // pedantic-expected-warning {{is a GNU 
extension}}
+
+struct y {int x,y;};
+int a2[(long)&((struct y*)0)->y]; // expected-warning {{folded to constant 
array}} \
+  // pedantic-expected-warning {{folded to 
constant array}} \
+  // ref-warning {{folded to constant array}} \
+  // pedantic-ref-warning {{folded to constant 
array}}
+
+const struct y *yy = (struct y*)0;
+const long L = (long)(&(yy->y)); // expected-error {{not a compile-time 
constant}} \
+ // pedantic-expected-error {{not a 
compile-time constant}} \
+ // ref-error {{not a compile-time constant}} \
+ // pedantic-ref-error {{not a compile-time 
constant}}
diff --git a/clang/test/AST/Interp/records.cpp 
b/clang/test/AST/Interp/records.cpp
index e899e37915f0398..280eaf34898ceca 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1102,3 +1102,36 @@ namespace DelegatingConstructors {
   static_assert(d4.a == 10, "");
   static_assert(d4.b == 12, "");
 }
+
+namespace AccessOnNullptr {
+  struct F {
+int a;
+  };
+
+  constexpr int a() { // expected-error {{never produces a constant 
expression}} \
+  // ref-error {{never produces a constant expression}}
+F *f = nullptr;
+
+f->a = 0; // expected-note 2{{cannot access field of null pointer}} \
+  // ref-note 2{{cannot access field of null pointer}}
+return f->a;
+  }
+  static_assert(a() == 0, ""); // expected-error {{not an integral constant 
expression}} \
+   // expected-note {{in call to 'a()'}} \
+   // ref-error {{not an integral constant 
expression}} \
+   // ref-note {{in call to 'a()'}}
+
+  constexpr int a2() { // expected-error {{never produces a constant 
expression}} \
+  // ref-error {{never produces a constant expression}}
+F *f = nullptr;
+
+
+const int *a = &(f->a); // expected-note 2{{cannot access field of null 
pointer}} \
+// ref-note 2{{cannot access field of null 
pointer}}
+return f->a;
+  }
+  static_assert(a2() == 0, ""); // expected-error {{not an integral constant 
expression}} \
+   // expected-note {{in call to 'a2()'}} \
+   // r

[clang] [clang][Interp] Add explicit dummy descriptors (PR #68888)

2023-10-26 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

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


  1   2   3   4   5   >