[clang] clang/OpenCL: set sqrt fp accuracy on call to Z4sqrt (PR #66651)

2023-09-18 Thread Romaric Jodin via cfe-commits

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


[clang-tools-extra] [clang-tidy] Update llvmlibc-implementation-in-namespace to new rules (PR #66504)

2023-09-18 Thread Piotr Zegar via cfe-commits


@@ -30,15 +32,18 @@ void ImplementationInNamespaceCheck::check(
 return;

PiotrZSL wrote:

this could be replaced with `decl(isExpansionInMainFile())`

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


[clang-tools-extra] [clang] remove ClassScopeFunctionSpecializationDecl (PR #66636)

2023-09-18 Thread Erich Keane via cfe-commits

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


[clang] [clang] remove ClassScopeFunctionSpecializationDecl (PR #66636)

2023-09-18 Thread Erich Keane via cfe-commits


@@ -10442,32 +10441,54 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator 
&D, DeclContext *DC,
 if (getLangOpts().CUDA && !isFunctionTemplateSpecialization)
   maybeAddCUDAHostDeviceAttrs(NewFD, Previous);
 
-// If it's a friend (and only if it's a friend), it's possible
-// that either the specialized function type or the specialized
-// template is dependent, and therefore matching will fail.  In
-// this case, don't check the specialization yet.
-if (isFunctionTemplateSpecialization && isFriend &&
-(NewFD->getType()->isDependentType() || DC->isDependentContext() ||
- 
TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
- TemplateArgs.arguments( {
-  assert(HasExplicitTemplateArgs &&
- "friend function specialization without template args");
-  if (CheckDependentFunctionTemplateSpecialization(NewFD, TemplateArgs,
-   Previous))
-NewFD->setInvalidDecl();
-} else if (isFunctionTemplateSpecialization) {
-  if (CurContext->isDependentContext() && CurContext->isRecord()
-  && !isFriend) {
-isDependentClassScopeExplicitSpecialization = true;
-  } else if (!NewFD->isInvalidDecl() &&
- CheckFunctionTemplateSpecialization(
- NewFD, (HasExplicitTemplateArgs ? &TemplateArgs : 
nullptr),
- Previous))
-NewFD->setInvalidDecl();
+// Handle explict specializations of function templates
+// and friend function declarations with an explicit
+// template argument list.
+if (isFunctionTemplateSpecialization) {
+  bool isDependentSpecialization = false;
+  if (isFriend) {
+// For friend function specializations, this is a dependent
+// specialization if its semantic context is dependent, its
+// type is dependent, or if its template-id is dependent.
+isDependentSpecialization =
+DC->isDependentContext() || NewFD->getType()->isDependentType() ||
+(HasExplicitTemplateArgs &&
+ TemplateSpecializationType::
+ anyInstantiationDependentTemplateArguments(
+ TemplateArgs.arguments()));
+assert(!isDependentSpecialization ||
+   (HasExplicitTemplateArgs == isDependentSpecialization) &&
+   "dependent friend function specialization without template "
+   "args");
+  } else {
+// For class-scope explicit specializations of function templates,
+// if the lexical context is dependent, then the specialization
+// is dependent.
+isDependentSpecialization =
+CurContext->isRecord() && CurContext->isDependentContext();
+  }
+
+  TemplateArgumentListInfo *ExplicitTemplateArgs =
+  HasExplicitTemplateArgs ? &TemplateArgs : nullptr;
+  if (isDependentSpecialization) {
+// If it's a dependent specialization, it may not be possible
+// to determine the primary template (for explicit specializations)
+// or befriended declaration (for friends) until the enclosing
+// template is instantiated. In such cases, we store the declarations
+// found by name lookup and defer resolution until instantiation.
+if (CheckDependentFunctionTemplateSpecialization(
+NewFD, ExplicitTemplateArgs, Previous))
+  NewFD->setInvalidDecl();
+  } else if (!NewFD->isInvalidDecl()) {
+if (CheckFunctionTemplateSpecialization(NewFD, ExplicitTemplateArgs,
+Previous))
+  NewFD->setInvalidDecl();
+  }
 
   // C++ [dcl.stc]p1:
   //   A storage-class-specifier shall not be specified in an explicit
   //   specialization (14.7.3)
+  // FIXME: We should be checking this for dependent specializations.

erichkeane wrote:

This seems like an important "FIXME' here, right?  Particularly since the 
dependence check is removed below? (10514)

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


[clang] [clang] remove ClassScopeFunctionSpecializationDecl (PR #66636)

2023-09-18 Thread Erich Keane via cfe-commits


@@ -428,6 +428,8 @@ class ASTNodeTraverser
   void VisitFunctionDecl(const FunctionDecl *D) {
 if (const auto *FTSI = D->getTemplateSpecializationInfo())
   dumpTemplateArgumentList(*FTSI->TemplateArguments);
+else if (const auto *DFTSI = D->getDependentSpecializationInfo())

erichkeane wrote:

Annoyingly, we're using 'auto' around here, but based on my understanding of 
our coding standard, it isn't permitted here (as the RHS doesn't state the 
type).

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


[clang] [clang] remove ClassScopeFunctionSpecializationDecl (PR #66636)

2023-09-18 Thread Erich Keane via cfe-commits


@@ -2154,6 +2144,15 @@ bool 
RecursiveASTVisitor::TraverseFunctionHelper(FunctionDecl *D) {
   TALI->NumTemplateArgs));
   }
 }
+// FIXME: Do we want to traverse the explicit template arguments for

erichkeane wrote:

I don't have a great idea here... what do we do with other explicit template 
arguments?  My knee-jerk is 'yes'? 

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


[clang] [clang] remove ClassScopeFunctionSpecializationDecl (PR #66636)

2023-09-18 Thread Erich Keane via cfe-commits

https://github.com/erichkeane commented:

I didn't spend much time in Serialization, so hopefully someone else can take a 
look, but in general I think I'm warming toward this.

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


[clang] [clang] remove ClassScopeFunctionSpecializationDecl (PR #66636)

2023-09-18 Thread Erich Keane via cfe-commits


@@ -185,14 +185,11 @@ namespace SameSignatureAfterInstantiation {
 
 namespace PR22040 {
   template  struct Foobar {
-template <> void bazqux(typename T::type) {}  // expected-error 2{{cannot 
be used prior to '::' because it has no members}}

erichkeane wrote:

Can you restore the test here?  We still want to capture that behavior.  
Additionally, despite them not being particularly interesting, please leave the 
ones from the 192-195 as well;

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


[clang-tools-extra] [clang-tidy] Update llvmlibc-implementation-in-namespace to new rules (PR #66504)

2023-09-18 Thread Piotr Zegar via cfe-commits


@@ -14,7 +14,9 @@ using namespace clang::ast_matchers;
 
 namespace clang::tidy::llvm_libc {
 
-const static StringRef RequiredNamespace = "__llvm_libc";
+const static StringRef RequiredNamespaceStart = "__llvm_libc";
+const static StringRef RequiredNamespaceMacroName = "LIBC_NAMESPACE";
+
 void ImplementationInNamespaceCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
   decl(hasParent(translationUnitDecl()), unless(linkageSpecDecl()))

PiotrZSL wrote:

Maybe: hasParent -> hasDeclContext(translationUnitDecl())




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


[clang-tools-extra] [clang-tidy] Update llvmlibc-implementation-in-namespace to new rules (PR #66504)

2023-09-18 Thread Piotr Zegar via cfe-commits

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

As a single small change to make hardcoded namespaces configurable looks fine.
I added some comments related to overall issues in this check.
Fell free to fix them or ignore them.

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


[clang] [clang-repl][CUDA] Move CUDA module registration to beginning of global_ctors (PR #66658)

2023-09-18 Thread Anubhab Ghosh via cfe-commits

https://github.com/argentite created 
https://github.com/llvm/llvm-project/pull/66658

CUDA device code needs to be registered to the runtime before kernels can be 
launched. This is done through a global constructor. User code in Clang 
interpreter, is also executed through `global_ctors`. This patch ensures 
kernels can be launched in the same iteration it is defined in by making the 
registration first in the list.

This allows `#include`-ing a large portion of code that defines device 
functions and also launches kernels in clang-repl. 

>From fb806d7c7d357f1769538df0ba7729e4b328da79 Mon Sep 17 00:00:00 2001
From: Anubhab Ghosh 
Date: Mon, 18 Sep 2023 20:33:19 +0530
Subject: [PATCH] [clang-repl][CUDA] Move CUDA module registration to beginning
 of global_ctors

CUDA device code needs to be registered to the runtime before kernels
can be launched. This is done through a global constructor.
User code in Clang interpreter, is also executed through global_ctors.
This patch ensures kernels can be launched in the same iteration it is
defined in by making the registration first in the list.
---
 clang/lib/CodeGen/CodeGenModule.cpp   |  2 +-
 .../test/Interpreter/CUDA/launch-same-ptu.cu  | 21 +++
 2 files changed, 22 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Interpreter/CUDA/launch-same-ptu.cu

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 8b0c9340775cbe9..783865409c778f5 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -794,7 +794,7 @@ void CodeGenModule::Release() {
   AddGlobalCtor(ObjCInitFunction);
   if (Context.getLangOpts().CUDA && CUDARuntime) {
 if (llvm::Function *CudaCtorFunction = CUDARuntime->finalizeModule())
-  AddGlobalCtor(CudaCtorFunction);
+  AddGlobalCtor(CudaCtorFunction, 0);
   }
   if (OpenMPRuntime) {
 if (llvm::Function *OpenMPRequiresDirectiveRegFun =
diff --git a/clang/test/Interpreter/CUDA/launch-same-ptu.cu 
b/clang/test/Interpreter/CUDA/launch-same-ptu.cu
new file mode 100644
index 000..93e203a47212fbf
--- /dev/null
+++ b/clang/test/Interpreter/CUDA/launch-same-ptu.cu
@@ -0,0 +1,21 @@
+// Tests __device__ function calls
+// RUN: cat %s | clang-repl --cuda | FileCheck %s
+
+extern "C" int printf(const char*, ...);
+
+int var;
+int* devptr = nullptr;
+printf("cudaMalloc: %d\n", cudaMalloc((void **) &devptr, sizeof(int)));
+// CHECK: cudaMalloc: 0
+
+__device__ inline void test_device(int* value) { *value = 42; } __global__ 
void test_kernel(int* value) { test_device(value); } 
test_kernel<<<1,1>>>(devptr);
+printf("CUDA Error: %d\n", cudaGetLastError());
+// CHECK-NEXT: CUDA Error: 0
+
+printf("cudaMemcpy: %d\n", cudaMemcpy(&var, devptr, sizeof(int), 
cudaMemcpyDeviceToHost));
+// CHECK-NEXT: cudaMemcpy: 0
+
+printf("Value: %d\n", var);
+// CHECK-NEXT: Value: 42
+
+%quit

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


[clang] [clang-repl][CUDA] Move CUDA module registration to beginning of global_ctors (PR #66658)

2023-09-18 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen


Changes

CUDA device code needs to be registered to the runtime before kernels can be 
launched. This is done through a global constructor. User code in Clang 
interpreter, is also executed through `global_ctors`. This patch ensures 
kernels can be launched in the same iteration it is defined in by making the 
registration first in the list.

This allows `#include`-ing a large portion of code that defines device 
functions and also launches kernels in clang-repl. 

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


2 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-1) 
- (added) clang/test/Interpreter/CUDA/launch-same-ptu.cu (+21) 


``diff
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 8b0c9340775cbe9..783865409c778f5 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -794,7 +794,7 @@ void CodeGenModule::Release() {
   AddGlobalCtor(ObjCInitFunction);
   if (Context.getLangOpts().CUDA && CUDARuntime) {
 if (llvm::Function *CudaCtorFunction = CUDARuntime->finalizeModule())
-  AddGlobalCtor(CudaCtorFunction);
+  AddGlobalCtor(CudaCtorFunction, 0);
   }
   if (OpenMPRuntime) {
 if (llvm::Function *OpenMPRequiresDirectiveRegFun =
diff --git a/clang/test/Interpreter/CUDA/launch-same-ptu.cu 
b/clang/test/Interpreter/CUDA/launch-same-ptu.cu
new file mode 100644
index 000..93e203a47212fbf
--- /dev/null
+++ b/clang/test/Interpreter/CUDA/launch-same-ptu.cu
@@ -0,0 +1,21 @@
+// Tests __device__ function calls
+// RUN: cat %s | clang-repl --cuda | FileCheck %s
+
+extern "C" int printf(const char*, ...);
+
+int var;
+int* devptr = nullptr;
+printf("cudaMalloc: %d\n", cudaMalloc((void **) &devptr, sizeof(int)));
+// CHECK: cudaMalloc: 0
+
+__device__ inline void test_device(int* value) { *value = 42; } __global__ 
void test_kernel(int* value) { test_device(value); } 
test_kernel<<<1,1>>>(devptr);
+printf("CUDA Error: %d\n", cudaGetLastError());
+// CHECK-NEXT: CUDA Error: 0
+
+printf("cudaMemcpy: %d\n", cudaMemcpy(&var, devptr, sizeof(int), 
cudaMemcpyDeviceToHost));
+// CHECK-NEXT: cudaMemcpy: 0
+
+printf("Value: %d\n", var);
+// CHECK-NEXT: Value: 42
+
+%quit

``




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


[clang] clang/OpenCL: set sqrt fp accuracy on call to Z4sqrt (PR #66651)

2023-09-18 Thread Romaric Jodin via cfe-commits

https://github.com/rjodinchr updated 
https://github.com/llvm/llvm-project/pull/66651

>From b6df142239256e979a70896f324f9ed3547c640c Mon Sep 17 00:00:00 2001
From: Romaric Jodin 
Date: Mon, 18 Sep 2023 09:34:56 +0200
Subject: [PATCH 1/2] Revert "clang/OpenCL: Add inline implementations of sqrt
 in builtin header"

This reverts commit 15e0fe0b6122e32657b98daf74a1fce028d2e5bf.
---
 clang/lib/Headers/opencl-c-base.h   |  58 ---
 clang/lib/Headers/opencl-c.h|  26 +++
 clang/lib/Sema/OpenCLBuiltins.td|   5 +-
 clang/test/CodeGenOpenCL/sqrt-fpmath.cl | 201 
 4 files changed, 27 insertions(+), 263 deletions(-)
 delete mode 100644 clang/test/CodeGenOpenCL/sqrt-fpmath.cl

diff --git a/clang/lib/Headers/opencl-c-base.h 
b/clang/lib/Headers/opencl-c-base.h
index d56e5ceae652ad5..2494f6213fc5695 100644
--- a/clang/lib/Headers/opencl-c-base.h
+++ b/clang/lib/Headers/opencl-c-base.h
@@ -819,64 +819,6 @@ int printf(__constant const char* st, ...) 
__attribute__((format(printf, 1, 2)))
 
 #endif // cl_intel_device_side_avc_motion_estimation
 
-/**
- * Compute square root.
- *
- * Provide inline implementations using the builtin so that we get appropriate
- * !fpmath based on -cl-fp32-correctly-rounded-divide-sqrt, attached to
- * llvm.sqrt. The implementation should still provide an external definition.
- */
-#define __ovld __attribute__((overloadable))
-#define __cnfn __attribute__((const))
-
-inline float __ovld __cnfn sqrt(float __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-inline float2 __ovld __cnfn sqrt(float2 __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-inline float3 __ovld __cnfn sqrt(float3 __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-inline float4 __ovld __cnfn sqrt(float4 __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-inline float8 __ovld __cnfn sqrt(float8 __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-inline float16 __ovld __cnfn sqrt(float16 __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-// We only really want to define the float variants here. However
-// -fdeclare-opencl-builtins will not work if some overloads are already
- // provided in the base header, so provide all overloads here.
-
-#ifdef cl_khr_fp64
-double __ovld __cnfn sqrt(double);
-double2 __ovld __cnfn sqrt(double2);
-double3 __ovld __cnfn sqrt(double3);
-double4 __ovld __cnfn sqrt(double4);
-double8 __ovld __cnfn sqrt(double8);
-double16 __ovld __cnfn sqrt(double16);
-#endif //cl_khr_fp64
-#ifdef cl_khr_fp16
-half __ovld __cnfn sqrt(half);
-half2 __ovld __cnfn sqrt(half2);
-half3 __ovld __cnfn sqrt(half3);
-half4 __ovld __cnfn sqrt(half4);
-half8 __ovld __cnfn sqrt(half8);
-half16 __ovld __cnfn sqrt(half16);
-#endif //cl_khr_fp16
-
-#undef __cnfn
-#undef __ovld
-
 // Disable any extensions we may have enabled previously.
 #pragma OPENCL EXTENSION all : disable
 
diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h
index 1efbbf8f8ee6a01..288bb18bc654ebc 100644
--- a/clang/lib/Headers/opencl-c.h
+++ b/clang/lib/Headers/opencl-c.h
@@ -8496,6 +8496,32 @@ half8 __ovld __cnfn sinpi(half8);
 half16 __ovld __cnfn sinpi(half16);
 #endif //cl_khr_fp16
 
+/**
+ * Compute square root.
+ */
+float __ovld __cnfn sqrt(float);
+float2 __ovld __cnfn sqrt(float2);
+float3 __ovld __cnfn sqrt(float3);
+float4 __ovld __cnfn sqrt(float4);
+float8 __ovld __cnfn sqrt(float8);
+float16 __ovld __cnfn sqrt(float16);
+#ifdef cl_khr_fp64
+double __ovld __cnfn sqrt(double);
+double2 __ovld __cnfn sqrt(double2);
+double3 __ovld __cnfn sqrt(double3);
+double4 __ovld __cnfn sqrt(double4);
+double8 __ovld __cnfn sqrt(double8);
+double16 __ovld __cnfn sqrt(double16);
+#endif //cl_khr_fp64
+#ifdef cl_khr_fp16
+half __ovld __cnfn sqrt(half);
+half2 __ovld __cnfn sqrt(half2);
+half3 __ovld __cnfn sqrt(half3);
+half4 __ovld __cnfn sqrt(half4);
+half8 __ovld __cnfn sqrt(half8);
+half16 __ovld __cnfn sqrt(half16);
+#endif //cl_khr_fp16
+
 /**
  * Compute tangent.
  */
diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td
index 9db450281912d2f..0cceba090bd8f26 100644
--- a/clang/lib/Sema/OpenCLBuiltins.td
+++ b/clang/lib/Sema/OpenCLBuiltins.td
@@ -563,15 +563,12 @@ foreach name = ["acos", "acosh", "acospi",
 "log", "log2", "log10", "log1p", "logb",
 "rint", "round", "rsqrt",
 "sin", "sinh", "sinpi",
+"sqrt",
 "tan", "tanh", "tanpi",
 "tgamma", "trunc",
 "lgamma"] in {
 def : Builtin;
 }
-
-// sqrt is handled in opencl-c-base.h to handle
-// -cl-fp32-correctly-rounded-divide-sqrt.
-
 foreach name = ["nan"] in {
   def : Builtin;
   def : Builtin;
diff --git a/clang/test/CodeGenOpenCL/sqrt-fpmath.cl 
b/clang/test/CodeGenOpenCL/sqrt-fpmath.cl
deleted file mode 100644
index df30085cba2e7d5..000
--- a/clang/test/CodeGenOpenCL/sqrt-fpmath.cl
+++ /dev/null
@@ -1,201 +0,0 @@
-// Test that float variants of s

[clang] [analyzer] Fix StackAddrEscapeChecker crash on temporary object fields (PR #66493)

2023-09-18 Thread via cfe-commits

DonatNagyE wrote:

LGTM.

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


[clang] [clang-repl][CUDA] Move CUDA module registration to beginning of global_ctors (PR #66658)

2023-09-18 Thread Anubhab Ghosh via cfe-commits

https://github.com/argentite updated 
https://github.com/llvm/llvm-project/pull/66658

>From bed2919f781c5ef71e268c95b31a6b9af5392730 Mon Sep 17 00:00:00 2001
From: Anubhab Ghosh 
Date: Mon, 18 Sep 2023 20:33:19 +0530
Subject: [PATCH] [clang-repl][CUDA] Move CUDA module registration to beginning
 of global_ctors

CUDA device code needs to be registered to the runtime before kernels
can be launched. This is done through a global constructor.
User code in Clang interpreter, is also executed through global_ctors.
This patch ensures kernels can be launched in the same iteration it is
defined in by making the registration first in the list.
---
 clang/lib/CodeGen/CodeGenModule.cpp   |  2 +-
 .../test/Interpreter/CUDA/launch-same-ptu.cu  | 21 +++
 2 files changed, 22 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Interpreter/CUDA/launch-same-ptu.cu

diff --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 8b0c9340775cbe9..647c8922f27a00f 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -794,7 +794,7 @@ void CodeGenModule::Release() {
   AddGlobalCtor(ObjCInitFunction);
   if (Context.getLangOpts().CUDA && CUDARuntime) {
 if (llvm::Function *CudaCtorFunction = CUDARuntime->finalizeModule())
-  AddGlobalCtor(CudaCtorFunction);
+  AddGlobalCtor(CudaCtorFunction, /*Priority=*/0);
   }
   if (OpenMPRuntime) {
 if (llvm::Function *OpenMPRequiresDirectiveRegFun =
diff --git a/clang/test/Interpreter/CUDA/launch-same-ptu.cu 
b/clang/test/Interpreter/CUDA/launch-same-ptu.cu
new file mode 100644
index 000..93e203a47212fbf
--- /dev/null
+++ b/clang/test/Interpreter/CUDA/launch-same-ptu.cu
@@ -0,0 +1,21 @@
+// Tests __device__ function calls
+// RUN: cat %s | clang-repl --cuda | FileCheck %s
+
+extern "C" int printf(const char*, ...);
+
+int var;
+int* devptr = nullptr;
+printf("cudaMalloc: %d\n", cudaMalloc((void **) &devptr, sizeof(int)));
+// CHECK: cudaMalloc: 0
+
+__device__ inline void test_device(int* value) { *value = 42; } __global__ 
void test_kernel(int* value) { test_device(value); } 
test_kernel<<<1,1>>>(devptr);
+printf("CUDA Error: %d\n", cudaGetLastError());
+// CHECK-NEXT: CUDA Error: 0
+
+printf("cudaMemcpy: %d\n", cudaMemcpy(&var, devptr, sizeof(int), 
cudaMemcpyDeviceToHost));
+// CHECK-NEXT: cudaMemcpy: 0
+
+printf("Value: %d\n", var);
+// CHECK-NEXT: Value: 42
+
+%quit

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


[clang] clang/OpenCL: set sqrt fp accuracy on call to Z4sqrt (PR #66651)

2023-09-18 Thread Matt Arsenault via cfe-commits


@@ -5612,6 +5612,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo 
&CallInfo,
   BundleList);
 EmitBlock(Cont);
   }
+  if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
+  CI->getCalledFunction()->getName().contains("Z4sqrt")) {

arsenm wrote:

Probably should check the language, and exact match on the permissible names 

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


[clang] [mlir][sparse] refine sparse fusion with empty tensors materialization (PR #66563)

2023-09-18 Thread Aart Bik via cfe-commits

https://github.com/aartbik updated 
https://github.com/llvm/llvm-project/pull/66563

>From afd923169445f8800365859145c8abd0823c5ef7 Mon Sep 17 00:00:00 2001
From: Aart Bik 
Date: Fri, 15 Sep 2023 17:22:34 -0700
Subject: [PATCH] [mlir][sparse] refine sparse fusion with empty tensors
 materialization

This is a minor step towards deprecating bufferization.alloc_tensor().
It replaces the examples with tensor.empty() and adjusts the underlying
rewriting logic to prepare for this upcoming change.
---
 .../Transforms/SparseTensorRewriting.cpp  | 28 +-
 .../Dialect/SparseTensor/sparse_sddmm.mlir| 54 +--
 2 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp 
b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp
index 38e6621d54b331d..08482de5879ded7 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp
@@ -50,8 +50,8 @@ static bool isSparseTensor(Value v) {
 }
 static bool isSparseTensor(OpOperand *op) { return isSparseTensor(op->get()); }
 
-// Helper method to find zero/uninitialized allocation.
-static bool isAlloc(OpOperand *op, bool isZero) {
+// Helper method to find zero/uninitialized tensor materialization.
+static bool isMaterializing(OpOperand *op, bool isZero) {
   Value val = op->get();
   // Check allocation, with zero alloc when required.
   if (auto alloc = val.getDefiningOp()) {
@@ -60,6 +60,9 @@ static bool isAlloc(OpOperand *op, bool isZero) {
   return copy && isZeroValue(copy);
 return !copy;
   }
+  // Check for empty tensor materialization.
+  if (auto empty = val.getDefiningOp())
+return !isZero;
   // Last resort for zero alloc: the whole value is zero.
   return isZero && isZeroValue(val);
 }
@@ -219,24 +222,22 @@ struct FoldInvariantYield : public 
OpRewritePattern {
   LogicalResult matchAndRewrite(GenericOp op,
 PatternRewriter &rewriter) const override {
 if (!op.hasTensorSemantics() || op.getNumResults() != 1 ||
-!isAlloc(op.getDpsInitOperand(0), /*isZero=*/false) ||
+!isMaterializing(op.getDpsInitOperand(0), /*isZero=*/false) ||
 !isZeroYield(op) || !op.getDpsInitOperand(0)->get().hasOneUse())
   return failure();
 auto outputType = getRankedTensorType(op.getResult(0));
-// Yielding zero on newly allocated (all-zero) sparse tensors can be
-// optimized out directly (regardless of dynamic or static size).
+// Yielding zero on newly materialized sparse tensor can be
+// optimized directly (regardless of dynamic or static size).
 if (getSparseTensorEncoding(outputType)) {
   rewriter.replaceOp(op, op.getDpsInitOperand(0)->get());
   return success();
 }
-// Incorporate zero value into allocation copy.
+// Use static zero value directly instead of materialization.
 if (!outputType.hasStaticShape())
   return failure();
-Value zero = constantZero(rewriter, op.getLoc(), 
op.getResult(0).getType());
-AllocTensorOp a =
-op.getDpsInitOperand(0)->get().getDefiningOp();
-rewriter.updateRootInPlace(a, [&]() { a.getCopyMutable().assign(zero); });
-rewriter.replaceOp(op, op.getDpsInitOperand(0)->get());
+Operation *def = op.getDpsInitOperand(0)->get().getDefiningOp();
+rewriter.replaceOp(op, constantZero(rewriter, op.getLoc(), outputType));
+rewriter.eraseOp(def);
 return success();
   }
 };
@@ -286,8 +287,8 @@ struct FuseSparseMultiplyOverAdd : public 
OpRewritePattern {
 !prod.getResult(0).hasOneUse())
   return failure();
 // Sampling consumer and sum of multiplication chain producer.
-if (!isAlloc(op.getDpsInitOperand(0), /*isZero=*/false) ||
-!isAlloc(prod.getDpsInitOperand(0), /*isZero=*/true) ||
+if (!isMaterializing(op.getDpsInitOperand(0), /*isZero=*/false) ||
+!isMaterializing(prod.getDpsInitOperand(0), /*isZero=*/true) ||
 !isSampling(op) || !isSumOfMul(prod))
   return failure();
 // Modify operand structure of producer and consumer.
@@ -327,6 +328,7 @@ struct FuseSparseMultiplyOverAdd : public 
OpRewritePattern {
 last = rewriter.clone(*acc, mapper)->getResult(0);
 rewriter.create(loc, last);
 // Force initial value on merged allocation for dense outputs.
+// TODO: deal with non alloc tensor here one day
 if (!getSparseTensorEncoding(op.getResult(0).getType())) {
   Value init = prod.getDpsInitOperand(0)
->get()
diff --git a/mlir/test/Dialect/SparseTensor/sparse_sddmm.mlir 
b/mlir/test/Dialect/SparseTensor/sparse_sddmm.mlir
index 610ff30a48c4a4f..707648e42cbd849 100755
--- a/mlir/test/Dialect/SparseTensor/sparse_sddmm.mlir
+++ b/mlir/test/Dialect/SparseTensor/sparse_sddmm.mlir
@@ -21,13 +21,12 @@
 }
 
 // CHECK-LABEL: func.func @fold_yield_arg_zero() -> tensor<1024x1024xf64> {
-// CHECK: 

[clang] [mlir][sparse] refine sparse fusion with empty tensors materialization (PR #66563)

2023-09-18 Thread Matthias Springer via cfe-commits

https://github.com/matthias-springer approved this pull request.


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


[clang] clang/OpenCL: set sqrt fp accuracy on call to Z4sqrt (PR #66651)

2023-09-18 Thread Romaric Jodin via cfe-commits


@@ -5612,6 +5612,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo 
&CallInfo,
   BundleList);
 EmitBlock(Cont);
   }
+  if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
+  CI->getCalledFunction()->getName().contains("Z4sqrt")) {

rjodinchr wrote:

the language is checked by `SetSqrtFPAccuracy`. I'll have a look at a better 
match for the name

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


[PATCH] D158156: [analyzer] Add C++ array delete checker

2023-09-18 Thread Donát Nagy via Phabricator via cfe-commits
donat.nagy added a comment.

Looks good, thanks for the improvements!

One minor remark: your commit uses backticks (`) around the class names in the 
bug reports, which is commonly used to mark code fragments e.g. in commit 
messages; however, in the bug reports IIRC most other checkers use apostrophes 
(').


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

https://reviews.llvm.org/D158156

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


[clang] [clang] remove ClassScopeFunctionSpecializationDecl (PR #66636)

2023-09-18 Thread Krystian Stasiowski via cfe-commits


@@ -10442,32 +10441,54 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator 
&D, DeclContext *DC,
 if (getLangOpts().CUDA && !isFunctionTemplateSpecialization)
   maybeAddCUDAHostDeviceAttrs(NewFD, Previous);
 
-// If it's a friend (and only if it's a friend), it's possible
-// that either the specialized function type or the specialized
-// template is dependent, and therefore matching will fail.  In
-// this case, don't check the specialization yet.
-if (isFunctionTemplateSpecialization && isFriend &&
-(NewFD->getType()->isDependentType() || DC->isDependentContext() ||
- 
TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
- TemplateArgs.arguments( {
-  assert(HasExplicitTemplateArgs &&
- "friend function specialization without template args");
-  if (CheckDependentFunctionTemplateSpecialization(NewFD, TemplateArgs,
-   Previous))
-NewFD->setInvalidDecl();
-} else if (isFunctionTemplateSpecialization) {
-  if (CurContext->isDependentContext() && CurContext->isRecord()
-  && !isFriend) {
-isDependentClassScopeExplicitSpecialization = true;
-  } else if (!NewFD->isInvalidDecl() &&
- CheckFunctionTemplateSpecialization(
- NewFD, (HasExplicitTemplateArgs ? &TemplateArgs : 
nullptr),
- Previous))
-NewFD->setInvalidDecl();
+// Handle explict specializations of function templates
+// and friend function declarations with an explicit
+// template argument list.
+if (isFunctionTemplateSpecialization) {
+  bool isDependentSpecialization = false;
+  if (isFriend) {
+// For friend function specializations, this is a dependent
+// specialization if its semantic context is dependent, its
+// type is dependent, or if its template-id is dependent.
+isDependentSpecialization =
+DC->isDependentContext() || NewFD->getType()->isDependentType() ||
+(HasExplicitTemplateArgs &&
+ TemplateSpecializationType::
+ anyInstantiationDependentTemplateArguments(
+ TemplateArgs.arguments()));
+assert(!isDependentSpecialization ||
+   (HasExplicitTemplateArgs == isDependentSpecialization) &&
+   "dependent friend function specialization without template "
+   "args");
+  } else {
+// For class-scope explicit specializations of function templates,
+// if the lexical context is dependent, then the specialization
+// is dependent.
+isDependentSpecialization =
+CurContext->isRecord() && CurContext->isDependentContext();
+  }
+
+  TemplateArgumentListInfo *ExplicitTemplateArgs =
+  HasExplicitTemplateArgs ? &TemplateArgs : nullptr;
+  if (isDependentSpecialization) {
+// If it's a dependent specialization, it may not be possible
+// to determine the primary template (for explicit specializations)
+// or befriended declaration (for friends) until the enclosing
+// template is instantiated. In such cases, we store the declarations
+// found by name lookup and defer resolution until instantiation.
+if (CheckDependentFunctionTemplateSpecialization(
+NewFD, ExplicitTemplateArgs, Previous))
+  NewFD->setInvalidDecl();
+  } else if (!NewFD->isInvalidDecl()) {
+if (CheckFunctionTemplateSpecialization(NewFD, ExplicitTemplateArgs,
+Previous))
+  NewFD->setInvalidDecl();
+  }
 
   // C++ [dcl.stc]p1:
   //   A storage-class-specifier shall not be specified in an explicit
   //   specialization (14.7.3)
+  // FIXME: We should be checking this for dependent specializations.

sdkrystian wrote:

I opted to not fix it in this commit to minimize unrelated changes. We _should_ 
be doing this check if `!isFriend` (since we already diagnose storage class 
specifiers on friend declarations elsewhere). Furthermore, the check for 
inconsistent storage class should happen in 
`CheckFunctionTemplateSpecialization` (so we check during the instantiation of 
dependent specializations, once the primary template is known).

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


[clang] [NFC][Clang][Headers] Update refs to ACLE in comments (PR #66662)

2023-09-18 Thread M Iyengar via cfe-commits

https://github.com/Blue-Dot created 
https://github.com/llvm/llvm-project/pull/2

Non functional change to update section comments in arm_acle.h, in order to 
align with updated documentation:  
[https://arm-software.github.io/acle/main/acle.html](https://arm-software.github.io/acle/main/acle.html)

>From b6c54823c95da82fc07e46b2edddbf6484c4201c Mon Sep 17 00:00:00 2001
From: Max Iyengar 
Date: Mon, 18 Sep 2023 13:21:28 +0100
Subject: [PATCH] [NFC][Clang][Headers] Update refs to ACLE in comments

---
 clang/lib/Headers/arm_acle.h | 61 ++--
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/clang/lib/Headers/arm_acle.h b/clang/lib/Headers/arm_acle.h
index 61d80258d166a1d..aed789863f29a2c 100644
--- a/clang/lib/Headers/arm_acle.h
+++ b/clang/lib/Headers/arm_acle.h
@@ -20,8 +20,8 @@
 extern "C" {
 #endif
 
-/* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
-/* 8.3 Memory barriers */
+/* 7 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
+/* 7.3 Memory barriers */
 #if !__has_builtin(__dmb)
 #define __dmb(i) __builtin_arm_dmb(i)
 #endif
@@ -32,7 +32,7 @@ extern "C" {
 #define __isb(i) __builtin_arm_isb(i)
 #endif
 
-/* 8.4 Hints */
+/* 7.4 Hints */
 
 #if !__has_builtin(__wfi)
 static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
__wfi(void) {
@@ -68,7 +68,7 @@ static __inline__ void __attribute__((__always_inline__, 
__nodebug__)) __yield(v
 #define __dbg(t) __builtin_arm_dbg(t)
 #endif
 
-/* 8.5 Swap */
+/* 7.5 Swap */
 static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
 __swp(uint32_t __x, volatile uint32_t *__p) {
   uint32_t v;
@@ -78,8 +78,8 @@ __swp(uint32_t __x, volatile uint32_t *__p) {
   return v;
 }
 
-/* 8.6 Memory prefetch intrinsics */
-/* 8.6.1 Data prefetch */
+/* 7.6 Memory prefetch intrinsics */
+/* 7.6.1 Data prefetch */
 #define __pld(addr) __pldx(0, 0, 0, addr)
 
 #if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
@@ -90,7 +90,7 @@ __swp(uint32_t __x, volatile uint32_t *__p) {
   __builtin_arm_prefetch(addr, access_kind, cache_level, retention_policy, 1)
 #endif
 
-/* 8.6.2 Instruction prefetch */
+/* 7.6.2 Instruction prefetch */
 #define __pli(addr) __plix(0, 0, addr)
 
 #if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
@@ -101,15 +101,15 @@ __swp(uint32_t __x, volatile uint32_t *__p) {
   __builtin_arm_prefetch(addr, 0, cache_level, retention_policy, 0)
 #endif
 
-/* 8.7 NOP */
+/* 7.7 NOP */
 #if !defined(_MSC_VER) || !defined(__aarch64__)
 static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
__nop(void) {
   __builtin_arm_nop();
 }
 #endif
 
-/* 9 DATA-PROCESSING INTRINSICS */
-/* 9.2 Miscellaneous data-processing intrinsics */
+/* 8 DATA-PROCESSING INTRINSICS */
+/* 8.2 Miscellaneous data-processing intrinsics */
 /* ROR */
 static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
 __ror(uint32_t __x, uint32_t __y) {
@@ -248,9 +248,7 @@ __rbitl(unsigned long __t) {
 #endif
 }
 
-/*
- * 9.3 16-bit multiplications
- */
+/* 8.3 16-bit multiplications */
 #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP
 static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
 __smulbb(int32_t __a, int32_t __b) {
@@ -279,18 +277,18 @@ __smulwt(int32_t __a, int32_t __b) {
 #endif
 
 /*
- * 9.4 Saturating intrinsics
+ * 8.4 Saturating intrinsics
  *
  * FIXME: Change guard to their corresponding __ARM_FEATURE flag when Q flag
  * intrinsics are implemented and the flag is enabled.
  */
-/* 9.4.1 Width-specified saturation intrinsics */
+/* 8.4.1 Width-specified saturation intrinsics */
 #if defined(__ARM_FEATURE_SAT) && __ARM_FEATURE_SAT
 #define __ssat(x, y) __builtin_arm_ssat(x, y)
 #define __usat(x, y) __builtin_arm_usat(x, y)
 #endif
 
-/* 9.4.2 Saturating addition and subtraction intrinsics */
+/* 8.4.2 Saturating addition and subtraction intrinsics */
 #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP
 static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
 __qadd(int32_t __t, int32_t __v) {
@@ -308,7 +306,7 @@ __qdbl(int32_t __t) {
 }
 #endif
 
-/* 9.4.3 Accumultating multiplications */
+/* 8.4.3 Accumultating multiplications */
 #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP
 static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
 __smlabb(int32_t __a, int32_t __b, int32_t __c) {
@@ -337,13 +335,13 @@ __smlawt(int32_t __a, int32_t __b, int32_t __c) {
 #endif
 
 
-/* 9.5.4 Parallel 16-bit saturation */
+/* 8.5.4 Parallel 16-bit saturation */
 #if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
 #define __ssat16(x, y) __builtin_arm_ssat16(x, y)
 #define __usat16(x, y) __builtin_arm_usat16(x, y)
 #endif
 
-/* 9.5.5 Packing and unpacking */
+/* 8.5.5 Packing and unpacking */
 #if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
 typedef int32_t int8x4_t;
 typedef int32_t int16x2_t;
@@ -368,7 +366,7 @@ __uxtb16(int8x4_t __a) {
 }
 #endif
 
-/* 9.5.6 Parallel selection */
+/* 8.5.6 Parallel sele

[clang] [NFC][Clang][Headers] Update refs to ACLE in comments (PR #66662)

2023-09-18 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-x86


Changes

Non functional change to update section comments in arm_acle.h, in order to 
align with updated documentation:  
[https://arm-software.github.io/acle/main/acle.html](https://arm-software.github.io/acle/main/acle.html)

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


1 Files Affected:

- (modified) clang/lib/Headers/arm_acle.h (+30-31) 


``diff
diff --git a/clang/lib/Headers/arm_acle.h b/clang/lib/Headers/arm_acle.h
index 61d80258d166a1d..aed789863f29a2c 100644
--- a/clang/lib/Headers/arm_acle.h
+++ b/clang/lib/Headers/arm_acle.h
@@ -20,8 +20,8 @@
 extern "C" {
 #endif
 
-/* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
-/* 8.3 Memory barriers */
+/* 7 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
+/* 7.3 Memory barriers */
 #if !__has_builtin(__dmb)
 #define __dmb(i) __builtin_arm_dmb(i)
 #endif
@@ -32,7 +32,7 @@ extern "C" {
 #define __isb(i) __builtin_arm_isb(i)
 #endif
 
-/* 8.4 Hints */
+/* 7.4 Hints */
 
 #if !__has_builtin(__wfi)
 static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
__wfi(void) {
@@ -68,7 +68,7 @@ static __inline__ void __attribute__((__always_inline__, 
__nodebug__)) __yield(v
 #define __dbg(t) __builtin_arm_dbg(t)
 #endif
 
-/* 8.5 Swap */
+/* 7.5 Swap */
 static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
 __swp(uint32_t __x, volatile uint32_t *__p) {
   uint32_t v;
@@ -78,8 +78,8 @@ __swp(uint32_t __x, volatile uint32_t *__p) {
   return v;
 }
 
-/* 8.6 Memory prefetch intrinsics */
-/* 8.6.1 Data prefetch */
+/* 7.6 Memory prefetch intrinsics */
+/* 7.6.1 Data prefetch */
 #define __pld(addr) __pldx(0, 0, 0, addr)
 
 #if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
@@ -90,7 +90,7 @@ __swp(uint32_t __x, volatile uint32_t *__p) {
   __builtin_arm_prefetch(addr, access_kind, cache_level, retention_policy, 1)
 #endif
 
-/* 8.6.2 Instruction prefetch */
+/* 7.6.2 Instruction prefetch */
 #define __pli(addr) __plix(0, 0, addr)
 
 #if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
@@ -101,15 +101,15 @@ __swp(uint32_t __x, volatile uint32_t *__p) {
   __builtin_arm_prefetch(addr, 0, cache_level, retention_policy, 0)
 #endif
 
-/* 8.7 NOP */
+/* 7.7 NOP */
 #if !defined(_MSC_VER) || !defined(__aarch64__)
 static __inline__ void __attribute__((__always_inline__, __nodebug__)) 
__nop(void) {
   __builtin_arm_nop();
 }
 #endif
 
-/* 9 DATA-PROCESSING INTRINSICS */
-/* 9.2 Miscellaneous data-processing intrinsics */
+/* 8 DATA-PROCESSING INTRINSICS */
+/* 8.2 Miscellaneous data-processing intrinsics */
 /* ROR */
 static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__))
 __ror(uint32_t __x, uint32_t __y) {
@@ -248,9 +248,7 @@ __rbitl(unsigned long __t) {
 #endif
 }
 
-/*
- * 9.3 16-bit multiplications
- */
+/* 8.3 16-bit multiplications */
 #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP
 static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
 __smulbb(int32_t __a, int32_t __b) {
@@ -279,18 +277,18 @@ __smulwt(int32_t __a, int32_t __b) {
 #endif
 
 /*
- * 9.4 Saturating intrinsics
+ * 8.4 Saturating intrinsics
  *
  * FIXME: Change guard to their corresponding __ARM_FEATURE flag when Q flag
  * intrinsics are implemented and the flag is enabled.
  */
-/* 9.4.1 Width-specified saturation intrinsics */
+/* 8.4.1 Width-specified saturation intrinsics */
 #if defined(__ARM_FEATURE_SAT) && __ARM_FEATURE_SAT
 #define __ssat(x, y) __builtin_arm_ssat(x, y)
 #define __usat(x, y) __builtin_arm_usat(x, y)
 #endif
 
-/* 9.4.2 Saturating addition and subtraction intrinsics */
+/* 8.4.2 Saturating addition and subtraction intrinsics */
 #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP
 static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
 __qadd(int32_t __t, int32_t __v) {
@@ -308,7 +306,7 @@ __qdbl(int32_t __t) {
 }
 #endif
 
-/* 9.4.3 Accumultating multiplications */
+/* 8.4.3 Accumultating multiplications */
 #if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP
 static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
 __smlabb(int32_t __a, int32_t __b, int32_t __c) {
@@ -337,13 +335,13 @@ __smlawt(int32_t __a, int32_t __b, int32_t __c) {
 #endif
 
 
-/* 9.5.4 Parallel 16-bit saturation */
+/* 8.5.4 Parallel 16-bit saturation */
 #if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
 #define __ssat16(x, y) __builtin_arm_ssat16(x, y)
 #define __usat16(x, y) __builtin_arm_usat16(x, y)
 #endif
 
-/* 9.5.5 Packing and unpacking */
+/* 8.5.5 Packing and unpacking */
 #if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
 typedef int32_t int8x4_t;
 typedef int32_t int16x2_t;
@@ -368,7 +366,7 @@ __uxtb16(int8x4_t __a) {
 }
 #endif
 
-/* 9.5.6 Parallel selection */
+/* 8.5.6 Parallel selection */
 #if defined(__ARM_FEATURE_SIMD32) && __ARM_FEATURE_SIMD32
 static __inline__ uint8x4_t __attribute__((__always_inline__, __nodebug__))
 __sel(uint8x4_t __a, uint8x4_t __b) {
@@ -376,7 

[clang-tools-extra] [mlir][sparse] refine sparse fusion with empty tensors materialization (PR #66563)

2023-09-18 Thread Aart Bik via cfe-commits

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


[clang] [clang] remove ClassScopeFunctionSpecializationDecl (PR #66636)

2023-09-18 Thread Krystian Stasiowski via cfe-commits


@@ -2154,6 +2144,15 @@ bool 
RecursiveASTVisitor::TraverseFunctionHelper(FunctionDecl *D) {
   TALI->NumTemplateArgs));
   }
 }
+// FIXME: Do we want to traverse the explicit template arguments for

sdkrystian wrote:

I originally added this comment because it changes behavior (i.e. explicit 
template arguments for dependent friends were not previously traversed, but are 
traversed with this change). Upon a second examination, I don't think the 
comment is necessary, and the correct behavior is to traverse the explicit 
arguments (as we would traverse them for a non-dependent specialization).

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


[clang] [analyzer] Fix StackAddrEscapeChecker crash on temporary object fields (PR #66493)

2023-09-18 Thread Gábor Horváth via cfe-commits

https://github.com/Xazax-hun approved this pull request.


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


[clang] [analyzer] Do not use APInt methods on _BitInt() Types (PR #65887)

2023-09-18 Thread Balazs Benics via cfe-commits

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

What are the semantics of assigning a wider biting to a smaller one?
BTW LGTM.

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


[clang] [clang] Fix null dereference on return in lambda attribute statement expr (PR #66643)

2023-09-18 Thread Piotr Fusik via cfe-commits

https://github.com/pfusik updated 
https://github.com/llvm/llvm-project/pull/66643

>From 88028509d7e5b5eaf38075c18abba498cb00087a Mon Sep 17 00:00:00 2001
From: Piotr Fusik 
Date: Mon, 18 Sep 2023 18:07:44 +0200
Subject: [PATCH] [clang] Fix null dereference on return in lambda attribute
 statement expr

clang was crashing on a lambda attribute with a statement expression
that contained a `return`.
It attempted to access the lambda type which was unknown at that point.

Fixes https://github.com/llvm/llvm-project/issues/48527
---
 clang/docs/ReleaseNotes.rst  |  4 
 clang/lib/Sema/SemaStmt.cpp  |  2 ++
 clang/test/SemaCXX/gh48527-2.cpp |  6 ++
 clang/test/SemaCXX/gh48527.cpp   | 10 ++
 4 files changed, 22 insertions(+)
 create mode 100644 clang/test/SemaCXX/gh48527-2.cpp
 create mode 100644 clang/test/SemaCXX/gh48527.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 500f9c9a0cda741..c6f258991c85a79 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -291,6 +291,10 @@ Bug Fixes to C++ Support
   pointers on win32.
   (`#62594 `_)
 
+- Fix crash for a lambda attribute with a statement expression
+  that contains a `return`.
+  (`#48527 `_)
+
 Bug Fixes to AST Handling
 ^
 - Fixed an import failure of recursive friend class template.
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 7cc509542d5381d..10adfbc406dfbb5 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3577,6 +3577,8 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation 
ReturnLoc,
   CapturingScopeInfo *CurCap = cast(getCurFunction());
   QualType FnRetType = CurCap->ReturnType;
   LambdaScopeInfo *CurLambda = dyn_cast(CurCap);
+  if (CurLambda && CurLambda->CallOperator->getType().isNull())
+return StmtError();
   bool HasDeducedReturnType =
   CurLambda && hasDeducedReturnType(CurLambda->CallOperator);
 
diff --git a/clang/test/SemaCXX/gh48527-2.cpp b/clang/test/SemaCXX/gh48527-2.cpp
new file mode 100644
index 000..c5d45f29252ca6b
--- /dev/null
+++ b/clang/test/SemaCXX/gh48527-2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int main() {
+auto a = []()__attribute__((b(({ return 0; }{}; // expected-warning 
{{unknown attribute 'b' ignored}}
+return 0;
+}
diff --git a/clang/test/SemaCXX/gh48527.cpp b/clang/test/SemaCXX/gh48527.cpp
new file mode 100644
index 000..420c35be37f5191
--- /dev/null
+++ b/clang/test/SemaCXX/gh48527.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int main() { // expected-note {{to match this '{'}}
+auto a = [](void)__attribute__((b(({ // expected-note {{to match this '('}}
+return 0;
+} // expected-error 3 {{expected ')'}} \
+  // expected-error {{expected ';' at end of declaration}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{expected body of lambda expression}}
+// expected-error {{expected '}'}}

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


[clang] Support target names with dots in more utilities (PR #65812)

2023-09-18 Thread via cfe-commits

dankm wrote:

> Just making sure I follow: the problem with `stem` is that if a filename 
> includes a dot, but no ".exe" or equivalent suffix, it would drop the bit 
> from the last dot onwards, even though it might be part of the tool's actual 
> name. Is that correct?

Yes, that's correct. The real examples I've run into have been 
`x86_64-unknown-freebsd13.2-clang`, fixed in 
[D135284](https://reviews.llvm.org/D135284), and the `llvm-ar` and 
`llvm-ranlib` cases in this PR. In both cases they had previously been using 
`stem` and returning `x86_64-unknown-freebsd13` and then failing to determine 
the tool name. I was mostly concerned with the cases where behaviour was 
affected. Tool name printing is valid too, though, of course.

> It looks like a number of tools have changed, but I don't see equivalent test 
> changes/new tests for all of them. It seems like we should have testing for 
> all cases where the code goes to some attempt to print the tool name. 
> Assuming it is, I note that some tools no longer will drop "other" file 
> extensions. However, I don't know of any real such extensions other than 
> Window's ".exe". Do any others exist on other platforms?

This makes sense. For my first round I did leave out the cases where having 
multiple dots in the tool name didn't make sense, such as for `dlltool` or 
`llvm-rc`. You're right though that we should test those. I'll add more tests, 
and see if I can find more examples of using `stem` or `filename` when printing 
a tool name.

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


[clang] Support target names with dots in more utilities (PR #65812)

2023-09-18 Thread via cfe-commits

dankm wrote:

> Do any others exist on other platforms?

I don't know. I explicitly tested that `.sh` remains, but that was just because 
it's relatively common (in my experience) to see tools like clang wrapped in a 
shell script. On Windows there are several executable extensions but I think 
the only one that makes sense in our use case is `.exe`, though `.ex_` might 
also be a possibility.

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


[clang] [analyzer] Remove inaccurate legacy handling of bad bitwise shifts (PR #66647)

2023-09-18 Thread Balazs Benics via cfe-commits

steakhal wrote:

What report diff's should we expect?

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


[PATCH] D64087: [clang] Correct source locations for instantiations of out-of-line defaulted special member functions. (PR25683)

2023-09-18 Thread Tom Honermann via Phabricator via cfe-commits
tahonermann added a comment.

@cor3ntin, any concerns or suggestions per my recent updates? I'll plan to land 
this in the next couple of days otherwise.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D64087

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


[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,133 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+template  class PagedVector {
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector Lookup;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The oder of
+  // the elements however depends on the order of access of the pages.
+  mutable std::vector Data;
+
+public:
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < Lookup.size());
+auto &PageId = Lookup[Index / PAGE_SIZE];
+// If the range is not filled, fill it
+if (PageId == -1) {
+  int OldSize = Data.size();
+  PageId = OldSize / PAGE_SIZE;
+  // Allocate the memory
+  Data.resize(OldSize + PAGE_SIZE);
+  // Fill the whole capacity with empty elements
+  for (int I = 0; I < PAGE_SIZE; ++I) {
+Data[I + OldSize] = T();
+  }
+}
+// Calculate the actual position in the Data vector
+// by taking the start of the page and adding the offset
+// in the page.
+std::size_t StoreIndex = Index % PAGE_SIZE + PAGE_SIZE * PageId;
+// Return the element
+assert(StoreIndex < Data.size());
+return Data[StoreIndex];
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return Lookup.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZE;
+if (Remainder) {
+  Pages += 1;
+}
+assert(Pages > Lookup.size());
+// We use -1 to indicate that a page has not been allocated yet.
+// This cannot be 0, because 0 is a valid page id.
+// We use -1 instead of a separate bool to avoid wasting space.
+Lookup.resize(Pages, -1);
+Size = NewSize;
+  }
+
+  // Return true if the vector is empty
+  bool empty() const { return Size == 0; }
+
+  /// Clear the vector, i.e. clear the allocated pages, the whole page
+  /// lookup index and reset the size.
+  void clear() {
+Size = 0;
+Lookup.clear();
+Data.clear();
+  }
+
+  /// Return the materi

[PATCH] D145214: [TSAN] add support for riscv64

2023-09-18 Thread Aditya Kumar via Phabricator via cfe-commits
hiraditya added a comment.

ping: @jrtc27 @asb do you have any pending feedback for this patch?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145214

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


[clang] [clang] Fix null dereference on return in lambda attribute statement expr (PR #66643)

2023-09-18 Thread via cfe-commits

cor3ntin wrote:

I would still move the original test, things in sema usually at least parse 
(ie, this has unbalanced parens). I won't insist though

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


[clang] [clang] Better bitfield access units (PR #65742)

2023-09-18 Thread Nathan Sidwell via cfe-commits

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


[PATCH] D64087: [clang] Correct source locations for instantiations of out-of-line defaulted special member functions. (PR25683)

2023-09-18 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin accepted this revision.
cor3ntin added a comment.

1 nit but still LGTM




Comment at: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:4993
 
-  // Copy the inner loc start from the pattern.
+  // Copy source locations from the pattern.
+  Function->setLocation(PatternDecl->getLocation());




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D64087

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


[clang] [analyzer] Add std::variant checker (PR #66481)

2023-09-18 Thread Balazs Benics via cfe-commits


@@ -0,0 +1,312 @@
+//===- StdVariantChecker.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 "clang/AST/Type.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+
+#include "TaggedUnionModeling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace variant_modeling;
+
+REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType)
+
+namespace clang {
+namespace ento {
+namespace variant_modeling {
+
+// Returns the CallEvent representing the caller of the function
+// It is needed because the CallEvent class does not contain enough information
+// to tell who called it. Checker context is needed.
+CallEventRef<> getCaller(const CallEvent &Call, const ProgramStateRef &State) {
+  const auto *CallLocationContext = Call.getLocationContext();
+  if (!CallLocationContext) {
+return nullptr;
+  }
+
+  if (CallLocationContext->inTopFrame()) {
+return nullptr;
+  }
+  const auto *CallStackFrameContext = CallLocationContext->getStackFrame();
+  if (!CallStackFrameContext) {
+return nullptr;
+  }
+
+  CallEventManager &CEMgr = State->getStateManager().getCallEventManager();
+  return CEMgr.getCaller(CallStackFrameContext, State);
+}
+
+const CXXConstructorDecl *
+getConstructorDeclarationForCall(const CallEvent &Call) {
+  const auto *ConstructorCall = dyn_cast(&Call);
+  if (!ConstructorCall) {
+return nullptr;
+  }
+  return ConstructorCall->getDecl();
+}
+
+bool isCopyConstructorCall(const CallEvent &Call) {
+  const CXXConstructorDecl *ConstructorDecl =
+  getConstructorDeclarationForCall(Call);
+  if (!ConstructorDecl) {
+return false;
+  }
+  return ConstructorDecl->isCopyConstructor();
+}
+
+bool isCopyAssignmentCall(const CallEvent &Call) {
+  const Decl *CopyAssignmentDecl = Call.getDecl();
+  if (!CopyAssignmentDecl) {
+return false;
+  }
+  const auto *AsMethodDecl = dyn_cast(CopyAssignmentDecl);
+  if (!AsMethodDecl) {
+return false;
+  }
+  return AsMethodDecl->isCopyAssignmentOperator();
+}
+
+bool isMoveConstructorCall(const CallEvent &Call) {
+  const CXXConstructorDecl *ConstructorDecl =
+  getConstructorDeclarationForCall(Call);
+  if (!ConstructorDecl) {
+return false;
+  }
+  return ConstructorDecl->isMoveConstructor();
+}
+
+bool isMoveAssignmentCall(const CallEvent &Call) {
+  const Decl *CopyAssignmentDecl = Call.getDecl();
+  if (!CopyAssignmentDecl) {
+return false;
+  }
+  const auto *AsMethodDecl = dyn_cast(CopyAssignmentDecl);
+  if (!AsMethodDecl) {
+return false;
+  }
+  return AsMethodDecl->isMoveAssignmentOperator();
+}
+
+const TemplateArgument &getFirstTemplateArgument(const CallEvent &Call) {
+  const CallExpr *CE = cast(Call.getOriginExpr());
+  const FunctionDecl *FD = CE->getDirectCallee();
+  assert(1 <= FD->getTemplateSpecializationArgs()->asArray().size() &&
+ "std::get should have at least 1 template argument!");
+  return FD->getTemplateSpecializationArgs()->asArray()[0];
+}
+
+bool isStdType(const Type *Type, const std::string &TypeName) {
+  auto *Decl = Type->getAsRecordDecl();
+  if (!Decl) {
+return false;
+  }
+
+  return (Decl->getNameAsString() == TypeName) && Decl->isInStdNamespace();
+}
+
+bool isStdVariant(const Type *Type) {
+  return isStdType(Type, std::string("variant"));
+}
+
+bool calledFromSystemHeader(const CallEvent &Call,
+const ProgramStateRef &State) {
+  auto Caller = getCaller(Call, State);
+  if (Caller) {
+return Caller->isInSystemHeader();
+  }
+  return false;
+}
+
+bool calledFromSystemHeader(const CallEvent &Call, CheckerContext &C) {
+  return calledFromSystemHeader(Call, C.getState());
+}
+
+} // end of namespace variant_modeling
+} // end of namespace ento
+} // end of namespace clang
+
+static ArrayRef
+getTemplateArgsFromVariant(const Type *VariantType) {
+  const auto *TempSpecType = VariantType->getAs();
+  assert(TempSpecType &&
+ "We are in a variant instance. It must be a template 
specialization!");
+  return TempSpecType->template_arguments();
+}
+
+static QualType getNthTemplateTypeArgFromVariant(const Type *varType,
+ unsigned i) {
+  return getTemplateArgsFromVariant(varType)[i].getAsType();
+}
+
+class StdVaria

[clang] [clang] Fix null dereference on return in lambda attribute statement expr (PR #66643)

2023-09-18 Thread Piotr Fusik via cfe-commits

pfusik wrote:

@cor3ntin to `test/CXX/what` or `test/Parser` ?

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


[clang] [analyzer] TaintPropagation checker strlen() should not propagate (PR #66086)

2023-09-18 Thread Daniel Krupp via cfe-commits

https://github.com/dkrupp updated 
https://github.com/llvm/llvm-project/pull/66086

>From 889c886c3eed31335531ec61ad2b48bef15414d8 Mon Sep 17 00:00:00 2001
From: Daniel Krupp 
Date: Fri, 8 Sep 2023 16:57:49 +0200
Subject: [PATCH] [analyzer] TaintPropagation checker strlen() should not
 propagate

strlen(..) call should not propagate taintedness,
because it brings in many false positive findings.
It is a common pattern to copy user provided input
to another buffer. In these cases we always
get warnings about tainted data used as the malloc parameter:

buf = malloc(strlen(tainted_txt) + 1); // false warning

This pattern can lead to a denial of service attack only, when
the attacker can directly specify the size of the allocated area
as an arbitrary large number (e.g. the value is converted
from a user provided string).

Later, we could reintroduce strlen() as a taint propagating function
with the consideration not to emit warnings when the tainted value
cannot be "arbitrarily large" (such as the size of an already allocated
memory block).
---
 clang/docs/ReleaseNotes.rst   |  7 +
 clang/docs/analyzer/checkers.rst  |  4 +--
 .../Checkers/GenericTaintChecker.cpp  |  7 ++---
 .../test/Analysis/taint-diagnostic-visitor.c  | 13 +-
 clang/test/Analysis/taint-generic.c   | 26 +--
 5 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3cdad2f7b9f0e5a..414cd7f62e2d764 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -409,6 +409,13 @@ Static Analyzer
   bitwise shift operators produce undefined behavior (because some operand is
   negative or too large).
 
+- The ``alpha.security.taint.TaintPropagation`` checker no longer propagates
+  taint on ``strlen`` and ``strnlen`` calls, unless these are marked
+  explicitly propagators in the user-provided taint configuration file.
+  This removal empirically reduces the number of false positive reports.
+  Read the PR for the details.
+  (`#66086 `_)
+
 .. _release-notes-sanitizers:
 
 Sanitizers
diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst
index 54ea49e7426cc86..dbd6d7787823530 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -2599,8 +2599,8 @@ Default propagations rules:
  ``memcpy``, ``memmem``, ``memmove``, ``mbtowc``, ``pread``, ``qsort``,
  ``qsort_r``, ``rawmemchr``, ``read``, ``recv``, ``recvfrom``, ``rindex``,
  ``strcasestr``, ``strchr``, ``strchrnul``, ``strcasecmp``, ``strcmp``,
- ``strcspn``, ``strlen``, ``strncasecmp``, ``strncmp``, ``strndup``,
- ``strndupa``, ``strnlen``, ``strpbrk``, ``strrchr``, ``strsep``, ``strspn``,
+ ``strcspn``, ``strncasecmp``, ``strncmp``, ``strndup``,
+ ``strndupa``, ``strpbrk``, ``strrchr``, ``strsep``, ``strspn``,
  ``strstr``, ``strtol``, ``strtoll``, ``strtoul``, ``strtoull``, ``tolower``,
  ``toupper``, ``ttyname``, ``ttyname_r``, ``wctomb``, ``wcwidth``
 
diff --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
index 5da0f34b3d0464f..dae8ff0c5c8f1b8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -695,9 +695,10 @@ void GenericTaintChecker::initTaintRules(CheckerContext 
&C) const {
   {{{"strpbrk"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
   {{{"strndup"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
   {{{"strndupa"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
-  {{{"strlen"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
-  {{{"wcslen"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
-  {{{"strnlen"}}, TR::Prop({{0}}, {{ReturnValueIndex}})},
+
+  // strlen, wcslen, strnlen and alike intentionally don't propagate taint.
+  // See the details here: https://github.com/llvm/llvm-project/pull/66086
+
   {{{"strtol"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
   {{{"strtoll"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
   {{{"strtoul"}}, TR::Prop({{0}}, {{1, ReturnValueIndex}})},
diff --git a/clang/test/Analysis/taint-diagnostic-visitor.c 
b/clang/test/Analysis/taint-diagnostic-visitor.c
index f1b9ceebdd9a6b8..8a7510177f3e444 100644
--- a/clang/test/Analysis/taint-diagnostic-visitor.c
+++ b/clang/test/Analysis/taint-diagnostic-visitor.c
@@ -10,6 +10,7 @@ int scanf(const char *restrict format, ...);
 int system(const char *command);
 char* getenv( const char* env_var );
 size_t strlen( const char* str );
+int atoi( const char* str );
 void *malloc(size_t size );
 void free( void *ptr );
 char *fgets(char *str, int n, FILE *stream);
@@ -54,11 +55,11 @@ void taintDiagnosticVLA(void) {
 // propagating through variables and expressions
 char *taintDiagnosticPropagation(){
   char *pathbuf;
-  char *pathlist=getenv("PATH"); // expected-note {{Taint 

[clang] [analyzer] TaintPropagation checker strlen() should not propagate (PR #66086)

2023-09-18 Thread Daniel Krupp via cfe-commits

dkrupp wrote:

> As I'm not a maintainer, I could not push to your branch. Here is a patch 
> that I think has the missing pieces to satisfy my review. 
> [0001-fixup-analyzer-TaintPropagation-checker-strlen-shoul.patch.txt](https://github.com/llvm/llvm-project/files/12645128/0001-fixup-analyzer-TaintPropagation-checker-strlen-shoul.patch.txt)
>  Apply it to your branch by `git am 
> 0001-fixup-analyzer-TaintPropagation-checker-strlen-shoul.patch.txt`. After 
> that, I'm okay to squash merge this PR, if you are also okay with my 
> suggestions.

Thanks for the suggestions. I squashed it.

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


[clang] clang/OpenCL: set sqrt fp accuracy on call to Z4sqrt (PR #66651)

2023-09-18 Thread Romaric Jodin via cfe-commits

https://github.com/rjodinchr updated 
https://github.com/llvm/llvm-project/pull/66651

>From b6df142239256e979a70896f324f9ed3547c640c Mon Sep 17 00:00:00 2001
From: Romaric Jodin 
Date: Mon, 18 Sep 2023 09:34:56 +0200
Subject: [PATCH 1/2] Revert "clang/OpenCL: Add inline implementations of sqrt
 in builtin header"

This reverts commit 15e0fe0b6122e32657b98daf74a1fce028d2e5bf.
---
 clang/lib/Headers/opencl-c-base.h   |  58 ---
 clang/lib/Headers/opencl-c.h|  26 +++
 clang/lib/Sema/OpenCLBuiltins.td|   5 +-
 clang/test/CodeGenOpenCL/sqrt-fpmath.cl | 201 
 4 files changed, 27 insertions(+), 263 deletions(-)
 delete mode 100644 clang/test/CodeGenOpenCL/sqrt-fpmath.cl

diff --git a/clang/lib/Headers/opencl-c-base.h 
b/clang/lib/Headers/opencl-c-base.h
index d56e5ceae652ad5..2494f6213fc5695 100644
--- a/clang/lib/Headers/opencl-c-base.h
+++ b/clang/lib/Headers/opencl-c-base.h
@@ -819,64 +819,6 @@ int printf(__constant const char* st, ...) 
__attribute__((format(printf, 1, 2)))
 
 #endif // cl_intel_device_side_avc_motion_estimation
 
-/**
- * Compute square root.
- *
- * Provide inline implementations using the builtin so that we get appropriate
- * !fpmath based on -cl-fp32-correctly-rounded-divide-sqrt, attached to
- * llvm.sqrt. The implementation should still provide an external definition.
- */
-#define __ovld __attribute__((overloadable))
-#define __cnfn __attribute__((const))
-
-inline float __ovld __cnfn sqrt(float __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-inline float2 __ovld __cnfn sqrt(float2 __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-inline float3 __ovld __cnfn sqrt(float3 __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-inline float4 __ovld __cnfn sqrt(float4 __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-inline float8 __ovld __cnfn sqrt(float8 __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-inline float16 __ovld __cnfn sqrt(float16 __x) {
-  return __builtin_elementwise_sqrt(__x);
-}
-
-// We only really want to define the float variants here. However
-// -fdeclare-opencl-builtins will not work if some overloads are already
- // provided in the base header, so provide all overloads here.
-
-#ifdef cl_khr_fp64
-double __ovld __cnfn sqrt(double);
-double2 __ovld __cnfn sqrt(double2);
-double3 __ovld __cnfn sqrt(double3);
-double4 __ovld __cnfn sqrt(double4);
-double8 __ovld __cnfn sqrt(double8);
-double16 __ovld __cnfn sqrt(double16);
-#endif //cl_khr_fp64
-#ifdef cl_khr_fp16
-half __ovld __cnfn sqrt(half);
-half2 __ovld __cnfn sqrt(half2);
-half3 __ovld __cnfn sqrt(half3);
-half4 __ovld __cnfn sqrt(half4);
-half8 __ovld __cnfn sqrt(half8);
-half16 __ovld __cnfn sqrt(half16);
-#endif //cl_khr_fp16
-
-#undef __cnfn
-#undef __ovld
-
 // Disable any extensions we may have enabled previously.
 #pragma OPENCL EXTENSION all : disable
 
diff --git a/clang/lib/Headers/opencl-c.h b/clang/lib/Headers/opencl-c.h
index 1efbbf8f8ee6a01..288bb18bc654ebc 100644
--- a/clang/lib/Headers/opencl-c.h
+++ b/clang/lib/Headers/opencl-c.h
@@ -8496,6 +8496,32 @@ half8 __ovld __cnfn sinpi(half8);
 half16 __ovld __cnfn sinpi(half16);
 #endif //cl_khr_fp16
 
+/**
+ * Compute square root.
+ */
+float __ovld __cnfn sqrt(float);
+float2 __ovld __cnfn sqrt(float2);
+float3 __ovld __cnfn sqrt(float3);
+float4 __ovld __cnfn sqrt(float4);
+float8 __ovld __cnfn sqrt(float8);
+float16 __ovld __cnfn sqrt(float16);
+#ifdef cl_khr_fp64
+double __ovld __cnfn sqrt(double);
+double2 __ovld __cnfn sqrt(double2);
+double3 __ovld __cnfn sqrt(double3);
+double4 __ovld __cnfn sqrt(double4);
+double8 __ovld __cnfn sqrt(double8);
+double16 __ovld __cnfn sqrt(double16);
+#endif //cl_khr_fp64
+#ifdef cl_khr_fp16
+half __ovld __cnfn sqrt(half);
+half2 __ovld __cnfn sqrt(half2);
+half3 __ovld __cnfn sqrt(half3);
+half4 __ovld __cnfn sqrt(half4);
+half8 __ovld __cnfn sqrt(half8);
+half16 __ovld __cnfn sqrt(half16);
+#endif //cl_khr_fp16
+
 /**
  * Compute tangent.
  */
diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td
index 9db450281912d2f..0cceba090bd8f26 100644
--- a/clang/lib/Sema/OpenCLBuiltins.td
+++ b/clang/lib/Sema/OpenCLBuiltins.td
@@ -563,15 +563,12 @@ foreach name = ["acos", "acosh", "acospi",
 "log", "log2", "log10", "log1p", "logb",
 "rint", "round", "rsqrt",
 "sin", "sinh", "sinpi",
+"sqrt",
 "tan", "tanh", "tanpi",
 "tgamma", "trunc",
 "lgamma"] in {
 def : Builtin;
 }
-
-// sqrt is handled in opencl-c-base.h to handle
-// -cl-fp32-correctly-rounded-divide-sqrt.
-
 foreach name = ["nan"] in {
   def : Builtin;
   def : Builtin;
diff --git a/clang/test/CodeGenOpenCL/sqrt-fpmath.cl 
b/clang/test/CodeGenOpenCL/sqrt-fpmath.cl
deleted file mode 100644
index df30085cba2e7d5..000
--- a/clang/test/CodeGenOpenCL/sqrt-fpmath.cl
+++ /dev/null
@@ -1,201 +0,0 @@
-// Test that float variants of s

[PATCH] D159351: [Sema] Change order of displayed overloads in diagnostics

2023-09-18 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a subscriber: cjdb.
rnk added a comment.

+@cjdb , do you have time to review this?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D159351

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


[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZ

[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZ

[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZ

[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }

kuhar wrote:

Can we make this a constant instead of a function? Or do you see benefits of 
doing it this way?

Also, since this is not a valid pointer to `T`, what do you think of changing 
the type to `uintptr_t`?

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


[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}

kuhar wrote:

Could we use `PointerIntPair`?

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


[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {

kuhar wrote:

Could we set `Size = NewSize` before this `if` to handle both outcomes?

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

[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZ

[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZ

[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZ

[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread Jakub Kuderski via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZ

[clang] [clang] Fix null dereference on return in lambda attribute statement expr (PR #66643)

2023-09-18 Thread via cfe-commits

cor3ntin wrote:

`test/Parser`. `CXX` is for tests that map very directly to a paragraph in the 
standard

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


[clang-tools-extra] [mlir][sparse] refine sparse fusion with empty tensors materialization (PR #66563)

2023-09-18 Thread Aart Bik via cfe-commits

aartbik wrote:

I have to fix a merge conflict on the test. Coming up.


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


[clang] [mlir][sparse] refine sparse fusion with empty tensors materialization (PR #66563)

2023-09-18 Thread Aart Bik via cfe-commits

aartbik wrote:

I have to fix a merge conflict on the test. Coming up.


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


[clang] [clang] Fix null dereference on return in lambda attribute statement expr (PR #66643)

2023-09-18 Thread Piotr Fusik via cfe-commits

https://github.com/pfusik updated 
https://github.com/llvm/llvm-project/pull/66643

>From 33c94d5bedf8889ab7b7fe2442fa0a3196223c91 Mon Sep 17 00:00:00 2001
From: Piotr Fusik 
Date: Mon, 18 Sep 2023 18:41:54 +0200
Subject: [PATCH] [clang] Fix null dereference on return in lambda attribute
 statement expr

clang was crashing on a lambda attribute with a statement expression
that contained a `return`.
It attempted to access the lambda type which was unknown at that point.

Fixes https://github.com/llvm/llvm-project/issues/48527
---
 clang/docs/ReleaseNotes.rst  |  4 
 clang/lib/Sema/SemaStmt.cpp  |  2 ++
 clang/test/Parser/gh48527.cpp| 10 ++
 clang/test/SemaCXX/gh48527-2.cpp |  6 ++
 4 files changed, 22 insertions(+)
 create mode 100644 clang/test/Parser/gh48527.cpp
 create mode 100644 clang/test/SemaCXX/gh48527-2.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 500f9c9a0cda741..c6f258991c85a79 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -291,6 +291,10 @@ Bug Fixes to C++ Support
   pointers on win32.
   (`#62594 `_)
 
+- Fix crash for a lambda attribute with a statement expression
+  that contains a `return`.
+  (`#48527 `_)
+
 Bug Fixes to AST Handling
 ^
 - Fixed an import failure of recursive friend class template.
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 7cc509542d5381d..10adfbc406dfbb5 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3577,6 +3577,8 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation 
ReturnLoc,
   CapturingScopeInfo *CurCap = cast(getCurFunction());
   QualType FnRetType = CurCap->ReturnType;
   LambdaScopeInfo *CurLambda = dyn_cast(CurCap);
+  if (CurLambda && CurLambda->CallOperator->getType().isNull())
+return StmtError();
   bool HasDeducedReturnType =
   CurLambda && hasDeducedReturnType(CurLambda->CallOperator);
 
diff --git a/clang/test/Parser/gh48527.cpp b/clang/test/Parser/gh48527.cpp
new file mode 100644
index 000..420c35be37f5191
--- /dev/null
+++ b/clang/test/Parser/gh48527.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int main() { // expected-note {{to match this '{'}}
+auto a = [](void)__attribute__((b(({ // expected-note {{to match this '('}}
+return 0;
+} // expected-error 3 {{expected ')'}} \
+  // expected-error {{expected ';' at end of declaration}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{expected body of lambda expression}}
+// expected-error {{expected '}'}}
diff --git a/clang/test/SemaCXX/gh48527-2.cpp b/clang/test/SemaCXX/gh48527-2.cpp
new file mode 100644
index 000..c5d45f29252ca6b
--- /dev/null
+++ b/clang/test/SemaCXX/gh48527-2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int main() {
+auto a = []()__attribute__((b(({ return 0; }{}; // expected-warning 
{{unknown attribute 'b' ignored}}
+return 0;
+}

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


[clang] [clang-repl][CUDA] Move CUDA module registration to beginning of global_ctors (PR #66658)

2023-09-18 Thread Artem Belevich via cfe-commits


@@ -794,7 +794,7 @@ void CodeGenModule::Release() {
   AddGlobalCtor(ObjCInitFunction);
   if (Context.getLangOpts().CUDA && CUDARuntime) {
 if (llvm::Function *CudaCtorFunction = CUDARuntime->finalizeModule())
-  AddGlobalCtor(CudaCtorFunction);
+  AddGlobalCtor(CudaCtorFunction, /*Priority=*/0);

Artem-B wrote:

> User code in Clang interpreter, is also executed through global_ctors. This 
> patch ensures kernels can be launched in the same iteration it is defined in 
> by making the registration first in the list.

This sounds like an application-specific problem that may be addressable by 
lowering priority of user code initializers.

In general, I'm very reluctant to change the initialization order to be 
different from what NVCC generates. We do need to interoperate with NVIDIA's 
libraries and the change in initialization order is potentially risky. 
Considering that we have no practical way to test it, and that it appears to 
address something that affects only one application (and may be dealt with on 
the app level), I do not think we should change the priority for the 
clang-generated kernel registration code.



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


[clang-tools-extra] [InstCombine] Simplify the pattern `a ne/eq (zext (a ne/eq c))` (PR #65852)

2023-09-18 Thread via cfe-commits


@@ -6380,7 +6380,56 @@ Instruction 
*InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) {
   Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE)
 return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y);
 
+  ICmpInst::Predicate Pred1, Pred2;
   const APInt *C;
+  // icmp eq/ne X, (zext (icmp eq/ne X, C))
+  if (match(&I, m_c_ICmp(Pred1, m_Value(X),
+ m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_APInt(C) &&

goldsteinn wrote:

Think it may be worth it to handle `sext` as well. X86 vec compare intrinsics 
for example expand to `(sext (icmp))`

Think logic is just about exactly the same but the `C->isOne()` case becomes: 
`isZext ? C->isOne() : C->isAllOnes()`

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


[libunwind] [libunwind][AIX] Fix up TOC register if unw_getcontext is called from a different module (PR #66549)

2023-09-18 Thread via cfe-commits

https://github.com/xingxue-ibm updated 
https://github.com/llvm/llvm-project/pull/66549

>From d42f6f35b8a4f3750b151f29951b215889d2c3e4 Mon Sep 17 00:00:00 2001
From: Xing Xue 
Date: Fri, 15 Sep 2023 16:09:43 -0400
Subject: [PATCH 1/2] The TOC register (r2) was changed by the glue code if
 unw_getcontext is called from a different module. Fix it up by using the
 original TOC register saved in the stack frame.

---
 libunwind/src/UnwindRegistersSave.S | 29 +++--
 libunwind/test/unw_resume.pass.cpp  |  3 ---
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/libunwind/src/UnwindRegistersSave.S 
b/libunwind/src/UnwindRegistersSave.S
index 58ffd1b9e1fb35a..f47b38ff848f729 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -305,9 +305,22 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   mflr  0
   std   0, PPC64_OFFS_SRR0(3) // store lr as ssr0
   PPC64_STR(1)
+  PPC64_STR(4)  // Save r4 first since it will be used for fixing r2.
+#if defined(_AIX)
+  // The TOC register (r2) was changed by the glue code if unw_getcontext
+  // is called from a different module. Save the original TOC register
+  // in the context if this is the case.
+  mflr  4
+  lwz   4, 0(4) // Get the first instruction at the return address.
+  lis   0, 0xe841   // Is it reloading the TOC register "ld 2,40(1)"?
+  ori   0, 0, 0x28
+  cmpw  0, 0, 4
+  bne   0, LnoR2Fix // No need to fix up r2 if it is not.
+  ld2, 40(1)// Use the saved TOC register in the stack.
+LnoR2Fix:
+#endif
   PPC64_STR(2)
   PPC64_STR(3)
-  PPC64_STR(4)
   PPC64_STR(5)
   PPC64_STR(6)
   PPC64_STR(7)
@@ -547,9 +560,21 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   mflr0
   stw 0,   0(3) // store lr as ssr0
   stw 1,  12(3)
+  stw 4,  24(3) // Save r4 first since it will be used for fixing r2.
+#if defined(_AIX)
+  // The TOC register (r2) was changed by the glue code if unw_getcontext
+  // is called from a different module. Save the original TOC register
+  // in the context if this is the case.
+  mflr4
+  lwz 4,  0(4)  // Get the instruction at the return address.
+  xoris   4,  4, 0x8041 // Is it reloading the TOC register "lwz r2,20(r1)"?
+  cmplwi  4,  0x14
+  bne 0,  LnoR2Fix  // No need to fix up r2 if it is not.
+  lwz 2,  20(1) // Use the saved TOC register in the stack.
+LnoR2Fix:
+#endif
   stw 2,  16(3)
   stw 3,  20(3)
-  stw 4,  24(3)
   stw 5,  28(3)
   stw 6,  32(3)
   stw 7,  36(3)
diff --git a/libunwind/test/unw_resume.pass.cpp 
b/libunwind/test/unw_resume.pass.cpp
index 76273e4a8ef0a71..08e8d4edeaf2927 100644
--- a/libunwind/test/unw_resume.pass.cpp
+++ b/libunwind/test/unw_resume.pass.cpp
@@ -10,9 +10,6 @@
 // Ensure that unw_resume() resumes execution at the stack frame identified by
 // cursor.
 
-// TODO: Investigate this failure on AIX system.
-// XFAIL: target={{.*}}-aix{{.*}}
-
 // TODO: Figure out why this fails with Memory Sanitizer.
 // XFAIL: msan
 

>From b9b6bed9a3658627b3d93a22043edb1da40134f2 Mon Sep 17 00:00:00 2001
From: Xing Xue 
Date: Mon, 18 Sep 2023 12:47:07 -0400
Subject: [PATCH 2/2] Addressed comment. - use the same code for 32- and 64-bit
 comparison.

---
 libunwind/src/UnwindRegistersSave.S | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/libunwind/src/UnwindRegistersSave.S 
b/libunwind/src/UnwindRegistersSave.S
index f47b38ff848f729..5534d1734b6ba7b 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -305,18 +305,17 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   mflr  0
   std   0, PPC64_OFFS_SRR0(3) // store lr as ssr0
   PPC64_STR(1)
-  PPC64_STR(4)  // Save r4 first since it will be used for fixing r2.
+  PPC64_STR(4)// Save r4 first since it will be used for fixing r2.
 #if defined(_AIX)
   // The TOC register (r2) was changed by the glue code if unw_getcontext
   // is called from a different module. Save the original TOC register
   // in the context if this is the case.
-  mflr  4
-  lwz   4, 0(4) // Get the first instruction at the return address.
-  lis   0, 0xe841   // Is it reloading the TOC register "ld 2,40(1)"?
-  ori   0, 0, 0x28
-  cmpw  0, 0, 4
-  bne   0, LnoR2Fix // No need to fix up r2 if it is not.
-  ld2, 40(1)// Use the saved TOC register in the stack.
+  mflr   4
+  lwz4, 0(4)  // Get the first instruction at the return address.
+  xoris  0, 4, 0xe841 // Is it reloading the TOC register "ld 2,40(1)"?
+  cmplwi 0, 0x28
+  bne0, LnoR2Fix  // No need to fix up r2 if it is not.
+  ld 2, 40(1) // Use the saved TOC register in the stack.
 LnoR2Fix:
 #endif
   PPC64_STR(2)
@@ -566,9 +565,9 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   // is called from a different module. Save the original TOC register
   // in the context if this is the case.
   mflr4
-  lwz 4,  0(4)  // Get the instruction at th

[libunwind] [libunwind][AIX] Fix up TOC register if unw_getcontext is called from a different module (PR #66549)

2023-09-18 Thread via cfe-commits

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


[libunwind] [libunwind][AIX] Fix up TOC register if unw_getcontext is called from a different module (PR #66549)

2023-09-18 Thread via cfe-commits


@@ -305,9 +305,22 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   mflr  0
   std   0, PPC64_OFFS_SRR0(3) // store lr as ssr0
   PPC64_STR(1)
+  PPC64_STR(4)  // Save r4 first since it will be used for fixing r2.
+#if defined(_AIX)
+  // The TOC register (r2) was changed by the glue code if unw_getcontext
+  // is called from a different module. Save the original TOC register
+  // in the context if this is the case.
+  mflr  4
+  lwz   4, 0(4) // Get the first instruction at the return address.
+  lis   0, 0xe841   // Is it reloading the TOC register "ld 2,40(1)"?

xingxue-ibm wrote:

Changed to use the same comparison technique for 32- and 64-bit as suggested, 
thanks!

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


[libunwind] [libunwind][AIX] Fix up TOC register if unw_getcontext is called from a different module (PR #66549)

2023-09-18 Thread via cfe-commits

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


[clang] [Driver][NVPTX] Add a warning that device debug info does not work with optimizations (PR #65327)

2023-09-18 Thread Artem Belevich via cfe-commits


@@ -28,6 +28,17 @@
 // RUN:   --offload-arch=sm_35 --cuda-path=%S/Inputs/CUDA/usr/local/cuda \
 // RUN: | FileCheck -check-prefixes=CHECK,ARCH64,SM35,RDC %s
 
+// Compiling -O{1,2,3,4,fast,s,z} with -g does not pass -g debug info to ptxas.
+// NOTE: This is because ptxas does not support optimized debugging.
+// RUN: %clang -### --target=x86_64-linux-gnu -O3 -g -c %s 2>&1 \
+// RUN:   --offload-arch=sm_35 --cuda-path=%S/Inputs/CUDA/usr/local/cuda \
+// RUN: | FileCheck -check-prefixes=CHECK,ARCH64,SM35,OPT3-DBG %s
+
+// Compiling -O0 with -g passes -g debug info to ptxas.
+// RUN: %clang -### --target=x86_64-linux-gnu -O0 -g -c %s 2>&1 \
+// RUN:   --offload-arch=sm_35 --cuda-path=%S/Inputs/CUDA/usr/local/cuda \
+// RUN: | FileCheck -check-prefixes=CHECK,ARCH64,SM35,OPT0-DBG %s
+
 // With debugging enabled, ptxas should be run with with no ptxas 
optimizations.
 // RUN: %clang -### --target=x86_64-linux-gnu --cuda-noopt-device-debug -O2 -g 
-c %s 2>&1 \

Artem-B wrote:

We should have a test for the warning, so we're sure we're not spamming users 
with something they can't do much about.

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


[clang] [Driver][NVPTX] Add a warning that device debug info does not work with optimizations (PR #65327)

2023-09-18 Thread Artem Belevich via cfe-commits


@@ -413,13 +413,25 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const 
JobAction &JA,
 // TODO: Perhaps we should map host -O2 to ptxas -O3. -O3 is ptxas's
 // default, so it may correspond more closely to the spirit of clang -O2.
 
+bool noOptimization = A->getOption().matches(options::OPT_O0);
+// Emit a driver diagnostic as warning if any -O option different from -O0,

Artem-B wrote:

This is a bit too aggressive, IMO. E.g. `-g1` or `-gmlt` works just fine.
The warning should apply only to full debug info. You should probably move the 
code below to where we check DIKind and issue the warning only if `DIKind == 
FullDebug`.

Then there's a question of whether the warning is useful in general. E.g. in a 
large project where optimization and debug options are controlled globally, the 
users will all of a sudden start getting the warnings. The builds with -Werror 
will be broken and the users will have no easy way to deal with that.



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


[clang] [analyzer] TaintPropagation checker strlen() should not propagate (PR #66086)

2023-09-18 Thread Balazs Benics via cfe-commits

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

I hope in the future we will have a more satisfying solution.
LGTM.

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


[clang] Support target names with dots in more utilities (PR #65812)

2023-09-18 Thread via cfe-commits


@@ -1696,6 +1696,38 @@ TEST(Support, ReplacePathPrefix) {
   EXPECT_EQ(Path, "C:\\old/foo\\bar");
 }
 
+TEST(Support, FindProgramName) {
+  StringRef WindowsProgName =
+  path::program_name("C:\\Test\\foo.exe", path::Style::windows);
+  EXPECT_EQ(WindowsProgName, "foo");
+
+  StringRef WindowsProgNameManyDots = path::program_name(
+  "C:\\Test.7\\x86_64-freebsd14.0-clang.exe", path::Style::windows);
+  EXPECT_EQ(WindowsProgNameManyDots, "x86_64-freebsd14.0-clang");
+
+  StringRef PosixProgName =
+  path::program_name("/var/empty/clang.exe", path::Style::posix);
+  EXPECT_EQ(PosixProgName, "clang");
+
+  StringRef PosixProgNameManyDotsExe = path::program_name(
+  "/llvm-test16.4/x86_64-portbld-freebsd13.2-llvm-ar.exe",
+  path::Style::posix);
+  EXPECT_EQ(PosixProgNameManyDotsExe, "x86_64-portbld-freebsd13.2-llvm-ar");
+
+  StringRef PosixProgNameManyDots = path::program_name(
+  "/llvm-test16.4/x86_64-portbld-freebsd13.2-llvm-ar", path::Style::posix);
+  EXPECT_EQ(PosixProgNameManyDots, "x86_64-portbld-freebsd13.2-llvm-ar");
+
+  StringRef PosixProgNameSh =
+  
path::program_name("/llvm-test16.4/x86_64-portbld-freebsd13.2-llvm-ar.sh",
+ path::Style::posix);
+  EXPECT_EQ(PosixProgNameSh, "x86_64-portbld-freebsd13.2-llvm-ar.sh");
+
+  StringRef WorseThanFailure =

dankm wrote:

Yeah, that one was purely for my own benefit. I was describing behaviour I 
wasn't sure I wanted to keep, just what it was currently doing. It was intended 
as a reminder to me to come up 1. A better name, and 2. what the intended 
output should be.

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


[PATCH] D155610: [Clang][Sema] Fix display of characters on static assertion failure

2023-09-18 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: clang/test/SemaCXX/static-assert.cpp:287
+  static_assert((char16_t)L'ゆ' == L"C̵̭̯̠̎͌ͅť̺"[1], ""); // expected-error 
{{failed}} \
+  // expected-note {{evaluates 
to ''ゆ' (0x3086) == '̵' (0x335)'}}
+  static_assert(L"\/"[1] == u'\xFFFD', ""); // expected-error {{failed}} \

cor3ntin wrote:
> hubert.reinterpretcast wrote:
> > tahonermann wrote:
> > > cor3ntin wrote:
> > > > hubert.reinterpretcast wrote:
> > > > > hubert.reinterpretcast wrote:
> > > > > > cor3ntin wrote:
> > > > > > > hubert.reinterpretcast wrote:
> > > > > > > > The C++23 escaped string formatting facility would not generate 
> > > > > > > > a trailing combining character like this. I recommend following 
> > > > > > > > suit.
> > > > > > > > 
> > > > > > > > Info on U+0335: 
> > > > > > > > https://util.unicode.org/UnicodeJsps/character.jsp?a=0335
> > > > > > > > 
> > > > > > > This is way outside the scope of the patch. The diagnostic output 
> > > > > > > facility has no understanding of combining characters or 
> > > > > > > graphemes and do not attempt to match std::print. It probably 
> > > > > > > would be an improvement but this patch is not trying to modify 
> > > > > > > how all diagnostics are printed. (all of that logic is in 
> > > > > > > Diagnostic.cpp)
> > > > > > This patch is pushing the envelope of what appears in diagnostics. 
> > > > > > One can also argue that someone writing
> > > > > > ```
> > > > > > static_assert(false, "\u0301");
> > > > > > ```
> > > > > > gets what they deserve, but that case does not have a big problem 
> > > > > > anyway (because the provided message text appears after `: `).
> > > > > > 
> > > > > > This patch increases the exposure of the diagnostic output facility 
> > > > > > to input that it does not handle well. I disagree that it is 
> > > > > > outside the scope of this patch to insist that it does not generate 
> > > > > > such inputs to the diagnostic output facility (even if a possible 
> > > > > > solution is to modify the diagnostic output facility first).
> > > > > @cor3ntin, do you have status quo examples for how grapheme-extending 
> > > > > characters that are not already "problematic" in their original 
> > > > > context are emitted in diagnostics in contexts where they are?
> > > > Are you looking for that sort of examples? 
> > > > https://godbolt.org/z/c79xWr7Me
> > > > That shows that clang has no understanding of graphemes
> > > gcc and MSVC get that case "right" (probably by accident). 
> > > https://godbolt.org/z/Tjd6xnEon
> > I was more looking for cases where the output grapheme includes elements 
> > that were part of the fixed message text (gobbling quotes, etc.). Also, 
> > this patch is in the wrong shape for handling this concern in the 
> > diagnostic printer because the delimiting of the replacement text happens 
> > in this patch.
> Could you craft a message that becomes a graphene after substitution by the 
> engine? Maybe? You would have to try very hard and `static_assert` 
> diagnostics are not of the right shape.
> 
> > This patch increases the exposure of the diagnostic output facility to 
> > input that it does not handle well. I disagree that it is outside the scope 
> > of this patch to insist that it does not generate such inputs to the 
> > diagnostic output facility (even if a possible solution is to modify the 
> > diagnostic output facility first).
> 
> I still don't see it. None of the output produce in this patch are even close 
> to what i could be problematic. ie this patch is only ever producing ASCII or 
> single codepoints that gets escaped when they are not printable
> Could you craft a message that becomes a graphene after substitution by the 
> engine? Maybe? You would have to try very hard and `static_assert` 
> diagnostics are not of the right shape.

That is what I meant by this patch introducing new situations.

> > This patch increases the exposure of the diagnostic output facility to 
> > input that it does not handle well. I disagree that it is outside the scope 
> > of this patch to insist that it does not generate such inputs to the 
> > diagnostic output facility (even if a possible solution is to modify the 
> > diagnostic output facility first).
> 
> I still don't see it. None of the output produce in this patch are even close 
> to what i could be problematic. ie this patch is only ever producing ASCII or 
> single codepoints that gets escaped when they are not printable

This patch produces single codepoints that are not escaped even when they may 
combine with a `'` delimiter. This patch also (currently) forms the string with 
the `'` and the potentially-combining character directly adjacent to each 
other. The least this patch should do is to emit the potentially-combining 
character to the diagnostic facility as a separate substitution (that is, if we 
can agree that the diagnos

[clang] [analyzer] Do not use APInt methods on _BitInt() Types (PR #65887)

2023-09-18 Thread via cfe-commits

https://github.com/vabridgers updated 
https://github.com/llvm/llvm-project/pull/65887

>From ea63aae4c34cf452e684ec0dc943b7dbe52c453f Mon Sep 17 00:00:00 2001
From: Vince Bridgers 
Date: Sat, 9 Sep 2023 21:08:47 +0200
Subject: [PATCH] [analyzer] Fix crash analyzing _BitInt() in evalIntegralCast

evalIntegralCast was using makeIntVal, and when _BitInt() types were
introduced this exposed a crash in evalIntegralCast as a result.

Improve evalIntegralCast to use makeIntVal more efficiently to avoid the
crash exposed by use of _BitInt.

This was caught with our internal randomized testing.

/llvm/include/llvm/ADT/APInt.h:1510:
  int64_t llvm::APInt::getSExtValue() const: Assertion
  `getSignificantBits() <= 64 && "Too many bits for int64_t"' failed.a

...
 #9  llvm::APInt::getSExtValue() const
  /llvm/include/llvm/ADT/APInt.h:1510:5
  llvm::IntrusiveRefCntPtr,
  clang::ento::SVal, clang::QualType, clang::QualType)
  /clang/lib/StaticAnalyzer/Core/SValBuilder.cpp:607:24
  clang::Expr const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&)
  /clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp:413:61
...

 Fixes: https://github.com/llvm/llvm-project/issues/61960

 Reviewed By: donat.nagy
---
 clang/lib/StaticAnalyzer/Core/SValBuilder.cpp |  8 +++-
 clang/test/Analysis/bitint-no-crash.c | 11 +++
 2 files changed, 14 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Analysis/bitint-no-crash.c

diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp 
b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 4fe828bdf7681fc..f827f43eaa7da67 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -598,11 +598,9 @@ SVal SValBuilder::evalIntegralCast(ProgramStateRef state, 
SVal val,
   APSIntType ToType(getContext().getTypeSize(castTy),
 castTy->isUnsignedIntegerType());
   llvm::APSInt ToTypeMax = ToType.getMaxValue();
-  NonLoc ToTypeMaxVal =
-  makeIntVal(ToTypeMax.isUnsigned() ? ToTypeMax.getZExtValue()
-: ToTypeMax.getSExtValue(),
- castTy)
-  .castAs();
+
+  NonLoc ToTypeMaxVal = makeIntVal(ToTypeMax);
+
   // Check the range of the symbol being casted against the maximum value of 
the
   // target type.
   NonLoc FromVal = val.castAs();
diff --git a/clang/test/Analysis/bitint-no-crash.c 
b/clang/test/Analysis/bitint-no-crash.c
new file mode 100644
index 000..6fa041974a3c981
--- /dev/null
+++ b/clang/test/Analysis/bitint-no-crash.c
@@ -0,0 +1,11 @@
+ // RUN: %clang_analyze_cc1 -analyzer-checker=core \
+ // RUN:   -analyzer-checker=debug.ExprInspection \
+ // RUN:   -verify %s
+
+// Don't crash when using _BitInt()
+// expected-no-diagnostics
+_BitInt(256) a;
+_BitInt(129) b;
+void c() {
+  b = a;
+}

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


[clang-tools-extra] [clang] remove ClassScopeFunctionSpecializationDecl (PR #66636)

2023-09-18 Thread Piotr Zegar via cfe-commits


@@ -67,7 +67,7 @@ AST_MATCHER_P(CallExpr, hasLastArgument,
 // function had parameters defined (this is useful to check if there is only 
one
 // variadic argument).
 AST_MATCHER(CXXMemberCallExpr, hasSameNumArgsAsDeclNumParams) {
-  if (Node.getMethodDecl()->isFunctionTemplateSpecialization())
+  if (Node.getMethodDecl()->getPrimaryTemplate())

PiotrZSL wrote:

```
  if (const FunctionTemplateDecl* PrimaryTemplate = 
Node.getMethodDecl()->getPrimaryTemplate())
return Node.getNumArgs() == 
PrimaryTemplate->getTemplatedDecl()->getNumParams();
```

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


[clang] [clang-repl][CUDA] Move CUDA module registration to beginning of global_ctors (PR #66658)

2023-09-18 Thread Anubhab Ghosh via cfe-commits


@@ -794,7 +794,7 @@ void CodeGenModule::Release() {
   AddGlobalCtor(ObjCInitFunction);
   if (Context.getLangOpts().CUDA && CUDARuntime) {
 if (llvm::Function *CudaCtorFunction = CUDARuntime->finalizeModule())
-  AddGlobalCtor(CudaCtorFunction);
+  AddGlobalCtor(CudaCtorFunction, /*Priority=*/0);

argentite wrote:

The underlying issues is not actually clang-repl specific, it also affects 
clang. For example, this seems to succeed in `nvcc` but fails with `clang`:
```cpp
#include 

__global__ void kernel() {}

class C {
public:
  C() {
kernel<<<1, 1>>>();
printf("Error: %d\n", cudaGetLastError());
  }
};

C c;

int main() {}
```

This is fixed by this patch. Maybe we can look for a proper solution to this?

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


[clang-tools-extra] [InstCombine] Simplify the pattern `a ne/eq (zext (a ne/eq c))` (PR #65852)

2023-09-18 Thread Yingwei Zheng via cfe-commits


@@ -6380,7 +6380,56 @@ Instruction 
*InstCombinerImpl::foldICmpUsingBoolRange(ICmpInst &I) {
   Y->getType()->isIntOrIntVectorTy(1) && Pred == ICmpInst::ICMP_ULE)
 return BinaryOperator::CreateOr(Builder.CreateIsNull(X), Y);
 
+  ICmpInst::Predicate Pred1, Pred2;
   const APInt *C;
+  // icmp eq/ne X, (zext (icmp eq/ne X, C))
+  if (match(&I, m_c_ICmp(Pred1, m_Value(X),
+ m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_APInt(C) &&

dtcxzyw wrote:

Proof for `sext`: https://alive2.llvm.org/ce/z/tv5wuE

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


[clang] [clang] Fix null dereference on return in lambda attribute statement expr (PR #66643)

2023-09-18 Thread via cfe-commits


@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int main() {
+auto a = []()__attribute__((b(({ return 0; }{}; // expected-warning 
{{unknown attribute 'b' ignored}}
+return 0;
+}

cor3ntin wrote:

This can move to `clang/test/SemaCXX/lambda-expressions.cpp`
(the name of the function can have the number of the GH issue)

We try to limit the number of test files

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


[PATCH] D157615: [ExtendLifetimes][1/4] Add "disable-post-ra" function attribute to disable the post-regalloc scheduler

2023-09-18 Thread David Blaikie via Phabricator via cfe-commits
dblaikie added a comment.

In D157615#4647235 , @StephenTozer 
wrote:

> In D157615#4646848 , @dblaikie 
> wrote:
>
>> Might be worth rewording the commit, or  splitting it - I'd say the 
>> introduction of `optdebug` should be the noteworthier part of this patch (or 
>> whichever patch introduces it) - so either "this patch adds optdebug, and a 
>> first/exemplar use of it in postra scheduler" or split it into a patch that 
>> just adds the attribute and no uses, and one that adds the use.
>
> SGTM, the scope of this patch has increased as-of the latest update. That 
> being said AFAIK Github PRs don't currently have support for stacked PRs, so 
> I imagine I'll need to have one review up at a time.

Yeah, don't think we have a clear path for stacked PRs right now - so, yeah, 
will try to work through them one at a time. I guess you could post PRs that 
contain all the commits (eg: one review containing commit A, another review 
containing A and B, etc) - it doesn't have a good solution if large changes to 
predecessor patches need updates to latter patches (eg: if A causes invasive 
changes to B) - but otherwise it's probably OK-ish... (& in this case I don't 
think any changes to "adding optdebug" are likely to substantially change the 
nature of subsequent patches). But maybe not a big deal either way/can just 
wait for the subsequent patches.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D157615

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


[clang] [clang] Fix null dereference on return in lambda attribute statement expr (PR #66643)

2023-09-18 Thread Piotr Fusik via cfe-commits

https://github.com/pfusik updated 
https://github.com/llvm/llvm-project/pull/66643

>From 81281e52ac76d0c10ddadaf7d75a544eccce39a5 Mon Sep 17 00:00:00 2001
From: Piotr Fusik 
Date: Mon, 18 Sep 2023 19:54:16 +0200
Subject: [PATCH] [clang] Fix null dereference on return in lambda attribute
 statement expr

clang was crashing on a lambda attribute with a statement expression
that contained a `return`.
It attempted to access the lambda type which was unknown at that point.

Fixes https://github.com/llvm/llvm-project/issues/48527
---
 clang/docs/ReleaseNotes.rst   |  4 
 clang/lib/Sema/SemaStmt.cpp   |  2 ++
 clang/test/Parser/gh48527.cpp | 10 ++
 clang/test/SemaCXX/lambda-expressions.cpp |  4 
 4 files changed, 20 insertions(+)
 create mode 100644 clang/test/Parser/gh48527.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 500f9c9a0cda741..c6f258991c85a79 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -291,6 +291,10 @@ Bug Fixes to C++ Support
   pointers on win32.
   (`#62594 `_)
 
+- Fix crash for a lambda attribute with a statement expression
+  that contains a `return`.
+  (`#48527 `_)
+
 Bug Fixes to AST Handling
 ^
 - Fixed an import failure of recursive friend class template.
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 7cc509542d5381d..10adfbc406dfbb5 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3577,6 +3577,8 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation 
ReturnLoc,
   CapturingScopeInfo *CurCap = cast(getCurFunction());
   QualType FnRetType = CurCap->ReturnType;
   LambdaScopeInfo *CurLambda = dyn_cast(CurCap);
+  if (CurLambda && CurLambda->CallOperator->getType().isNull())
+return StmtError();
   bool HasDeducedReturnType =
   CurLambda && hasDeducedReturnType(CurLambda->CallOperator);
 
diff --git a/clang/test/Parser/gh48527.cpp b/clang/test/Parser/gh48527.cpp
new file mode 100644
index 000..420c35be37f5191
--- /dev/null
+++ b/clang/test/Parser/gh48527.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int main() { // expected-note {{to match this '{'}}
+auto a = [](void)__attribute__((b(({ // expected-note {{to match this '('}}
+return 0;
+} // expected-error 3 {{expected ')'}} \
+  // expected-error {{expected ';' at end of declaration}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{expected body of lambda expression}}
+// expected-error {{expected '}'}}
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp 
b/clang/test/SemaCXX/lambda-expressions.cpp
index 23745dc14154747..269a1e1040ee96f 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -714,3 +714,7 @@ void foo() {
   // CHECK-NEXT: ConstantExpr
   // CHECK-NEXT: value: Int 2
 }
+
+void GH48527() {
+auto a = []()__attribute__((b(({ return 0; }{}; // expected-warning 
{{unknown attribute 'b' ignored}}
+}

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


[clang] [clang] Fix null dereference on return in lambda attribute statement expr (PR #66643)

2023-09-18 Thread Piotr Fusik via cfe-commits

https://github.com/pfusik updated 
https://github.com/llvm/llvm-project/pull/66643

>From b84e2a821a3121fa3597e710da341de66746bb46 Mon Sep 17 00:00:00 2001
From: Piotr Fusik 
Date: Mon, 18 Sep 2023 19:56:10 +0200
Subject: [PATCH] [clang] Fix null dereference on return in lambda attribute
 statement expr

clang was crashing on a lambda attribute with a statement expression
that contained a `return`.
It attempted to access the lambda type which was unknown at that point.

Fixes https://github.com/llvm/llvm-project/issues/48527
---
 clang/docs/ReleaseNotes.rst   |  4 
 clang/lib/Sema/SemaStmt.cpp   |  2 ++
 clang/test/Parser/gh48527.cpp | 10 ++
 clang/test/SemaCXX/lambda-expressions.cpp |  4 
 4 files changed, 20 insertions(+)
 create mode 100644 clang/test/Parser/gh48527.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 500f9c9a0cda741..c6f258991c85a79 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -291,6 +291,10 @@ Bug Fixes to C++ Support
   pointers on win32.
   (`#62594 `_)
 
+- Fix crash for a lambda attribute with a statement expression
+  that contains a `return`.
+  (`#48527 `_)
+
 Bug Fixes to AST Handling
 ^
 - Fixed an import failure of recursive friend class template.
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 7cc509542d5381d..10adfbc406dfbb5 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3577,6 +3577,8 @@ StmtResult Sema::ActOnCapScopeReturnStmt(SourceLocation 
ReturnLoc,
   CapturingScopeInfo *CurCap = cast(getCurFunction());
   QualType FnRetType = CurCap->ReturnType;
   LambdaScopeInfo *CurLambda = dyn_cast(CurCap);
+  if (CurLambda && CurLambda->CallOperator->getType().isNull())
+return StmtError();
   bool HasDeducedReturnType =
   CurLambda && hasDeducedReturnType(CurLambda->CallOperator);
 
diff --git a/clang/test/Parser/gh48527.cpp b/clang/test/Parser/gh48527.cpp
new file mode 100644
index 000..420c35be37f5191
--- /dev/null
+++ b/clang/test/Parser/gh48527.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int main() { // expected-note {{to match this '{'}}
+auto a = [](void)__attribute__((b(({ // expected-note {{to match this '('}}
+return 0;
+} // expected-error 3 {{expected ')'}} \
+  // expected-error {{expected ';' at end of declaration}}
+// expected-error@+2 {{expected ')'}}
+// expected-error@+1 {{expected body of lambda expression}}
+// expected-error {{expected '}'}}
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp 
b/clang/test/SemaCXX/lambda-expressions.cpp
index 23745dc14154747..0c9e8584e653473 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -714,3 +714,7 @@ void foo() {
   // CHECK-NEXT: ConstantExpr
   // CHECK-NEXT: value: Int 2
 }
+
+void GH48527() {
+  auto a = []()__attribute__((b(({ return 0; }{}; // expected-warning 
{{unknown attribute 'b' ignored}}
+}

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


[clang] [clang] Fix null dereference on return in lambda attribute statement expr (PR #66643)

2023-09-18 Thread via cfe-commits

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

LGTM, thanks!

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


[clang-tools-extra] [libc++] Prevent calling the projection more than three times (PR #66315)

2023-09-18 Thread Jocelyn Castellano via cfe-commits

https://github.com/pandaninjas updated 
https://github.com/llvm/llvm-project/pull/66315

>From ead65bfcb70be46788bc9e88c891e7ae7f91b8d7 Mon Sep 17 00:00:00 2001
From: PandaNinjas 
Date: Wed, 13 Sep 2023 17:38:17 -0700
Subject: [PATCH 01/16] [libc++] Prevent calling the projection more than three
 times

---
 libcxx/include/__algorithm/ranges_clamp.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 9613f7f37720a6c..ca46675eb4b3041 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,9 +37,10 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, 
__low)))
+auto &projection = std::invoke(__proj, __value);
+if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
-else if (std::invoke(__comp, std::invoke(__proj, __high), 
std::invoke(__proj, __value)))
+else if (std::invoke(__comp, std::invoke(__proj, __high), projection))
   return __high;
 else
   return __value;

>From c18d60870ac342a95a5528396a8e0c7b91717cbb Mon Sep 17 00:00:00 2001
From: PandaNinjas 
Date: Wed, 13 Sep 2023 18:56:44 -0700
Subject: [PATCH 02/16] [libc++] Run clang-format on file

---
 libcxx/include/__algorithm/ranges_clamp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index ca46675eb4b3041..3469a6419b2270f 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,7 +37,7 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-auto &projection = std::invoke(__proj, __value);
+auto& projection = std::invoke(__proj, __value);
 if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
 else if (std::invoke(__comp, std::invoke(__proj, __high), projection))

>From b40e791f0e9fedbb19936851e1e71decf00331fa Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Wed, 13 Sep 2023 19:11:20 -0700
Subject: [PATCH 03/16] [libcxx] CamelCase projection and make variable name
 more descriptive

---
 libcxx/include/__algorithm/ranges_clamp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3469a6419b2270f..3adb5fa828e1ee5 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,7 +37,7 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-auto& projection = std::invoke(__proj, __value);
+auto& ValueProjection = std::invoke(__proj, __value);
 if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
 else if (std::invoke(__comp, std::invoke(__proj, __high), projection))

>From a8907624defa4cc4f47520a2d93a8bd042816aa2 Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Wed, 13 Sep 2023 19:11:47 -0700
Subject: [PATCH 04/16] [libcxx] properly change variable name

---
 libcxx/include/__algorithm/ranges_clamp.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3adb5fa828e1ee5..3d7a224b3649a3f 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -38,9 +38,9 @@ struct __fn {
  "Bad bounds passed to std::ranges::clamp");
 
 auto& ValueProjection = std::invoke(__proj, __value);
-if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
+if (std::invoke(__comp, ValueProjection, std::invoke(__proj, __low)))
   return __low;
-else if (std::invoke(__comp, std::invoke(__proj, __high), projection))
+else if (std::invoke(__comp, std::invoke(__proj, __high), ValueProjection))
   return __high;
 else
   return __value;

>From 15d3b2b79fbd61f97b0312e0913cede36b5b202d Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Thu, 14 Sep 2023 10:37:34 -0700
Subject: [PATCH 05/16] Apply suggestions from code review

---
 libcxx/include/__algorithm/ranges_clamp.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3d7a224b3649a3f..

[clang] [libc++] Prevent calling the projection more than three times (PR #66315)

2023-09-18 Thread Jocelyn Castellano via cfe-commits

https://github.com/pandaninjas updated 
https://github.com/llvm/llvm-project/pull/66315

>From ead65bfcb70be46788bc9e88c891e7ae7f91b8d7 Mon Sep 17 00:00:00 2001
From: PandaNinjas 
Date: Wed, 13 Sep 2023 17:38:17 -0700
Subject: [PATCH 01/16] [libc++] Prevent calling the projection more than three
 times

---
 libcxx/include/__algorithm/ranges_clamp.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 9613f7f37720a6c..ca46675eb4b3041 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,9 +37,10 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, 
__low)))
+auto &projection = std::invoke(__proj, __value);
+if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
-else if (std::invoke(__comp, std::invoke(__proj, __high), 
std::invoke(__proj, __value)))
+else if (std::invoke(__comp, std::invoke(__proj, __high), projection))
   return __high;
 else
   return __value;

>From c18d60870ac342a95a5528396a8e0c7b91717cbb Mon Sep 17 00:00:00 2001
From: PandaNinjas 
Date: Wed, 13 Sep 2023 18:56:44 -0700
Subject: [PATCH 02/16] [libc++] Run clang-format on file

---
 libcxx/include/__algorithm/ranges_clamp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index ca46675eb4b3041..3469a6419b2270f 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,7 +37,7 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-auto &projection = std::invoke(__proj, __value);
+auto& projection = std::invoke(__proj, __value);
 if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
 else if (std::invoke(__comp, std::invoke(__proj, __high), projection))

>From b40e791f0e9fedbb19936851e1e71decf00331fa Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Wed, 13 Sep 2023 19:11:20 -0700
Subject: [PATCH 03/16] [libcxx] CamelCase projection and make variable name
 more descriptive

---
 libcxx/include/__algorithm/ranges_clamp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3469a6419b2270f..3adb5fa828e1ee5 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -37,7 +37,7 @@ struct __fn {
 _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, 
__high), std::invoke(__proj, __low))),
  "Bad bounds passed to std::ranges::clamp");
 
-auto& projection = std::invoke(__proj, __value);
+auto& ValueProjection = std::invoke(__proj, __value);
 if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
   return __low;
 else if (std::invoke(__comp, std::invoke(__proj, __high), projection))

>From a8907624defa4cc4f47520a2d93a8bd042816aa2 Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Wed, 13 Sep 2023 19:11:47 -0700
Subject: [PATCH 04/16] [libcxx] properly change variable name

---
 libcxx/include/__algorithm/ranges_clamp.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3adb5fa828e1ee5..3d7a224b3649a3f 100644
--- a/libcxx/include/__algorithm/ranges_clamp.h
+++ b/libcxx/include/__algorithm/ranges_clamp.h
@@ -38,9 +38,9 @@ struct __fn {
  "Bad bounds passed to std::ranges::clamp");
 
 auto& ValueProjection = std::invoke(__proj, __value);
-if (std::invoke(__comp, projection, std::invoke(__proj, __low)))
+if (std::invoke(__comp, ValueProjection, std::invoke(__proj, __low)))
   return __low;
-else if (std::invoke(__comp, std::invoke(__proj, __high), projection))
+else if (std::invoke(__comp, std::invoke(__proj, __high), ValueProjection))
   return __high;
 else
   return __value;

>From 15d3b2b79fbd61f97b0312e0913cede36b5b202d Mon Sep 17 00:00:00 2001
From: Jocelyn Castellano 
Date: Thu, 14 Sep 2023 10:37:34 -0700
Subject: [PATCH 05/16] Apply suggestions from code review

---
 libcxx/include/__algorithm/ranges_clamp.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libcxx/include/__algorithm/ranges_clamp.h 
b/libcxx/include/__algorithm/ranges_clamp.h
index 3d7a224b3649a3f..

[clang] [DependencyScanningFilesystem] Make sure the local/shared cache filename lookups use only absolute paths (PR #66122)

2023-09-18 Thread Argyrios Kyrtzidis via cfe-commits

https://github.com/akyrtzi updated 
https://github.com/llvm/llvm-project/pull/66122

>From 5794986079f3eb0f52dd6089d50d994b4559ed06 Mon Sep 17 00:00:00 2001
From: Argyrios Kyrtzidis 
Date: Tue, 12 Sep 2023 11:26:46 -0700
Subject: [PATCH] [DependencyScanningFilesystem] Make sure the local/shared
 cache filename lookups use only absolute paths

Previously a relative path would be used as a key for cache lookup and if the 
same relative path
was used from another compiler invocation with a different working directory 
then the first cache entry
was erroneously returned.
---
 .../DependencyScanningFilesystem.h| 18 -
 .../DependencyScanningFilesystem.cpp  | 80 +++
 clang/test/ClangScanDeps/relative-filenames.c | 38 +
 3 files changed, 118 insertions(+), 18 deletions(-)
 create mode 100644 clang/test/ClangScanDeps/relative-filenames.c

diff --git 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
index 4b4e3c7eb2ecd06..dbe219b6dd8d723 100644
--- 
a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
+++ 
b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h
@@ -215,6 +215,7 @@ class DependencyScanningFilesystemLocalCache {
 public:
   /// Returns entry associated with the filename or nullptr if none is found.
   const CachedFileSystemEntry *findEntryByFilename(StringRef Filename) const {
+assert(llvm::sys::path::is_absolute_gnu(Filename));
 auto It = Cache.find(Filename);
 return It == Cache.end() ? nullptr : It->getValue();
   }
@@ -224,6 +225,7 @@ class DependencyScanningFilesystemLocalCache {
   const CachedFileSystemEntry &
   insertEntryForFilename(StringRef Filename,
  const CachedFileSystemEntry &Entry) {
+assert(llvm::sys::path::is_absolute_gnu(Filename));
 const auto *InsertedEntry = Cache.insert({Filename, &Entry}).first->second;
 assert(InsertedEntry == &Entry && "entry already present");
 return *InsertedEntry;
@@ -282,13 +284,14 @@ class DependencyScanningWorkerFilesystem : public 
llvm::vfs::ProxyFileSystem {
 public:
   DependencyScanningWorkerFilesystem(
   DependencyScanningFilesystemSharedCache &SharedCache,
-  IntrusiveRefCntPtr FS)
-  : ProxyFileSystem(std::move(FS)), SharedCache(SharedCache) {}
+  IntrusiveRefCntPtr FS);
 
   llvm::ErrorOr status(const Twine &Path) override;
   llvm::ErrorOr>
   openFileForRead(const Twine &Path) override;
 
+  std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
+
   /// Returns entry for the given filename.
   ///
   /// Attempts to use the local and shared caches first, then falls back to
@@ -304,8 +307,11 @@ class DependencyScanningWorkerFilesystem : public 
llvm::vfs::ProxyFileSystem {
   /// For a filename that's not yet associated with any entry in the caches,
   /// uses the underlying filesystem to either look up the entry based in the
   /// shared cache indexed by unique ID, or creates new entry from scratch.
+  /// \p FilenameForLookup will always be an absolute path, and different than
+  /// \p OriginalFilename if \p OriginalFilename is relative.
   llvm::ErrorOr
-  computeAndStoreResult(StringRef Filename);
+  computeAndStoreResult(StringRef OriginalFilename,
+StringRef FilenameForLookup);
 
   /// Scan for preprocessor directives for the given entry if necessary and
   /// returns a wrapper object with reference semantics.
@@ -388,6 +394,12 @@ class DependencyScanningWorkerFilesystem : public 
llvm::vfs::ProxyFileSystem {
   /// The local cache is used by the worker thread to cache file system queries
   /// locally instead of querying the global cache every time.
   DependencyScanningFilesystemLocalCache LocalCache;
+
+  /// The working directory to use for making relative paths absolute before
+  /// using them for cache lookups.
+  llvm::ErrorOr WorkingDirForCacheLookup;
+
+  void updateWorkingDirForCacheLookup();
 };
 
 } // end namespace dependencies
diff --git 
a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp 
b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
index 31404855e3b1dc3..e2c404206170ee9 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp
@@ -96,6 +96,7 @@ DependencyScanningFilesystemSharedCache::
 DependencyScanningFilesystemSharedCache::CacheShard &
 DependencyScanningFilesystemSharedCache::getShardForFilename(
 StringRef Filename) const {
+  assert(llvm::sys::path::is_absolute_gnu(Filename));
   return CacheShards[llvm::hash_value(Filename) % NumShards];
 }
 
@@ -109,6 +110,7 @@ DependencyScanningFilesystemSharedCache::getShardForUID(
 const CachedFileSystemEntry *
 DependencyScanningFilesystemSharedCache::CacheShard::findEntryByFilename(
 StringRef 

[clang] [DependencyScanningFilesystem] Make sure the local/shared cache filename lookups use only absolute paths (PR #66122)

2023-09-18 Thread Argyrios Kyrtzidis via cfe-commits


@@ -330,3 +353,20 @@ DependencyScanningWorkerFilesystem::openFileForRead(const 
Twine &Path) {
 return Result.getError();
   return DepScanFile::create(Result.get());
 }
+
+std::error_code DependencyScanningWorkerFilesystem::setCurrentWorkingDirectory(
+const Twine &Path) {
+  updateWorkingDirForCacheLookup(Path.str());
+  return ProxyFileSystem::setCurrentWorkingDirectory(Path);
+}
+
+void DependencyScanningWorkerFilesystem::updateWorkingDirForCacheLookup(
+llvm::ErrorOr CWD) {
+  if (CWD && !CWD->empty()) {
+WorkingDirForCacheLookup = *CWD;
+  } else {
+// The cache lookup functions will not accept relative paths for safety, so
+// at least make it absolute from a "root".
+WorkingDirForCacheLookup = "/";

akyrtzi wrote:

See latest commit, I've changed it so it became `llvm::ErrorOr 
WorkingDirForCacheLookup` and 
`DependencyScanningWorkerFilesystem::getOrCreateFileSystemEntry()` errors out 
if it needs to use `WorkingDirForCacheLookup` and it's erroneous.

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


[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread David Blaikie via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZ

[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread David Blaikie via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZ

[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread David Blaikie via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {

dwblaikie wrote:

I'd probably omit `at` and just provide `op[]`? `at()` implies "throws if out 
of bounds" but LLVM doesn't use exceptions, so that seems at odds with each 
other.

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


[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread David Blaikie via cfe-commits


@@ -7944,9 +7944,13 @@ void ASTReader::PrintStats() {
   std::fprintf(stderr, "*** AST File Statistics:\n");
 
   unsigned NumTypesLoaded =
-  TypesLoaded.size() - llvm::count(TypesLoaded, QualType());
+  TypesLoaded.size() - std::count(TypesLoaded.materialisedBegin(),

dwblaikie wrote:

This seems confusing - I'd have thought any materialised type was a loaded 
type? So `NumTypesLoaded = std::count(TypesLoaded.materialisedBegin(), 
TypesLoaded.materialisedEnd())`?

(similarly for `DeclsLoaded` below)

Like wouldn't this result in `NumTypesLoaded` too high - for unmaterialized 
values they're all assumed to be loaded? Which sounds backwards.

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


[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread David Blaikie via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {

dwblaikie wrote:

Should this be called `resize` (I see a bunch of places that rename `resize` 
calls to `expand` calls, so it sounds like it's meant to have similar/matching 
semantics)

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


[clang] Introduce paged vector (PR #66430)

2023-09-18 Thread David Blaikie via cfe-commits


@@ -0,0 +1,301 @@
+//===- llvm/ADT/PagedVector.h - 'Lazyly allocated' vectors *- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines the PagedVector class.
+//
+//===--===//
+#ifndef LLVM_ADT_PAGEDVECTOR_H
+#define LLVM_ADT_PAGEDVECTOR_H
+
+#include "llvm/Support/Allocator.h"
+#include 
+#include 
+#include 
+
+namespace llvm {
+// A vector that allocates memory in pages.
+// Order is kept, but memory is allocated only when one element of the page is
+// accessed. This introduces a level of indirection, but it is useful when you
+// have a sparsely initialised vector where the full size is allocated upfront
+// with the default constructor and elements are initialised later, on first
+// access.
+//
+// Notice that this does not have iterators, because if you
+// have iterators it probably means you are going to touch
+// all the memory in any case, so better use a std::vector in
+// the first place.
+//
+// Pages are allocated in SLAB_SIZE chunks, using the BumpPtrAllocator.
+template 
+class PagedVector {
+  static_assert(PAGE_SIZE > 0, "PAGE_SIZE must be greater than 0. Most likely "
+   "you want it to be greater than 16.");
+  // The actual number of element in the vector which can be accessed.
+  std::size_t Size = 0;
+
+  // The position of the initial element of the page in the Data vector.
+  // Pages are allocated contiguously in the Data vector.
+  mutable std::vector PageToDataIdx;
+  // Actual page data. All the page elements are added to this vector on the
+  // first access of any of the elements of the page. Elements default
+  // constructed and elements of the page are stored contiguously. The order of
+  // the elements however depends on the order of access of the pages.
+  uintptr_t Allocator = 0;
+
+  constexpr static T *invalidPage() { return reinterpret_cast(SIZE_MAX); }
+
+public:
+  // Default constructor. We build our own allocator.
+  PagedVector()
+  : Allocator(reinterpret_cast(new BumpPtrAllocator) | 0x1) {}
+  PagedVector(BumpPtrAllocator *A)
+  : Allocator(reinterpret_cast(A)) {}
+
+  ~PagedVector() {
+// If we own the allocator, delete it.
+if (Allocator & 0x1) {
+  delete getAllocator();
+}
+  }
+
+  // Get the allocator.
+  BumpPtrAllocator *getAllocator() const {
+return reinterpret_cast(Allocator & ~0x1);
+  }
+  // Lookup an element at position Index.
+  T &operator[](std::size_t Index) const { return at(Index); }
+
+  // Lookup an element at position i.
+  // If the associated page is not filled, it will be filled with default
+  // constructed elements. If the associated page is filled, return the 
element.
+  T &at(std::size_t Index) const {
+assert(Index < Size);
+assert(Index / PAGE_SIZE < PageToDataIdx.size());
+auto *&PagePtr = PageToDataIdx[Index / PAGE_SIZE];
+// If the page was not yet allocated, allocate it.
+if (PagePtr == invalidPage()) {
+  PagePtr = getAllocator()->template Allocate(PAGE_SIZE);
+  // We need to invoke the default constructor on all the elements of the
+  // page.
+  for (std::size_t I = 0; I < PAGE_SIZE; ++I) {
+new (PagePtr + I) T();
+  }
+}
+// Dereference the element in the page.
+return *((Index % PAGE_SIZE) + PagePtr);
+  }
+
+  // Return the capacity of the vector. I.e. the maximum size it can be 
expanded
+  // to with the expand method without allocating more pages.
+  std::size_t capacity() const { return PageToDataIdx.size() * PAGE_SIZE; }
+
+  // Return the size of the vector. I.e. the maximum index that can be
+  // accessed, i.e. the maximum value which was used as argument of the
+  // expand method.
+  std::size_t size() const { return Size; }
+
+  // Expands the vector to the given NewSize number of elements.
+  // If the vector was smaller, allocates new pages as needed.
+  // It should be called only with NewSize >= Size.
+  void expand(std::size_t NewSize) {
+// You cannot shrink the vector, otherwise
+// one would have to invalidate contents which is expensive and
+// while giving the false hope that the resize is cheap.
+if (NewSize <= Size) {
+  return;
+}
+// If the capacity is enough, just update the size and continue
+// with the currently allocated pages.
+if (NewSize <= capacity()) {
+  Size = NewSize;
+  return;
+}
+// The number of pages to allocate. The Remainder is calculated
+// for the case in which the NewSize is not a multiple of PAGE_SIZE.
+// In that case we need one more page.
+auto Pages = NewSize / PAGE_SIZE;
+auto Remainder = NewSize % PAGE_SIZ

[clang] [LLVM] Add new attribute `optdebug` to optimize for debugging (PR #66632)

2023-09-18 Thread David Blaikie via cfe-commits


@@ -2325,6 +2325,7 @@ void 
CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
   B.addAttribute(llvm::Attribute::Naked);
 
 // OptimizeNone wins over OptimizeForSize and MinSize.
+F->removeFnAttr(llvm::Attribute::OptimizeForDebugging);

dwblaikie wrote:

+1, and otherwise the change makes sense to me. Could you post about this on 
Discourse, pointing to this pull request - just to make sure folks are aware 
we're adding a new IR attribute here? Be good to ensure there's consensus. 

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


[clang] [RISCV] Added definition of Ventana veyron-v1 processor. (PR #65535)

2023-09-18 Thread via cfe-commits

https://github.com/mgudim updated 
https://github.com/llvm/llvm-project/pull/65535

>From d1ba27988840703b9a7a12ad48ecfb282752e7e2 Mon Sep 17 00:00:00 2001
From: Mikhail Gudim 
Date: Wed, 6 Sep 2023 17:15:56 -0400
Subject: [PATCH 1/2] [RISCV] Added definition of Ventana veyron-v1 processor.

---
 clang/test/Driver/riscv-cpus.c| 25 +++
 clang/test/Misc/target-invalid-cpu-note.c |  2 +-
 llvm/lib/Target/RISCV/RISCVProcessors.td  | 22 
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
index bd8488d81c0b156..3eaceedce685fc6 100644
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -37,6 +37,31 @@
 // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=syntacore-scr1-max | 
FileCheck -check-prefix=MTUNE-SYNTACORE-SCR1-MAX %s
 // MTUNE-SYNTACORE-SCR1-MAX: "-tune-cpu" "syntacore-scr1-max"
 
+// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=veyron-v1 | FileCheck 
-check-prefix=MCPU-VEYRON-V1 %s
+// MCPU-VEYRON-V1: "-target-cpu" "veyron-v1"
+// MCPU-VEYRON-V1: "-target-feature" "+m"
+// MCPU-VEYRON-V1: "-target-feature" "+a"
+// MCPU-VEYRON-V1: "-target-feature" "+f"
+// MCPU-VEYRON-V1: "-target-feature" "+d"
+// MCPU-VEYRON-V1: "-target-feature" "+c"
+// MCPU-VEYRON-V1: "-target-feature" "+zicbom"
+// MCPU-VEYRON-V1: "-target-feature" "+zicbop"
+// MCPU-VEYRON-V1: "-target-feature" "+zicboz"
+// MCPU-VEYRON-V1: "-target-feature" "+zicntr"
+// MCPU-VEYRON-V1: "-target-feature" "+zicsr"
+// MCPU-VEYRON-V1: "-target-feature" "+zifencei"
+// MCPU-VEYRON-V1: "-target-feature" "+zihintpause"
+// MCPU-VEYRON-V1: "-target-feature" "+zihpm"
+// MCPU-VEYRON-V1: "-target-feature" "+zba"
+// MCPU-VEYRON-V1: "-target-feature" "+zbb"
+// MCPU-VEYRON-V1: "-target-feature" "+zbc"
+// MCPU-VEYRON-V1: "-target-feature" "+zbs"
+// MCPU-VEYRON-V1: "-target-feature" "+xventanacondops"
+// MCPU-VEYRON-V1: "-target-abi" "lp64d"
+
+// 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"
+
 // 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 c44bd6087af4132..871ac090fedba27 100644
--- a/clang/test/Misc/target-invalid-cpu-note.c
+++ b/clang/test/Misc/target-invalid-cpu-note.c
@@ -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, 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, generic, rocket, sifive-7-series, veyron-v1{{$}}
diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td 
b/llvm/lib/Target/RISCV/RISCVProcessors.td
index 01291001cd7ca24..402ec20fe39ab1c 100644
--- a/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -201,3 +201,25 @@ def SYNTACORE_SCR1_MAX : 
RISCVProcessorModel<"syntacore-scr1-max",
   FeatureStdExtM,
   FeatureStdExtC],
  [TuneNoDefaultUnroll]>;
+
+def VENTANA_VEYRON_V1 : RISCVProcessorModel<"veyron-v1",
+NoSchedModel,
+[Feature64Bit,
+ FeatureStdExtZifencei,
+ FeatureStdExtZicsr,
+ FeatureStdExtZicntr,
+ FeatureStdExtZihpm,
+ FeatureStdExtZihintpause,
+ FeatureStdExtM,
+ FeatureStdExtA,
+ FeatureStdExtF,
+ FeatureStdExtD,
+ FeatureStdExtC,
+ FeatureStdExtZba,
+ FeatureStdExtZbb,
+ FeatureStdExtZbc,
+ FeatureStdExtZbs,
+ FeatureStdExtZicbom,
+ FeatureStdExtZicbop,
+ 

[clang] [RISCV] Added definition of Ventana veyron-v1 processor. (PR #65535)

2023-09-18 Thread via cfe-commits

https://github.com/mgudim updated 
https://github.com/llvm/llvm-project/pull/65535

>From d1ba27988840703b9a7a12ad48ecfb282752e7e2 Mon Sep 17 00:00:00 2001
From: Mikhail Gudim 
Date: Wed, 6 Sep 2023 17:15:56 -0400
Subject: [PATCH 1/2] [RISCV] Added definition of Ventana veyron-v1 processor.

---
 clang/test/Driver/riscv-cpus.c| 25 +++
 clang/test/Misc/target-invalid-cpu-note.c |  2 +-
 llvm/lib/Target/RISCV/RISCVProcessors.td  | 22 
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
index bd8488d81c0b156..3eaceedce685fc6 100644
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -37,6 +37,31 @@
 // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=syntacore-scr1-max | 
FileCheck -check-prefix=MTUNE-SYNTACORE-SCR1-MAX %s
 // MTUNE-SYNTACORE-SCR1-MAX: "-tune-cpu" "syntacore-scr1-max"
 
+// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=veyron-v1 | FileCheck 
-check-prefix=MCPU-VEYRON-V1 %s
+// MCPU-VEYRON-V1: "-target-cpu" "veyron-v1"
+// MCPU-VEYRON-V1: "-target-feature" "+m"
+// MCPU-VEYRON-V1: "-target-feature" "+a"
+// MCPU-VEYRON-V1: "-target-feature" "+f"
+// MCPU-VEYRON-V1: "-target-feature" "+d"
+// MCPU-VEYRON-V1: "-target-feature" "+c"
+// MCPU-VEYRON-V1: "-target-feature" "+zicbom"
+// MCPU-VEYRON-V1: "-target-feature" "+zicbop"
+// MCPU-VEYRON-V1: "-target-feature" "+zicboz"
+// MCPU-VEYRON-V1: "-target-feature" "+zicntr"
+// MCPU-VEYRON-V1: "-target-feature" "+zicsr"
+// MCPU-VEYRON-V1: "-target-feature" "+zifencei"
+// MCPU-VEYRON-V1: "-target-feature" "+zihintpause"
+// MCPU-VEYRON-V1: "-target-feature" "+zihpm"
+// MCPU-VEYRON-V1: "-target-feature" "+zba"
+// MCPU-VEYRON-V1: "-target-feature" "+zbb"
+// MCPU-VEYRON-V1: "-target-feature" "+zbc"
+// MCPU-VEYRON-V1: "-target-feature" "+zbs"
+// MCPU-VEYRON-V1: "-target-feature" "+xventanacondops"
+// MCPU-VEYRON-V1: "-target-abi" "lp64d"
+
+// 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"
+
 // 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 c44bd6087af4132..871ac090fedba27 100644
--- a/clang/test/Misc/target-invalid-cpu-note.c
+++ b/clang/test/Misc/target-invalid-cpu-note.c
@@ -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, 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, generic, rocket, sifive-7-series, veyron-v1{{$}}
diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td 
b/llvm/lib/Target/RISCV/RISCVProcessors.td
index 01291001cd7ca24..402ec20fe39ab1c 100644
--- a/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -201,3 +201,25 @@ def SYNTACORE_SCR1_MAX : 
RISCVProcessorModel<"syntacore-scr1-max",
   FeatureStdExtM,
   FeatureStdExtC],
  [TuneNoDefaultUnroll]>;
+
+def VENTANA_VEYRON_V1 : RISCVProcessorModel<"veyron-v1",
+NoSchedModel,
+[Feature64Bit,
+ FeatureStdExtZifencei,
+ FeatureStdExtZicsr,
+ FeatureStdExtZicntr,
+ FeatureStdExtZihpm,
+ FeatureStdExtZihintpause,
+ FeatureStdExtM,
+ FeatureStdExtA,
+ FeatureStdExtF,
+ FeatureStdExtD,
+ FeatureStdExtC,
+ FeatureStdExtZba,
+ FeatureStdExtZbb,
+ FeatureStdExtZbc,
+ FeatureStdExtZbs,
+ FeatureStdExtZicbom,
+ FeatureStdExtZicbop,
+ 

[clang-tools-extra] [RISCV] Added definition of Ventana veyron-v1 processor. (PR #65535)

2023-09-18 Thread via cfe-commits

https://github.com/mgudim updated 
https://github.com/llvm/llvm-project/pull/65535

>From d1ba27988840703b9a7a12ad48ecfb282752e7e2 Mon Sep 17 00:00:00 2001
From: Mikhail Gudim 
Date: Wed, 6 Sep 2023 17:15:56 -0400
Subject: [PATCH 1/2] [RISCV] Added definition of Ventana veyron-v1 processor.

---
 clang/test/Driver/riscv-cpus.c| 25 +++
 clang/test/Misc/target-invalid-cpu-note.c |  2 +-
 llvm/lib/Target/RISCV/RISCVProcessors.td  | 22 
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c
index bd8488d81c0b156..3eaceedce685fc6 100644
--- a/clang/test/Driver/riscv-cpus.c
+++ b/clang/test/Driver/riscv-cpus.c
@@ -37,6 +37,31 @@
 // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=syntacore-scr1-max | 
FileCheck -check-prefix=MTUNE-SYNTACORE-SCR1-MAX %s
 // MTUNE-SYNTACORE-SCR1-MAX: "-tune-cpu" "syntacore-scr1-max"
 
+// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=veyron-v1 | FileCheck 
-check-prefix=MCPU-VEYRON-V1 %s
+// MCPU-VEYRON-V1: "-target-cpu" "veyron-v1"
+// MCPU-VEYRON-V1: "-target-feature" "+m"
+// MCPU-VEYRON-V1: "-target-feature" "+a"
+// MCPU-VEYRON-V1: "-target-feature" "+f"
+// MCPU-VEYRON-V1: "-target-feature" "+d"
+// MCPU-VEYRON-V1: "-target-feature" "+c"
+// MCPU-VEYRON-V1: "-target-feature" "+zicbom"
+// MCPU-VEYRON-V1: "-target-feature" "+zicbop"
+// MCPU-VEYRON-V1: "-target-feature" "+zicboz"
+// MCPU-VEYRON-V1: "-target-feature" "+zicntr"
+// MCPU-VEYRON-V1: "-target-feature" "+zicsr"
+// MCPU-VEYRON-V1: "-target-feature" "+zifencei"
+// MCPU-VEYRON-V1: "-target-feature" "+zihintpause"
+// MCPU-VEYRON-V1: "-target-feature" "+zihpm"
+// MCPU-VEYRON-V1: "-target-feature" "+zba"
+// MCPU-VEYRON-V1: "-target-feature" "+zbb"
+// MCPU-VEYRON-V1: "-target-feature" "+zbc"
+// MCPU-VEYRON-V1: "-target-feature" "+zbs"
+// MCPU-VEYRON-V1: "-target-feature" "+xventanacondops"
+// MCPU-VEYRON-V1: "-target-abi" "lp64d"
+
+// 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"
+
 // 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 c44bd6087af4132..871ac090fedba27 100644
--- a/clang/test/Misc/target-invalid-cpu-note.c
+++ b/clang/test/Misc/target-invalid-cpu-note.c
@@ -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, 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, generic, rocket, sifive-7-series, veyron-v1{{$}}
diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td 
b/llvm/lib/Target/RISCV/RISCVProcessors.td
index 01291001cd7ca24..402ec20fe39ab1c 100644
--- a/llvm/lib/Target/RISCV/RISCVProcessors.td
+++ b/llvm/lib/Target/RISCV/RISCVProcessors.td
@@ -201,3 +201,25 @@ def SYNTACORE_SCR1_MAX : 
RISCVProcessorModel<"syntacore-scr1-max",
   FeatureStdExtM,
   FeatureStdExtC],
  [TuneNoDefaultUnroll]>;
+
+def VENTANA_VEYRON_V1 : RISCVProcessorModel<"veyron-v1",
+NoSchedModel,
+[Feature64Bit,
+ FeatureStdExtZifencei,
+ FeatureStdExtZicsr,
+ FeatureStdExtZicntr,
+ FeatureStdExtZihpm,
+ FeatureStdExtZihintpause,
+ FeatureStdExtM,
+ FeatureStdExtA,
+ FeatureStdExtF,
+ FeatureStdExtD,
+ FeatureStdExtC,
+ FeatureStdExtZba,
+ FeatureStdExtZbb,
+ FeatureStdExtZbc,
+ FeatureStdExtZbs,
+ FeatureStdExtZicbom,
+ FeatureStdExtZicbop,
+ 

[clang] In ExprRequirement building, treat OverloadExpr as dependent (PR #66683)

2023-09-18 Thread Erich Keane via cfe-commits

https://github.com/erichkeane created 
https://github.com/llvm/llvm-project/pull/66683

As reported in #66612, we aren't correctly treating the placeholder expression 
type correctly, so we ended up trying to get a reference version of it, and 
this resulted in an assertion, since the placeholder type cannot have a 
reference added.

Fixes: #66612

>From 5b4748e3ae06a5b90ecb2c84b7df989a94733175 Mon Sep 17 00:00:00 2001
From: erichkeane 
Date: Mon, 18 Sep 2023 11:38:12 -0700
Subject: [PATCH] In ExprRequirement building, treat OverloadExpr as dependent

As reported in #66612, we aren't correctly treating the placeholder
expression type correctly, so we ended up trying to get a reference
version of it, and this resulted in an assertion, since the placeholder
type cannot have a reference added.

Fixes: #66612
---
 clang/lib/Sema/SemaExprCXX.cpp   |  3 ++-
 clang/test/SemaTemplate/concepts.cpp | 17 +
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index bb4ef065d5c72aa..77289595972e3cf 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -9063,7 +9063,8 @@ Sema::BuildExprRequirement(
 concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {
   auto Status = concepts::ExprRequirement::SS_Satisfied;
   ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
-  if (E->isInstantiationDependent() || ReturnTypeRequirement.isDependent())
+  if (E->isInstantiationDependent() || E->getType()->isPlaceholderType() ||
+  ReturnTypeRequirement.isDependent())
 Status = concepts::ExprRequirement::SS_Dependent;
   else if (NoexceptLoc.isValid() && canThrow(E) == CanThrowResult::CT_Can)
 Status = concepts::ExprRequirement::SS_NoexceptNotMet;
diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index 891b45aa5789296..68050e0f09e248a 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1031,3 +1031,20 @@ void test() {
 fff(42UL); // expected-error {{no matching function}}
 }
 }
+
+namespace GH66612 {
+  template
+auto end(C c) ->int;
+
+  template 
+concept Iterator = true;
+
+  template 
+concept Container = requires(CT b) {
+{ end } -> Iterator; // #66612GH_END
+};
+
+  static_assert(Container);// expected-error{{static assertion failed}}
+  // expected-note@-1{{because 'int' does not satisfy 'Container'}}
+  // expected-note@#66612GH_END{{because 'end' would be invalid: reference to 
overloaded function could not be resolved; did you mean to call it?}}
+}

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


[clang] In ExprRequirement building, treat OverloadExpr as dependent (PR #66683)

2023-09-18 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang


Changes

As reported in #66612, we aren't correctly treating the placeholder 
expression type correctly, so we ended up trying to get a reference version of 
it, and this resulted in an assertion, since the placeholder type cannot have a 
reference added.

Fixes: #66612

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


2 Files Affected:

- (modified) clang/lib/Sema/SemaExprCXX.cpp (+2-1) 
- (modified) clang/test/SemaTemplate/concepts.cpp (+17) 


``diff
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index bb4ef065d5c72aa..77289595972e3cf 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -9063,7 +9063,8 @@ Sema::BuildExprRequirement(
 concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {
   auto Status = concepts::ExprRequirement::SS_Satisfied;
   ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
-  if (E->isInstantiationDependent() || ReturnTypeRequirement.isDependent())
+  if (E->isInstantiationDependent() || E->getType()->isPlaceholderType() ||
+  ReturnTypeRequirement.isDependent())
 Status = concepts::ExprRequirement::SS_Dependent;
   else if (NoexceptLoc.isValid() && canThrow(E) == CanThrowResult::CT_Can)
 Status = concepts::ExprRequirement::SS_NoexceptNotMet;
diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index 891b45aa5789296..68050e0f09e248a 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1031,3 +1031,20 @@ void test() {
 fff(42UL); // expected-error {{no matching function}}
 }
 }
+
+namespace GH66612 {
+  template
+auto end(C c) ->int;
+
+  template 
+concept Iterator = true;
+
+  template 
+concept Container = requires(CT b) {
+{ end } -> Iterator; // #66612GH_END
+};
+
+  static_assert(Container);// expected-error{{static assertion failed}}
+  // expected-note@-1{{because 'int' does not satisfy 'Container'}}
+  // expected-note@#66612GH_END{{because 'end' would be invalid: reference to 
overloaded function could not be resolved; did you mean to call it?}}
+}

``




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


[clang] In ExprRequirement building, treat OverloadExpr as dependent (PR #66683)

2023-09-18 Thread Erich Keane via cfe-commits


@@ -9063,7 +9063,8 @@ Sema::BuildExprRequirement(
 concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement) {
   auto Status = concepts::ExprRequirement::SS_Satisfied;
   ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
-  if (E->isInstantiationDependent() || ReturnTypeRequirement.isDependent())
+  if (E->isInstantiationDependent() || E->getType()->isPlaceholderType() ||
+  ReturnTypeRequirement.isDependent())

erichkeane wrote:

This makes sense in my head, as what is currently an unresolved overload 
expr(or other overload expr) could potentially become legal after instantiation 
I think?  So this should result in this being instantiated later/checked for 
correctness then.

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


[PATCH] D158730: [DebugMetadata][DwarfDebug] Don't retain local types with -fno-eliminate-unused-debug-types

2023-09-18 Thread David Blaikie via Phabricator via cfe-commits
dblaikie accepted this revision.
dblaikie added a comment.

Nice and easy


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D158730

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


[clang-tools-extra] [RISCV] Added definition of Ventana veyron-v1 processor. (PR #65535)

2023-09-18 Thread Michael Maitland via cfe-commits

michaelmaitland wrote:

> [Merge branch 'llvm:main' into 
> mgudim_veyron_def](https://github.com/llvm/llvm-project/pull/65535/commits/454b41eea50a3583ab5c29bffbd46bcd633b)

The [LLVM GitHub User Guide](https://llvm.org/docs//GitHub.html) recommends to 
rebase on main instead of merge main.

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


[clang] [RISCV] Added definition of Ventana veyron-v1 processor. (PR #65535)

2023-09-18 Thread via cfe-commits

mgudim wrote:

> > [Merge branch 'llvm:main' into 
> > mgudim_veyron_def](https://github.com/llvm/llvm-project/pull/65535/commits/454b41eea50a3583ab5c29bffbd46bcd633b)
> 
> The [LLVM GitHub User Guide](https://llvm.org/docs//GitHub.html) recommends 
> to rebase on main instead of merge main.

Yes, my bad. Still learning the new workflow. I go this merge commit after 
pressing the "sync" button on my fork. Is there a way to fix this now?

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


[clang-tools-extra] [RISCV] Added definition of Ventana veyron-v1 processor. (PR #65535)

2023-09-18 Thread Michael Maitland via cfe-commits

michaelmaitland wrote:

> Is there a way to fix this now?

I think you can drop the merge commit using `git rebase -i`. You may have to 
pass `--rebase-merges` to have the ability to drop the merge commit. Then you 
can pull upstream and `git rebase upstream/main`.

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


[clang] Support target names with dots in more utilities (PR #65812)

2023-09-18 Thread via cfe-commits


@@ -5,11 +5,14 @@
 # RUN: mkdir %t
 # RUN: ln -s llvm-ranlib %t/llvm-ranlib-9
 # RUN: ln -s llvm-ranlib %t/ranlib.exe
+# RUN: ln -s llvm-ranlib %t/x86_64-unknown-freebsd13.2-llvm-ranlib

dankm wrote:

Yep, your second point is why I didn't bother making the second case for 
llvm-ranlib. On my first pass I just updated the existing testcases I found, 
but for ranlib I realised the same thing you did. I may just drop the ranlib 
test entirely.

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


[clang] b1e3cd1 - [driver] Conditionally include installed libc++ headers for Android

2023-09-18 Thread Shoaib Meenai via cfe-commits

Author: Shoaib Meenai
Date: 2023-09-18T12:18:45-07:00
New Revision: b1e3cd1d79443603dc003441e07cdd8d30bb7f26

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

LOG: [driver] Conditionally include installed libc++ headers for Android

https://reviews.llvm.org/D71154 prevented Clang from search for libc++
headers installed alongside the driver when targeting Android. The
motivation was the NDK's use of a different libc++ inline namespace
(`__ndk1` instead of the standard `__1`), which made regular libc++
headers incompatible with the NDK's libc++ library.

Since then, libc++ has gained the ability to install its `__config_site`
header (which controls the inline namespace, among other things) to a
per-target include directory, which enables per-target customizations.
If this directory is present, the user has expressly built libc++ for
Android, and we should use those headers.

The motivation is that, with the current setup, if a user builds their
own libc++ for Android, they'll use the library they built themselves
but the NDK's headers instead of their own, which is surprising at best
and can cause all sorts of problems (e.g. if you built your own libc++
with a different ABI configuration). It's important to match the headers
and libraries in that scenario, and checking for an Android per-target
include directory lets us do so without regressing the original scenario
which https://reviews.llvm.org/D71154 was addressing.

While I'm here, switch to using sys::path::append instead of slashes
directly, to get system path separators on Windows, which is consistent
with how library paths are constructed (and that consistency will be
important in a follow-up, where we use a common search function for the
include and library path construction).

(As an aside, one of the motivations for https://reviews.llvm.org/D71154
was to support targeting both Android and Apple platforms, which
expected libc++ headers to be provided by the toolcain at the time.
Apple has since switched to including libc++ headers in the platform SDK
instead of in the toolchain, so that specific motivation no longer
applies either.)

Reviewed By: phosek

Differential Revision: https://reviews.llvm.org/D159292

Added: 
clang/test/Driver/android-installed-libcxx.cpp

Modified: 
clang/lib/Driver/ToolChains/Gnu.cpp
clang/test/Driver/android-ndk-standalone.cpp
clang/test/Driver/linux-header-search.cpp
clang/test/Driver/linux-musl-header-search.cpp
clang/test/Driver/linux-per-target-runtime-dir.c

Removed: 
clang/test/Driver/android-no-installed-libcxx.cpp



diff  --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index 7aeb8e29ebc5574..aa27584e2ebcc06 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -3102,32 +3102,44 @@ Generic_GCC::addLibCxxIncludePaths(const 
llvm::opt::ArgList &DriverArgs,
   std::string SysRoot = computeSysRoot();
   std::string Target = getTripleString();
 
-  auto AddIncludePath = [&](std::string Path) {
+  auto AddIncludePath = [&](StringRef Path, bool TargetDirRequired = false) {
 std::string Version = detectLibcxxVersion(Path);
 if (Version.empty())
   return false;
 
 // First add the per-target include path if it exists.
-std::string TargetDir = Path + "/" + Target + "/c++/" + Version;
+SmallString<128> TargetDir(Path);
+llvm::sys::path::append(TargetDir, Target, "c++", Version);
 if (D.getVFS().exists(TargetDir))
   addSystemInclude(DriverArgs, CC1Args, TargetDir);
+else if (TargetDirRequired)
+  return false;
 
 // Second add the generic one.
-addSystemInclude(DriverArgs, CC1Args, Path + "/c++/" + Version);
+SmallString<128> GenericDir(Path);
+llvm::sys::path::append(GenericDir, "c++", Version);
+addSystemInclude(DriverArgs, CC1Args, GenericDir);
 return true;
   };
 
-  // Android never uses the libc++ headers installed alongside the toolchain,
-  // which are generally incompatible with the NDK libraries anyway.
-  if (!getTriple().isAndroid())
-if (AddIncludePath(getDriver().Dir + "/../include"))
-  return;
+  // Android only uses the libc++ headers installed alongside the toolchain if
+  // they contain an Android-specific target include path, otherwise they're
+  // incompatible with the NDK libraries.
+  SmallString<128> DriverIncludeDir(getDriver().Dir);
+  llvm::sys::path::append(DriverIncludeDir, "..", "include");
+  if (AddIncludePath(DriverIncludeDir,
+ /*TargetDirRequired=*/getTriple().isAndroid()))
+return;
   // If this is a development, non-installed, clang, libcxx will
   // not be found at ../include/c++ but it likely to be found at
   // one of the following two locations:
-  if (AddInc

  1   2   3   4   5   >