[clang] Reapply "[clang][analyzer] StreamChecker: Model getc, vfscanf, putc, … (PR #83281)

2024-02-29 Thread Alejandro Álvarez Ayllón via cfe-commits

alejandro-alvarez-sonarsource wrote:

@balazske @steakhal I broke some tests on aarch64 since there 
`__builtin_valist` is a struct and not a pointer to struct, so `lookupFn` was 
not matching `vfprintf` nor `vfscanf`, and the NULL pointer dereference 
triggered on the `fclose`. I have fixed that and modified `stream.c` to always 
run with four different target architectures, to make sure different `va_list` 
are handled.

Not sure if that is the best way, though.

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


[clang] [compiler-rt] [AArch64] Implement __builtin_cpu_supports, compiler-rt tests. (PR #82378)

2024-02-29 Thread via cfe-commits

eaeltsin wrote:

Thanks @DanielKristofKiss - considering compilations with older toolchains is a 
good reason to choose the particular behavior. It would be very valuable if all 
these reasons and the selected behavior for unsupported builtins/parameters are 
documented, i.e. here - 
https://clang.llvm.org/docs/LanguageExtensions.html#builtin-functions


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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-29 Thread Matt Arsenault via cfe-commits

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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -814,6 +814,15 @@ bool shouldEmitConstantsToTextSection(const Triple &TT);
 /// to integer.
 int getIntegerAttribute(const Function &F, StringRef Name, int Default);
 
+/// \returns Unsigned Integer value requested using \p F's \p Name attribute.
+///
+/// \returns \p Default if attribute is not present.
+///
+/// \returns \p Default and emits error if requested value cannot be converted
+/// to integer.
+unsigned getUnsignedIntegerAttribute(const Function &F, StringRef Name,

arsenm wrote:

The above getIntegerAttribute is actually dead, this shouldn't follow along. 
The equivalent functionality was moved to getFnAttributeAsParsedInteger

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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -356,6 +356,24 @@ void AMDGPUTargetCodeGenInfo::setFunctionDeclAttributes(
 if (NumVGPR != 0)
   F->addFnAttr("amdgpu-num-vgpr", llvm::utostr(NumVGPR));
   }
+
+  if (const auto *Attr = FD->getAttr()) {
+uint32_t X = Attr->getMaxNumWorkGroupsX()
+ ->EvaluateKnownConstInt(M.getContext())
+ .getExtValue();
+uint32_t Y = Attr->getMaxNumWorkGroupsY()
+ ->EvaluateKnownConstInt(M.getContext())
+ .getExtValue();
+uint32_t Z = Attr->getMaxNumWorkGroupsZ()
+ ->EvaluateKnownConstInt(M.getContext())
+ .getExtValue();
+
+llvm::SmallString<32> AttrVal;
+llvm::raw_svector_ostream OS(AttrVal);
+OS << X << "," << Y << "," << Z;

arsenm wrote:

```suggestion
OS << X << ',' << Y << ',' << Z;
```

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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,84 @@
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck %s
+
+; Attribute not specified.
+; CHECK-LABEL: {{^}}empty_no_attribute:
+define amdgpu_kernel void @empty_no_attribute() {
+entry:
+  ret void
+}
+
+; Ignore if number of work groups for x dimension is 0.
+; CHECK-LABEL: {{^}}empty_max_num_work_groups_x0:
+define amdgpu_kernel void @empty_max_num_work_groups_x0() #0 {
+entry:
+  ret void
+}
+attributes #0 = {"amdgpu-max-num-work-groups"="0,2,3"}
+
+; Ignore if number of work groups for y dimension is 0.
+; CHECK-LABEL: {{^}}empty_max_num_work_groups_y0:
+define amdgpu_kernel void @empty_max_num_work_groups_y0() #1 {
+entry:
+  ret void
+}
+attributes #1 = {"amdgpu-max-num-work-groups"="1,0,3"}
+
+; Ignore if number of work groups for z dimension is 0.
+; CHECK-LABEL: {{^}}empty_max_num_work_groups_z0:
+define amdgpu_kernel void @empty_max_num_work_groups_z0() #2 {
+entry:
+  ret void
+}
+attributes #2 = {"amdgpu-max-num-work-groups"="1,2,0"}
+
+; CHECK-LABEL: {{^}}empty_max_num_work_groups_1_2_3:
+define amdgpu_kernel void @empty_max_num_work_groups_1_2_3() #3 {
+entry:
+  ret void
+}
+attributes #3 = {"amdgpu-max-num-work-groups"="1,2,3"}
+
+; CHECK-LABEL: {{^}}empty_max_num_work_groups_1024_1024_1024:
+define amdgpu_kernel void @empty_max_num_work_groups_1024_1024_1024() #4 {
+entry:
+  ret void
+}
+attributes #4 = {"amdgpu-max-num-work-groups"="1024,1024,1024"}
+

arsenm wrote:

Check some negative, and hex values which I believe will be handled correctly 
by the parser

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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -139,6 +139,36 @@ kernel void 
reqd_work_group_size_32_2_1_flat_work_group_size_16_128() {
 // CHECK: define{{.*}} amdgpu_kernel void 
@reqd_work_group_size_32_2_1_flat_work_group_size_16_128() 
[[FLAT_WORK_GROUP_SIZE_16_128:#[0-9]+]]
 }
 
+__attribute__((amdgpu_max_num_work_groups(1, 1, 1))) // expected-no-diagnostics
+kernel void max_num_work_groups_1_1_1() {
+// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_1_1_1() 
[[MAX_NUM_WORK_GROUPS_1_1_1:#[0-9]+]]
+}
+
+__attribute__((amdgpu_max_num_work_groups(32, 1, 1))) // 
expected-no-diagnostics
+kernel void max_num_work_groups_32_1_1() {
+// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_32_1_1() 
[[MAX_NUM_WORK_GROUPS_32_1_1:#[0-9]+]]
+}
+
+__attribute__((amdgpu_max_num_work_groups(32, 8, 1))) // 
expected-no-diagnostics
+kernel void max_num_work_groups_32_8_1() {
+// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_32_8_1() 
[[MAX_NUM_WORK_GROUPS_32_8_1:#[0-9]+]]
+}
+
+__attribute__((amdgpu_max_num_work_groups(1, 1, 32))) // 
expected-no-diagnostics
+kernel void max_num_work_groups_1_1_32() {
+// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_1_1_32() 
[[MAX_NUM_WORK_GROUPS_1_1_32:#[0-9]+]]
+}
+
+__attribute__((amdgpu_max_num_work_groups(1, 8, 32))) // 
expected-no-diagnostics
+kernel void max_num_work_groups_1_8_32() {
+// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_1_8_32() 
[[MAX_NUM_WORK_GROUPS_1_8_32:#[0-9]+]]
+}
+
+__attribute__((amdgpu_max_num_work_groups(4, 8, 32))) // 
expected-no-diagnostics
+kernel void max_num_work_groups_4_8_32() {
+// CHECK: define{{.*}} amdgpu_kernel void @max_num_work_groups_4_8_32() 
[[MAX_NUM_WORK_GROUPS_4_8_32:#[0-9]+]]
+}
+

arsenm wrote:

should test maximum allowed values and minimums 

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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -194,3 +204,105 @@ __global__ void non_cexpr_waves_per_eu_2() {}
 // expected-error@+1{{'amdgpu_waves_per_eu' attribute requires parameter 1 to 
be an integer constant}}
 __attribute__((amdgpu_waves_per_eu(2, ipow2(2
 __global__ void non_cexpr_waves_per_eu_2_4() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires exactly 
3 arguments}}
+__attribute__((amdgpu_max_num_work_groups(32)))
+__global__ void max_num_work_groups_32() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires exactly 
3 arguments}}
+__attribute__((amdgpu_max_num_work_groups(32, 1)))
+__global__ void max_num_work_groups_32_1() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires exactly 
3 arguments}}
+__attribute__((amdgpu_max_num_work_groups(32, 1, 1, 1)))
+__global__ void max_num_work_groups_32_1_1_1() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires 
parameter 0 to be an integer constant}}
+__attribute__((amdgpu_max_num_work_groups(ipow2(5), 1, 1)))
+__global__ void max_num_work_groups_32_1_1_non_int_arg0() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires 
parameter 1 to be an integer constant}}
+__attribute__((amdgpu_max_num_work_groups(32, "1", 1)))
+__global__ void max_num_work_groups_32_1_1_non_int_arg1() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires a 
non-negative integral compile time constant expression}}
+__attribute__((amdgpu_max_num_work_groups(-32, 1, 1)))
+__global__ void max_num_work_groups_32_1_1_neg_int_arg0() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires a 
non-negative integral compile time constant expression}}
+__attribute__((amdgpu_max_num_work_groups(32, -1, 1)))
+__global__ void max_num_work_groups_32_1_1_neg_int_arg1() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires a 
non-negative integral compile time constant expression}}
+__attribute__((amdgpu_max_num_work_groups(32, 1, -1)))
+__global__ void max_num_work_groups_32_1_1_neg_int_arg2() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute must be greater 
than 0}}
+__attribute__((amdgpu_max_num_work_groups(0, 1, 1)))
+__global__ void max_num_work_groups_0_1_1() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute must be greater 
than 0}}
+__attribute__((amdgpu_max_num_work_groups(32, 0, 1)))
+__global__ void max_num_work_groups_32_0_1() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute must be greater 
than 0}}
+__attribute__((amdgpu_max_num_work_groups(32, 1, 0)))
+__global__ void max_num_work_groups_32_1_0() {}
+
+
+int num_wg_x = 32;
+int num_wg_y = 1;
+int num_wg_z = 1;
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires 
parameter 0 to be an integer constant}}
+__attribute__((amdgpu_max_num_work_groups(num_wg_x, 1, 1)))
+__global__ void max_num_work_groups_32_1_1_non_const_arg0() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires 
parameter 1 to be an integer constant}}
+__attribute__((amdgpu_max_num_work_groups(32, num_wg_y, 1)))
+__global__ void max_num_work_groups_32_1_1_non_const_arg1() {}
+
+// expected-error@+1{{'amdgpu_max_num_work_groups' attribute requires 
parameter 2 to be an integer constant}}
+__attribute__((amdgpu_max_num_work_groups(32, 1, num_wg_z)))
+__global__ void max_num_work_groups_32_1_1_non_const_arg2() {}
+
+const int c_num_wg_x = 32;
+__attribute__((amdgpu_max_num_work_groups(c_num_wg_x, 1, 1)))
+__global__ void max_num_work_groups_32_1_1_const_arg0() {}
+
+template
+__attribute__((amdgpu_max_num_work_groups(a, 1, 1)))
+__global__ void template_a_1_1_max_num_work_groups() {}
+template __global__ void template_a_1_1_max_num_work_groups<32>();
+
+template
+__attribute__((amdgpu_max_num_work_groups(32, a, 1)))
+__global__ void template_32_a_1_max_num_work_groups() {}
+template __global__ void template_32_a_1_max_num_work_groups<1>();
+
+template
+__attribute__((amdgpu_max_num_work_groups(32, 1, a)))
+__global__ void template_32_1_a_max_num_work_groups() {}
+template __global__ void template_32_1_a_max_num_work_groups<1>();
+
+// expected-error@+3{{'amdgpu_max_num_work_groups' attribute must be greater 
than 0}}
+// expected-note@+4{{in instantiation of}}
+template
+__attribute__((amdgpu_max_num_work_groups(b, 1, 1)))
+__global__ void template_b_1_1_max_num_work_groups() {}
+template __global__ void template_b_1_1_max_num_work_groups<0>();
+
+// expected-error@+3{{'amdgpu_max_num_work_groups' attribute must be greater 
than 0}}
+// expected-note@+4{{in instantiation of}}
+template
+__attribute__((amdgpu_max_num_work_groups(32, b, 1)))
+__global__ void template_32_b_1_max_num_work_groups() {}
+template __global__ void template_32_b_1_max_num_work_groups<0>();
+
+// expected-error@+3{{'amdgpu_max_num_work_groups' attribute must be greater 
than 0}}
+// expected-note@+4{{in instantiation of}}
+template
+__attribute__(

[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -0,0 +1,84 @@
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck %s
+

arsenm wrote:

Missing a test for the various IR attribute parsing error conditions 

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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-29 Thread Matt Arsenault via cfe-commits

https://github.com/arsenm requested changes to this pull request.


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


[clang] [llvm] [AMDGPU] Adding the amdgpu-num-work-groups function attribute (PR #79035)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -137,6 +137,11 @@ Removed Compiler Flags
 
 Attribute Changes in Clang
 --
+- Introduced a new function attribute 
``__attribute__((amdgpu_max_num_work_groups(x, y, z)))`` or
+  ``[[clang::amdgpu_max_num_work_groups(x, y, z)]]`` for the AMDGPU target. 
This attribute can be
+  attached to HIP or OpenCL kernel function definitions to provide an 
optimization hint. The parameters
+  ``x``, ``y``, and ``z`` specify the maximum number of workgroups for the 
respective dimensions,
+  and each must be a positive integer.

arsenm wrote:

Should probably permit only specifying x, which leaves y and z assumed 1 

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


[clang-tools-extra] [include-cleaner] Generate references from explicit functiontemplate specializations (PR #83392)

2024-02-29 Thread kadir çetinkaya via cfe-commits

https://github.com/kadircet created 
https://github.com/llvm/llvm-project/pull/83392

None

From f62a553d8d4af339bdcb69024d5bf42527e3a01d Mon Sep 17 00:00:00 2001
From: Kadir Cetinkaya 
Date: Thu, 29 Feb 2024 09:25:18 +0100
Subject: [PATCH] [include-cleaner] Generate references from explicit
 functiontemplate specializations

---
 clang-tools-extra/include-cleaner/lib/WalkAST.cpp  |  5 +
 .../include-cleaner/unittests/WalkASTTest.cpp  | 10 --
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp 
b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 277e6ec5b08900..878067aca0173f 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -228,6 +228,11 @@ class ASTWalker : public RecursiveASTVisitor {
 // Mark declaration from definition as it needs type-checking.
 if (FD->isThisDeclarationADefinition())
   report(FD->getLocation(), FD);
+// Explicit specializaiton/instantiations of a function template requires
+// primary template.
+if (clang::isTemplateExplicitInstantiationOrSpecialization(
+FD->getTemplateSpecializationKind()))
+  report(FD->getLocation(), FD->getPrimaryTemplate());
 return true;
   }
   bool VisitVarDecl(VarDecl *VD) {
diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index e238dc3d902bbe..5dc88157e13af0 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -229,13 +229,9 @@ TEST(WalkAST, FunctionTemplates) {
   EXPECT_THAT(testWalk("template void foo(T) {}",
"template void ^foo(int);"),
   ElementsAre());
-  // FIXME: Report specialized template as used from explicit specializations.
-  EXPECT_THAT(testWalk("template void foo(T);",
+  EXPECT_THAT(testWalk("template void $explicit^foo(T);",
"template<> void ^foo(int);"),
-  ElementsAre());
-  EXPECT_THAT(testWalk("template void foo(T) {}",
-   "template void ^foo(T*) {}"),
-  ElementsAre());
+  ElementsAre(Decl::FunctionTemplate));
 
   // Implicit instantiations references most relevant template.
   EXPECT_THAT(testWalk(R"cpp(
@@ -510,6 +506,8 @@ TEST(WalkAST, Functions) {
   // Definition uses declaration, not the other way around.
   testWalk("void $explicit^foo();", "void ^foo() {}");
   testWalk("void foo() {}", "void ^foo();");
+  testWalk("template  void $explicit^foo();",
+   "template  void ^foo() {}");
 
   // Unresolved calls marks all the overloads.
   testWalk("void $ambiguous^foo(int); void $ambiguous^foo(char);",

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


[clang-tools-extra] [include-cleaner] Generate references from explicit functiontemplate specializations (PR #83392)

2024-02-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-tools-extra

Author: kadir çetinkaya (kadircet)


Changes



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


2 Files Affected:

- (modified) clang-tools-extra/include-cleaner/lib/WalkAST.cpp (+5) 
- (modified) clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp (+4-6) 


``diff
diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp 
b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 277e6ec5b08900..878067aca0173f 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -228,6 +228,11 @@ class ASTWalker : public RecursiveASTVisitor {
 // Mark declaration from definition as it needs type-checking.
 if (FD->isThisDeclarationADefinition())
   report(FD->getLocation(), FD);
+// Explicit specializaiton/instantiations of a function template requires
+// primary template.
+if (clang::isTemplateExplicitInstantiationOrSpecialization(
+FD->getTemplateSpecializationKind()))
+  report(FD->getLocation(), FD->getPrimaryTemplate());
 return true;
   }
   bool VisitVarDecl(VarDecl *VD) {
diff --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index e238dc3d902bbe..5dc88157e13af0 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -229,13 +229,9 @@ TEST(WalkAST, FunctionTemplates) {
   EXPECT_THAT(testWalk("template void foo(T) {}",
"template void ^foo(int);"),
   ElementsAre());
-  // FIXME: Report specialized template as used from explicit specializations.
-  EXPECT_THAT(testWalk("template void foo(T);",
+  EXPECT_THAT(testWalk("template void $explicit^foo(T);",
"template<> void ^foo(int);"),
-  ElementsAre());
-  EXPECT_THAT(testWalk("template void foo(T) {}",
-   "template void ^foo(T*) {}"),
-  ElementsAre());
+  ElementsAre(Decl::FunctionTemplate));
 
   // Implicit instantiations references most relevant template.
   EXPECT_THAT(testWalk(R"cpp(
@@ -510,6 +506,8 @@ TEST(WalkAST, Functions) {
   // Definition uses declaration, not the other way around.
   testWalk("void $explicit^foo();", "void ^foo() {}");
   testWalk("void foo() {}", "void ^foo();");
+  testWalk("template  void $explicit^foo();",
+   "template  void ^foo() {}");
 
   // Unresolved calls marks all the overloads.
   testWalk("void $ambiguous^foo(int); void $ambiguous^foo(char);",

``




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


[clang] [clang-format] Enable again some operator tests (PR #83380)

2024-02-29 Thread Owen Pan via cfe-commits


@@ -16671,9 +16667,8 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
SpaceFuncDecl);
   verifyFormat("int f () throw(Deprecated);", SpaceFuncDecl);
   verifyFormat("typedef void (*cb)(int);", SpaceFuncDecl);
-  // FIXME these tests regressed behaviour.
-  // verifyFormat("T A::operator() ();", SpaceFuncDecl);
-  // verifyFormat("X A::operator++ (T);", SpaceFuncDecl);
+  verifyFormat("T A::operator()();", SpaceFuncDecl);
+  verifyFormat("X A::operator++(T);", SpaceFuncDecl);

owenca wrote:

Why are the spaces removed?

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


[clang] [clang-format] Enable again some operator tests (PR #83380)

2024-02-29 Thread Owen Pan via cfe-commits


@@ -16797,7 +16792,7 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
   verifyFormat("int f() throw (Deprecated);", SomeSpace2);
   verifyFormat("typedef void (*cb) (int);", SomeSpace2);
   verifyFormat("T A::operator()();", SomeSpace2);
-  // verifyFormat("X A::operator++ (T);", SomeSpace2);
+  verifyFormat("X A::operator++ (T);", SomeSpace2);

owenca wrote:

Shouldn't the space be removed here?

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


[clang] [clang-format] Enable again some operator tests (PR #83380)

2024-02-29 Thread Owen Pan via cfe-commits


@@ -16710,7 +16705,7 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
   verifyFormat("typedef void (*cb)(int);", SpaceFuncDef);
   verifyFormat("T A::operator()();", SpaceFuncDef);
   verifyFormat("X A::operator++(T);", SpaceFuncDef);
-  // verifyFormat("T A::operator() () {}", SpaceFuncDef);
+  verifyFormat("T A::operator()() {}", SpaceFuncDef);

owenca wrote:

Why is the space removed?

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


[clang] [clang-format] Enable again some operator tests (PR #83380)

2024-02-29 Thread Owen Pan via cfe-commits


@@ -16797,7 +16792,7 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
   verifyFormat("int f() throw (Deprecated);", SomeSpace2);
   verifyFormat("typedef void (*cb) (int);", SomeSpace2);
   verifyFormat("T A::operator()();", SomeSpace2);
-  // verifyFormat("X A::operator++ (T);", SomeSpace2);
+  verifyFormat("X A::operator++ (T);", SomeSpace2);

owenca wrote:

Nvm.

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


[clang-tools-extra] [include-cleaner] Generate references from explicit functiontemplate specializations (PR #83392)

2024-02-29 Thread via cfe-commits

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


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


[clang] ddfc7e2 - [clang][Interp] Emit more dummy pointers in C++ mode

2024-02-29 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-02-29T10:04:42+01:00
New Revision: ddfc7e225474558613db3604c053fd73f1fdedac

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

LOG: [clang][Interp] Emit more dummy pointers in C++ mode

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index b151f8d0d7a79c..122b9045a75f6e 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3213,12 +3213,6 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const 
DeclRefExpr *E) {
   // we haven't seen yet.
   if (Ctx.getLangOpts().CPlusPlus) {
 if (const auto *VD = dyn_cast(D)) {
-  // Dummy for static locals
-  if (VD->isStaticLocal()) {
-if (std::optional I = P.getOrCreateDummy(D))
-  return this->emitGetPtrGlobal(*I, E);
-return false;
-  }
   // Visit local const variables like normal.
   if (VD->isLocalVarDecl() && VD->getType().isConstQualified()) {
 if (!this->visitVarDecl(VD))
@@ -3226,6 +3220,9 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const 
DeclRefExpr *E) {
 // Retry.
 return this->VisitDeclRefExpr(E);
   }
+
+  if (VD->hasExternalStorage())
+return this->emitInvalidDeclRef(E, E);
 }
   } else {
 if (const auto *VD = dyn_cast(D);
@@ -3235,11 +3232,11 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const 
DeclRefExpr *E) {
   // Retry.
   return this->VisitDeclRefExpr(E);
 }
-
-if (std::optional I = P.getOrCreateDummy(D))
-  return this->emitGetPtrGlobal(*I, E);
   }
 
+  if (std::optional I = P.getOrCreateDummy(D))
+return this->emitGetPtrGlobal(*I, E);
+
   return this->emitInvalidDeclRef(E, E);
 }
 

diff  --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 5670888c245eb1..4f3cd6cd21a151 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -285,10 +285,6 @@ static bool CheckConstant(InterpState &S, CodePtr OpPC, 
const Pointer &Ptr) {
   return CheckConstant(S, OpPC, Ptr.getDeclDesc());
 }
 
-bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
-  return !Ptr.isDummy();
-}
-
 bool CheckNull(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
CheckSubobjectKind CSK) {
   if (!Ptr.isZero())
@@ -595,10 +591,8 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, const 
Floating &Result,
   return true;
 }
 
-/// We aleady know the given DeclRefExpr is invalid for some reason,
-/// now figure out why and print appropriate diagnostics.
-bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) {
-  const ValueDecl *D = DR->getDecl();
+static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC,
+const ValueDecl *D) {
   const SourceInfo &E = S.Current->getSource(OpPC);
 
   if (isa(D)) {
@@ -621,10 +615,28 @@ bool CheckDeclRef(InterpState &S, CodePtr OpPC, const 
DeclRefExpr *DR) {
   return false;
 }
   }
-
   return false;
 }
 
+/// We aleady know the given DeclRefExpr is invalid for some reason,
+/// now figure out why and print appropriate diagnostics.
+bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) {
+  const ValueDecl *D = DR->getDecl();
+  return diagnoseUnknownDecl(S, OpPC, D);
+}
+
+bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
+  if (!Ptr.isDummy())
+return true;
+
+  const Descriptor *Desc = Ptr.getDeclDesc();
+  const ValueDecl *D = Desc->asValueDecl();
+  if (!D)
+return false;
+
+  return diagnoseUnknownDecl(S, OpPC, D);
+}
+
 bool CheckNonNullArgs(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *CE, unsigned ArgSize) {
   auto Args = llvm::ArrayRef(CE->getArgs(), CE->getNumArgs());

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 13e004371f912c..f379c9869d8d8e 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -572,7 +572,8 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const 
Pointer &Ptr) {
 template ::T>
 bool Inc(InterpState &S, CodePtr OpPC) {
   const Pointer &Ptr = S.Stk.pop();
-
+  if (Ptr.isDummy())
+return false;
   if (!CheckInitialized(S, OpPC, Ptr, AK_Increment))
 return false;
 
@@ -585,7 +586,8 @@ bool Inc(InterpState &S, CodePtr OpPC) {
 template ::T>
 bool IncPop(InterpState &S, CodePtr OpPC) {
   const Pointer &Ptr = S.Stk.pop();
-
+  if (Ptr.isDummy())
+return false;
   if (!CheckInitialized(S, OpPC, Ptr, AK_Incr

[clang] [compiler-rt] [AArch64] Implement __builtin_cpu_supports, compiler-rt tests. (PR #82378)

2024-02-29 Thread via cfe-commits

bgra8 wrote:

@DanielKristofKiss do I understand correctly that you confirm the current 
behavior for `__builtin_cpu_supports("unsupported-features")` -- does not 
compile no matter the CPU --  is a `clang` defect? 

If that is the case let's file a bug to have this fixed.



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


[clang-tools-extra] bd595d5 - [include-cleaner] Generate references from explicit functiontemplate specializations (#83392)

2024-02-29 Thread via cfe-commits

Author: kadir çetinkaya
Date: 2024-02-29T10:37:00+01:00
New Revision: bd595d54219e434acce2c05e97440847d30b5240

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

LOG: [include-cleaner] Generate references from explicit functiontemplate 
specializations (#83392)

Added: 


Modified: 
clang-tools-extra/include-cleaner/lib/WalkAST.cpp
clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp

Removed: 




diff  --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp 
b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index 277e6ec5b08900..878067aca0173f 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -228,6 +228,11 @@ class ASTWalker : public RecursiveASTVisitor {
 // Mark declaration from definition as it needs type-checking.
 if (FD->isThisDeclarationADefinition())
   report(FD->getLocation(), FD);
+// Explicit specializaiton/instantiations of a function template requires
+// primary template.
+if (clang::isTemplateExplicitInstantiationOrSpecialization(
+FD->getTemplateSpecializationKind()))
+  report(FD->getLocation(), FD->getPrimaryTemplate());
 return true;
   }
   bool VisitVarDecl(VarDecl *VD) {

diff  --git a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp 
b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
index e238dc3d902bbe..5dc88157e13af0 100644
--- a/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
@@ -229,13 +229,9 @@ TEST(WalkAST, FunctionTemplates) {
   EXPECT_THAT(testWalk("template void foo(T) {}",
"template void ^foo(int);"),
   ElementsAre());
-  // FIXME: Report specialized template as used from explicit specializations.
-  EXPECT_THAT(testWalk("template void foo(T);",
+  EXPECT_THAT(testWalk("template void $explicit^foo(T);",
"template<> void ^foo(int);"),
-  ElementsAre());
-  EXPECT_THAT(testWalk("template void foo(T) {}",
-   "template void ^foo(T*) {}"),
-  ElementsAre());
+  ElementsAre(Decl::FunctionTemplate));
 
   // Implicit instantiations references most relevant template.
   EXPECT_THAT(testWalk(R"cpp(
@@ -510,6 +506,8 @@ TEST(WalkAST, Functions) {
   // Definition uses declaration, not the other way around.
   testWalk("void $explicit^foo();", "void ^foo() {}");
   testWalk("void foo() {}", "void ^foo();");
+  testWalk("template  void $explicit^foo();",
+   "template  void ^foo() {}");
 
   // Unresolved calls marks all the overloads.
   testWalk("void $ambiguous^foo(int); void $ambiguous^foo(char);",



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


[clang-tools-extra] [include-cleaner] Generate references from explicit functiontemplate specializations (PR #83392)

2024-02-29 Thread kadir çetinkaya via cfe-commits

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


[clang] [OpenMP] Clang Codegen Interop : Accept multiple use & destroy clauses (PR #83398)

2024-02-29 Thread via cfe-commits

https://github.com/SunilKuravinakop created 
https://github.com/llvm/llvm-project/pull/83398

Modified clang/lib/CodeGen/CGStmtOpenMP.cpp to accept multiple use & destroy 
clauses with interop directive.
Modified clang/test/OpenMP/interop_codegen.cpp to check for the changes.

>From d3db4821ad4f6c93057df5130ecc67f8aa69ca63 Mon Sep 17 00:00:00 2001
From: Sunil Kuravinakop 
Date: Thu, 29 Feb 2024 03:38:27 -0600
Subject: [PATCH] Adding code for multiple occurences of "use" and "destroy"
 clause.

  Changes to be committed:
modified:   clang/lib/CodeGen/CGStmtOpenMP.cpp
modified:   clang/test/OpenMP/interop_codegen.cpp
---
 clang/lib/CodeGen/CGStmtOpenMP.cpp| 34 +--
 clang/test/OpenMP/interop_codegen.cpp | 22 -
 2 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp 
b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index ffcd3ae2711e34..3fbd2e03eb61df 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -7042,18 +7042,28 @@ void CodeGenFunction::EmitOMPInteropDirective(const 
OMPInteropDirective &S) {
   Device, NumDependences, DependenceList,
   Data.HasNowaitClause);
 }
-  } else if (const auto *C = S.getSingleClause()) {
-llvm::Value *InteropvarPtr =
-EmitLValue(C->getInteropVar()).getPointer(*this);
-OMPBuilder.createOMPInteropDestroy(Builder, InteropvarPtr, Device,
-   NumDependences, DependenceList,
-   Data.HasNowaitClause);
-  } else if (const auto *C = S.getSingleClause()) {
-llvm::Value *InteropvarPtr =
-EmitLValue(C->getInteropVar()).getPointer(*this);
-OMPBuilder.createOMPInteropUse(Builder, InteropvarPtr, Device,
-   NumDependences, DependenceList,
-   Data.HasNowaitClause);
+  }
+  auto ItOMPDestroyClause = S.getClausesOfKind();
+  if (!ItOMPDestroyClause.empty()) {
+// Look at the multiple destroy clauses
+for (const OMPDestroyClause *C : ItOMPDestroyClause) {
+  llvm::Value *InteropvarPtr =
+  EmitLValue(C->getInteropVar()).getPointer(*this);
+  OMPBuilder.createOMPInteropDestroy(Builder, InteropvarPtr, Device,
+ NumDependences, DependenceList,
+ Data.HasNowaitClause);
+}
+  }
+  auto ItOMPUseClause = S.getClausesOfKind();
+  if (!ItOMPUseClause.empty()) {
+// Look at the multiple use clauses
+for (const OMPUseClause *C : ItOMPUseClause) {
+  llvm::Value *InteropvarPtr =
+  EmitLValue(C->getInteropVar()).getPointer(*this);
+  OMPBuilder.createOMPInteropUse(Builder, InteropvarPtr, Device,
+ NumDependences, DependenceList,
+ Data.HasNowaitClause);
+}
   }
 }
 
diff --git a/clang/test/OpenMP/interop_codegen.cpp 
b/clang/test/OpenMP/interop_codegen.cpp
index ea83ef8ed4909f..31df2f1ba58c5f 100644
--- a/clang/test/OpenMP/interop_codegen.cpp
+++ b/clang/test/OpenMP/interop_codegen.cpp
@@ -15,21 +15,31 @@ typedef long omp_intptr_t;
 extern omp_intptr_t omp_get_interop_int(const omp_interop_t, int, int *);
 
 int main() {
-  omp_interop_t obj = omp_interop_none;
+  omp_interop_t obj1 = omp_interop_none;
+  omp_interop_t obj2 = omp_interop_none;
   omp_interop_t i1 = omp_interop_none;
   omp_interop_t i2 = omp_interop_none;
   omp_interop_t i3 = omp_interop_none;
   omp_interop_t i4 = omp_interop_none;
   omp_interop_t i5 = omp_interop_none;
 
-  #pragma omp interop init(targetsync: i1) init(targetsync: obj)
-  int id = (int )omp_get_interop_int(obj, omp_ipr_fr_id, NULL);
-  int id1 = (int )omp_get_interop_int(i1, omp_ipr_fr_id, NULL);
+  #pragma omp interop init(targetsync: obj1) init(targetsync: obj2)
+  int id = (int )omp_get_interop_int(obj1, omp_ipr_fr_id, NULL);
+  int id1 = (int )omp_get_interop_int(obj2, omp_ipr_fr_id, NULL);
+
+  #pragma omp interop init(target,targetsync: i1) use(i2) use(i3) destroy(i4) 
destroy(i5)
+  int id2 = (int )omp_get_interop_int(i1, omp_ipr_fr_id, NULL);
+  int id3 = (int )omp_get_interop_int(i2, omp_ipr_fr_id, NULL);
 
 
 }
 #endif
 
-// CHECK-LABEL: define {{.+}}main{{.+}} 
+// CHECK-LABEL: define {{.+}}main{{.+}}
+// CHECK: call {{.+}}__tgt_interop_init({{.+}}obj1{{.*}})
+// CHECK: call {{.+}}__tgt_interop_init({{.+}}obj2{{.*}})
 // CHECK: call {{.+}}__tgt_interop_init({{.+}}i1{{.*}})
-// CHECK: call {{.+}}__tgt_interop_init({{.+}}obj{{.*}})
+// CHECK: call {{.+}}__tgt_interop_destroy({{.+}}i4{{.*}})
+// CHECK: call {{.+}}__tgt_interop_destroy({{.+}}i5{{.*}})
+// CHECK: call {{.+}}__tgt_interop_use({{.+}}i2{{.*}})
+// CHECK: call {{.+}}__tgt_interop_use({{.+}}i3{{.*}})

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/c

[clang] [OpenMP] Clang Codegen Interop : Accept multiple use & destroy clauses (PR #83398)

2024-02-29 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: None (SunilKuravinakop)


Changes

Modified clang/lib/CodeGen/CGStmtOpenMP.cpp to accept multiple use & 
destroy clauses with interop directive.
Modified clang/test/OpenMP/interop_codegen.cpp to check for the changes.

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


2 Files Affected:

- (modified) clang/lib/CodeGen/CGStmtOpenMP.cpp (+22-12) 
- (modified) clang/test/OpenMP/interop_codegen.cpp (+16-6) 


``diff
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp 
b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index ffcd3ae2711e34..3fbd2e03eb61df 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -7042,18 +7042,28 @@ void CodeGenFunction::EmitOMPInteropDirective(const 
OMPInteropDirective &S) {
   Device, NumDependences, DependenceList,
   Data.HasNowaitClause);
 }
-  } else if (const auto *C = S.getSingleClause()) {
-llvm::Value *InteropvarPtr =
-EmitLValue(C->getInteropVar()).getPointer(*this);
-OMPBuilder.createOMPInteropDestroy(Builder, InteropvarPtr, Device,
-   NumDependences, DependenceList,
-   Data.HasNowaitClause);
-  } else if (const auto *C = S.getSingleClause()) {
-llvm::Value *InteropvarPtr =
-EmitLValue(C->getInteropVar()).getPointer(*this);
-OMPBuilder.createOMPInteropUse(Builder, InteropvarPtr, Device,
-   NumDependences, DependenceList,
-   Data.HasNowaitClause);
+  }
+  auto ItOMPDestroyClause = S.getClausesOfKind();
+  if (!ItOMPDestroyClause.empty()) {
+// Look at the multiple destroy clauses
+for (const OMPDestroyClause *C : ItOMPDestroyClause) {
+  llvm::Value *InteropvarPtr =
+  EmitLValue(C->getInteropVar()).getPointer(*this);
+  OMPBuilder.createOMPInteropDestroy(Builder, InteropvarPtr, Device,
+ NumDependences, DependenceList,
+ Data.HasNowaitClause);
+}
+  }
+  auto ItOMPUseClause = S.getClausesOfKind();
+  if (!ItOMPUseClause.empty()) {
+// Look at the multiple use clauses
+for (const OMPUseClause *C : ItOMPUseClause) {
+  llvm::Value *InteropvarPtr =
+  EmitLValue(C->getInteropVar()).getPointer(*this);
+  OMPBuilder.createOMPInteropUse(Builder, InteropvarPtr, Device,
+ NumDependences, DependenceList,
+ Data.HasNowaitClause);
+}
   }
 }
 
diff --git a/clang/test/OpenMP/interop_codegen.cpp 
b/clang/test/OpenMP/interop_codegen.cpp
index ea83ef8ed4909f..31df2f1ba58c5f 100644
--- a/clang/test/OpenMP/interop_codegen.cpp
+++ b/clang/test/OpenMP/interop_codegen.cpp
@@ -15,21 +15,31 @@ typedef long omp_intptr_t;
 extern omp_intptr_t omp_get_interop_int(const omp_interop_t, int, int *);
 
 int main() {
-  omp_interop_t obj = omp_interop_none;
+  omp_interop_t obj1 = omp_interop_none;
+  omp_interop_t obj2 = omp_interop_none;
   omp_interop_t i1 = omp_interop_none;
   omp_interop_t i2 = omp_interop_none;
   omp_interop_t i3 = omp_interop_none;
   omp_interop_t i4 = omp_interop_none;
   omp_interop_t i5 = omp_interop_none;
 
-  #pragma omp interop init(targetsync: i1) init(targetsync: obj)
-  int id = (int )omp_get_interop_int(obj, omp_ipr_fr_id, NULL);
-  int id1 = (int )omp_get_interop_int(i1, omp_ipr_fr_id, NULL);
+  #pragma omp interop init(targetsync: obj1) init(targetsync: obj2)
+  int id = (int )omp_get_interop_int(obj1, omp_ipr_fr_id, NULL);
+  int id1 = (int )omp_get_interop_int(obj2, omp_ipr_fr_id, NULL);
+
+  #pragma omp interop init(target,targetsync: i1) use(i2) use(i3) destroy(i4) 
destroy(i5)
+  int id2 = (int )omp_get_interop_int(i1, omp_ipr_fr_id, NULL);
+  int id3 = (int )omp_get_interop_int(i2, omp_ipr_fr_id, NULL);
 
 
 }
 #endif
 
-// CHECK-LABEL: define {{.+}}main{{.+}} 
+// CHECK-LABEL: define {{.+}}main{{.+}}
+// CHECK: call {{.+}}__tgt_interop_init({{.+}}obj1{{.*}})
+// CHECK: call {{.+}}__tgt_interop_init({{.+}}obj2{{.*}})
 // CHECK: call {{.+}}__tgt_interop_init({{.+}}i1{{.*}})
-// CHECK: call {{.+}}__tgt_interop_init({{.+}}obj{{.*}})
+// CHECK: call {{.+}}__tgt_interop_destroy({{.+}}i4{{.*}})
+// CHECK: call {{.+}}__tgt_interop_destroy({{.+}}i5{{.*}})
+// CHECK: call {{.+}}__tgt_interop_use({{.+}}i2{{.*}})
+// CHECK: call {{.+}}__tgt_interop_use({{.+}}i3{{.*}})

``




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


[clang-tools-extra] [clang-tidy] Improve `google-explicit-constructor` checks handling of `explicit(bool)` (PR #82689)

2024-02-29 Thread Benjamin Maxwell via cfe-commits

https://github.com/MacDue updated 
https://github.com/llvm/llvm-project/pull/82689

>From 6bf8d649fb78b81adbaa7de82064161e14213fc4 Mon Sep 17 00:00:00 2001
From: AMS21 
Date: Thu, 22 Feb 2024 22:10:09 +0100
Subject: [PATCH] [clang-tidy] Improve `google-explicit-constructor` checks
 handling of `explicit(bool)`

We now treat `explicit(false)` the same way we treat `noexcept(false)` in
the noexcept checks, which is ignoring it.

Also introduced a new warning message if a constructor has an `explicit`
declaration which evaluates to false and no longer emit a faulty FixIt.

Fixes #81121
---
 .../google/ExplicitConstructorCheck.cpp   | 33 ---
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 ++
 .../google/explicit-constructor-cxx20.cpp | 59 +++
 3 files changed, 88 insertions(+), 8 deletions(-)
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/google/explicit-constructor-cxx20.cpp

diff --git a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp 
b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp
index 34d49af9f81e23..6f26de9881357f 100644
--- a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp
+++ b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp
@@ -79,8 +79,10 @@ static bool isStdInitializerList(QualType Type) {
 }
 
 void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) {
-  constexpr char WarningMessage[] =
+  constexpr char NoExpressionWarningMessage[] =
   "%0 must be marked explicit to avoid unintentional implicit conversions";
+  constexpr char WithExpressionWarningMessage[] =
+  "%0 explicit expression evaluates to 'false'";
 
   if (const auto *Conversion =
   Result.Nodes.getNodeAs("conversion")) {
@@ -91,7 +93,7 @@ void ExplicitConstructorCheck::check(const 
MatchFinder::MatchResult &Result) {
 // gmock to define matchers).
 if (Loc.isMacroID())
   return;
-diag(Loc, WarningMessage)
+diag(Loc, NoExpressionWarningMessage)
 << Conversion << FixItHint::CreateInsertion(Loc, "explicit ");
 return;
   }
@@ -101,9 +103,11 @@ void ExplicitConstructorCheck::check(const 
MatchFinder::MatchResult &Result) {
   Ctor->getMinRequiredArguments() > 1)
 return;
 
+  const ExplicitSpecifier ExplicitSpec = Ctor->getExplicitSpecifier();
+
   bool TakesInitializerList = isStdInitializerList(
   Ctor->getParamDecl(0)->getType().getNonReferenceType());
-  if (Ctor->isExplicit() &&
+  if (ExplicitSpec.isExplicit() &&
   (Ctor->isCopyOrMoveConstructor() || TakesInitializerList)) {
 auto IsKwExplicit = [](const Token &Tok) {
   return Tok.is(tok::raw_identifier) &&
@@ -130,18 +134,31 @@ void ExplicitConstructorCheck::check(const 
MatchFinder::MatchResult &Result) {
 return;
   }
 
-  if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() ||
+  if (ExplicitSpec.isExplicit() || Ctor->isCopyOrMoveConstructor() ||
   TakesInitializerList)
 return;
 
-  bool SingleArgument =
+  // Don't complain about explicit(false) or dependent expressions
+  const Expr *ExplicitExpr = ExplicitSpec.getExpr();
+  if (ExplicitExpr) {
+ExplicitExpr = ExplicitExpr->IgnoreImplicit();
+if (isa(ExplicitExpr) ||
+ExplicitExpr->isInstantiationDependent())
+  return;
+  }
+
+  const bool SingleArgument =
   Ctor->getNumParams() == 1 && !Ctor->getParamDecl(0)->isParameterPack();
   SourceLocation Loc = Ctor->getLocation();
-  diag(Loc, WarningMessage)
+  auto Diag =
+  diag(Loc, ExplicitExpr ? WithExpressionWarningMessage
+ : NoExpressionWarningMessage)
   << (SingleArgument
   ? "single-argument constructors"
-  : "constructors that are callable with a single argument")
-  << FixItHint::CreateInsertion(Loc, "explicit ");
+  : "constructors that are callable with a single argument");
+
+  if (!ExplicitExpr)
+Diag << FixItHint::CreateInsertion(Loc, "explicit ");
 }
 
 } // namespace clang::tidy::google
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 3f90e7d63d6b23..f2df3d0d737c6b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -151,6 +151,10 @@ Changes in existing checks
   ` check by replacing the local
   option `HeaderFileExtensions` by the global option of the same name.
 
+- Improved :doc:`google-explicit-constructor
+  ` check to better handle
+  ``C++-20`` `explicit(bool)`.
+
 - Improved :doc:`google-global-names-in-headers
   ` check by replacing the 
local
   option `HeaderFileExtensions` by the global option of the same name.
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/google/explicit-constructor-cxx20.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/google/explicit-constructor-cxx20.cpp
new file mode 100644
index 00..95206f1ef420c3
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/go

[clang-tools-extra] [clang-tidy] Improve `google-explicit-constructor` checks handling of `explicit(bool)` (PR #82689)

2024-02-29 Thread via cfe-commits

https://github.com/AMS21 updated https://github.com/llvm/llvm-project/pull/82689

>From 6bf8d649fb78b81adbaa7de82064161e14213fc4 Mon Sep 17 00:00:00 2001
From: AMS21 
Date: Thu, 22 Feb 2024 22:10:09 +0100
Subject: [PATCH] [clang-tidy] Improve `google-explicit-constructor` checks
 handling of `explicit(bool)`

We now treat `explicit(false)` the same way we treat `noexcept(false)` in
the noexcept checks, which is ignoring it.

Also introduced a new warning message if a constructor has an `explicit`
declaration which evaluates to false and no longer emit a faulty FixIt.

Fixes #81121
---
 .../google/ExplicitConstructorCheck.cpp   | 33 ---
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 ++
 .../google/explicit-constructor-cxx20.cpp | 59 +++
 3 files changed, 88 insertions(+), 8 deletions(-)
 create mode 100644 
clang-tools-extra/test/clang-tidy/checkers/google/explicit-constructor-cxx20.cpp

diff --git a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp 
b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp
index 34d49af9f81e23..6f26de9881357f 100644
--- a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp
+++ b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp
@@ -79,8 +79,10 @@ static bool isStdInitializerList(QualType Type) {
 }
 
 void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) {
-  constexpr char WarningMessage[] =
+  constexpr char NoExpressionWarningMessage[] =
   "%0 must be marked explicit to avoid unintentional implicit conversions";
+  constexpr char WithExpressionWarningMessage[] =
+  "%0 explicit expression evaluates to 'false'";
 
   if (const auto *Conversion =
   Result.Nodes.getNodeAs("conversion")) {
@@ -91,7 +93,7 @@ void ExplicitConstructorCheck::check(const 
MatchFinder::MatchResult &Result) {
 // gmock to define matchers).
 if (Loc.isMacroID())
   return;
-diag(Loc, WarningMessage)
+diag(Loc, NoExpressionWarningMessage)
 << Conversion << FixItHint::CreateInsertion(Loc, "explicit ");
 return;
   }
@@ -101,9 +103,11 @@ void ExplicitConstructorCheck::check(const 
MatchFinder::MatchResult &Result) {
   Ctor->getMinRequiredArguments() > 1)
 return;
 
+  const ExplicitSpecifier ExplicitSpec = Ctor->getExplicitSpecifier();
+
   bool TakesInitializerList = isStdInitializerList(
   Ctor->getParamDecl(0)->getType().getNonReferenceType());
-  if (Ctor->isExplicit() &&
+  if (ExplicitSpec.isExplicit() &&
   (Ctor->isCopyOrMoveConstructor() || TakesInitializerList)) {
 auto IsKwExplicit = [](const Token &Tok) {
   return Tok.is(tok::raw_identifier) &&
@@ -130,18 +134,31 @@ void ExplicitConstructorCheck::check(const 
MatchFinder::MatchResult &Result) {
 return;
   }
 
-  if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() ||
+  if (ExplicitSpec.isExplicit() || Ctor->isCopyOrMoveConstructor() ||
   TakesInitializerList)
 return;
 
-  bool SingleArgument =
+  // Don't complain about explicit(false) or dependent expressions
+  const Expr *ExplicitExpr = ExplicitSpec.getExpr();
+  if (ExplicitExpr) {
+ExplicitExpr = ExplicitExpr->IgnoreImplicit();
+if (isa(ExplicitExpr) ||
+ExplicitExpr->isInstantiationDependent())
+  return;
+  }
+
+  const bool SingleArgument =
   Ctor->getNumParams() == 1 && !Ctor->getParamDecl(0)->isParameterPack();
   SourceLocation Loc = Ctor->getLocation();
-  diag(Loc, WarningMessage)
+  auto Diag =
+  diag(Loc, ExplicitExpr ? WithExpressionWarningMessage
+ : NoExpressionWarningMessage)
   << (SingleArgument
   ? "single-argument constructors"
-  : "constructors that are callable with a single argument")
-  << FixItHint::CreateInsertion(Loc, "explicit ");
+  : "constructors that are callable with a single argument");
+
+  if (!ExplicitExpr)
+Diag << FixItHint::CreateInsertion(Loc, "explicit ");
 }
 
 } // namespace clang::tidy::google
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 3f90e7d63d6b23..f2df3d0d737c6b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -151,6 +151,10 @@ Changes in existing checks
   ` check by replacing the local
   option `HeaderFileExtensions` by the global option of the same name.
 
+- Improved :doc:`google-explicit-constructor
+  ` check to better handle
+  ``C++-20`` `explicit(bool)`.
+
 - Improved :doc:`google-global-names-in-headers
   ` check by replacing the 
local
   option `HeaderFileExtensions` by the global option of the same name.
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/google/explicit-constructor-cxx20.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/google/explicit-constructor-cxx20.cpp
new file mode 100644
index 00..95206f1ef420c3
--- /dev/null
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/goog

[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)

2024-02-29 Thread via cfe-commits

https://github.com/AMS21 updated https://github.com/llvm/llvm-project/pull/82673

>From 7dcbbae9656700bde30caf28f8105648e8dfc623 Mon Sep 17 00:00:00 2001
From: AMS21 
Date: Thu, 22 Feb 2024 19:24:43 +0100
Subject: [PATCH] [clang-tidy] Let `bugprone-use-after-move` also handle calls
 to `std::forward`

Fixes #82023
---
 .../clang-tidy/bugprone/UseAfterMoveCheck.cpp | 57 ++-
 clang-tools-extra/docs/ReleaseNotes.rst   |  4 ++
 .../checks/bugprone/use-after-move.rst| 12 
 .../checkers/bugprone/use-after-move.cpp  | 37 
 4 files changed, 95 insertions(+), 15 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
index c5b6b541096ca98..b91ad0f18229550 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp
@@ -330,7 +330,8 @@ void UseAfterMoveFinder::getReinits(
 traverse(TK_AsIs, DeclRefMatcher),
 unless(parmVarDecl(hasType(
 references(qualType(isConstQualified())),
-unless(callee(functionDecl(hasName("::std::move")))
+unless(callee(functionDecl(
+hasAnyName("::std::move", "::std::forward")))
   .bind("reinit");
 
   Stmts->clear();
@@ -359,24 +360,46 @@ void UseAfterMoveFinder::getReinits(
   }
 }
 
+enum class MoveType {
+  Move,// std::move
+  Forward, // std::forward
+};
+
+static MoveType determineMoveType(const FunctionDecl *FuncDecl) {
+  if (FuncDecl->getName() == "move")
+return MoveType::Move;
+  if (FuncDecl->getName() == "forward")
+return MoveType::Forward;
+
+  llvm_unreachable("Invalid move type");
+}
+
 static void emitDiagnostic(const Expr *MovingCall, const DeclRefExpr *MoveArg,
const UseAfterMove &Use, ClangTidyCheck *Check,
-   ASTContext *Context) {
-  SourceLocation UseLoc = Use.DeclRef->getExprLoc();
-  SourceLocation MoveLoc = MovingCall->getExprLoc();
+   ASTContext *Context, MoveType Type) {
+  const SourceLocation UseLoc = Use.DeclRef->getExprLoc();
+  const SourceLocation MoveLoc = MovingCall->getExprLoc();
+
+  const bool IsMove = (Type == MoveType::Move);
 
-  Check->diag(UseLoc, "'%0' used after it was moved")
-  << MoveArg->getDecl()->getName();
-  Check->diag(MoveLoc, "move occurred here", DiagnosticIDs::Note);
+  Check->diag(UseLoc, "'%0' used after it was %select{forwarded|moved}1")
+  << MoveArg->getDecl()->getName() << IsMove;
+  Check->diag(MoveLoc, "%select{forward|move}0 occurred here",
+  DiagnosticIDs::Note)
+  << IsMove;
   if (Use.EvaluationOrderUndefined) {
-Check->diag(UseLoc,
-"the use and move are unsequenced, i.e. there is no guarantee "
-"about the order in which they are evaluated",
-DiagnosticIDs::Note);
+Check->diag(
+UseLoc,
+"the use and %select{forward|move}0 are unsequenced, i.e. "
+"there is no guarantee about the order in which they are evaluated",
+DiagnosticIDs::Note)
+<< IsMove;
   } else if (UseLoc < MoveLoc || Use.DeclRef == MoveArg) {
 Check->diag(UseLoc,
-"the use happens in a later loop iteration than the move",
-DiagnosticIDs::Note);
+"the use happens in a later loop iteration than the "
+"%select{forward|move}0",
+DiagnosticIDs::Note)
+<< IsMove;
   }
 }
 
@@ -388,7 +411,9 @@ void UseAfterMoveCheck::registerMatchers(MatchFinder 
*Finder) {
   auto TryEmplaceMatcher =
   cxxMemberCallExpr(callee(cxxMethodDecl(hasName("try_emplace";
   auto CallMoveMatcher =
-  callExpr(argumentCountIs(1), 
callee(functionDecl(hasName("::std::move"))),
+  callExpr(argumentCountIs(1),
+   callee(functionDecl(hasAnyName("::std::move", "::std::forward"))
+  .bind("move-decl")),
hasArgument(0, declRefExpr().bind("arg")),
unless(inDecltypeOrTemplateArg()),
unless(hasParent(TryEmplaceMatcher)), expr().bind("call-move"),
@@ -436,6 +461,7 @@ void UseAfterMoveCheck::check(const 
MatchFinder::MatchResult &Result) {
   const auto *CallMove = Result.Nodes.getNodeAs("call-move");
   const auto *MovingCall = Result.Nodes.getNodeAs("moving-call");
   const auto *Arg = Result.Nodes.getNodeAs("arg");
+  const auto *MoveDecl = Result.Nodes.getNodeAs("move-decl");
 
   if (!MovingCall || !MovingCall->getExprLoc().isValid())
 MovingCall = CallMove;
@@ -470,7 +496,8 @@ void UseAfterMoveCheck::check(const 
MatchFinder::MatchResult &Result) {
 UseAfterMoveFinder Finder(Result.Context);
 UseAfterMove Use;
 if (Finder.find(CodeBlock, MovingCall, Arg->getDecl(), &Use))
- 

[clang-tools-extra] [clang-tidy] Let `bugprone-use-after-move` also handle calls to `std::forward` (PR #82673)

2024-02-29 Thread via cfe-commits

AMS21 wrote:

Rebased to fix merge conflict

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


[clang] [compiler-rt] [AArch64] Implement __builtin_cpu_supports, compiler-rt tests. (PR #82378)

2024-02-29 Thread via cfe-commits

DanielKristofKiss wrote:

@bgra8 Correct, submitted #83407.

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


[clang] Disable FTZ/DAZ when compiling shared libraries by default. (PR #80475)

2024-02-29 Thread Matt Arsenault via cfe-commits

arsenm wrote:

> But the shared library stuff isn't an issue for AMDGPU, right?

No, we don't support shared library linking yet

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


[clang] [llvm] [AMDGPU] Add an option to disable unsafe uses of atomic xor (PR #69229)

2024-02-29 Thread Matt Arsenault via cfe-commits

arsenm wrote:

> In this case, MMRAs would only help in the sense that you won't need any new 
> attributes and can just add an MMRA such as `atomic-lowering:fine-grained`. 
> It's not really what MMRAs were made for (because this attribute doesn't 
> affect semantics, just lowering style I think?),

It is semantics. You get undefined behavior if you access fine grained memory 
for an atomic where the instruction doesn't handle it. I don't think it quite 
fits into the MMRA box, since it isn't about the synchronization properties of 
the memory access but where the underlying memory is 

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


[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-02-29 Thread Christian Kandeler via cfe-commits

https://github.com/ckandeler created 
https://github.com/llvm/llvm-project/pull/83412

... when converting unscoped to scoped enums.
With traditional enums, a popular technique to guard against potential name 
clashes is to use the enum name as a pseudo-namespace, like this:
  enum MyEnum { MyEnumValue1, MyEnumValue2 };
With scoped enums, this makes no sense, making it extremely unlikely that the 
user wants to keep such a prefix when modernizing. Therefore, our tweak now 
removes it.

>From c687b73939821eba285b35e50c241738ba7915e4 Mon Sep 17 00:00:00 2001
From: Christian Kandeler 
Date: Thu, 29 Feb 2024 12:26:52 +0100
Subject: [PATCH] [clangd] Remove potential prefix from enum value names

... when converting unscoped to scoped enums.
With traditional enums, a popular technique to guard against potential
name clashes is to use the enum name as a pseudo-namespace, like this:
  enum MyEnum { MyEnumValue1, MyEnumValue2 };
With scoped enums, this makes no sense, making it extremely unlikely
that the user wants to keep such a prefix when modernizing. Therefore, our
tweak now removes it.
---
 .../clangd/refactor/tweaks/ScopifyEnum.cpp| 49 +--
 .../unittests/tweaks/ScopifyEnumTests.cpp |  8 +--
 2 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
index e36b3249bc7b92..5c042ee7b782b9 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
@@ -40,15 +40,12 @@ namespace {
 ///   void f() { E e1 = EV1; }
 ///
 /// After:
-///   enum class E { EV1, EV2 };
-///   void f() { E e1 = E::EV1; }
+///   enum class E { V1, V2 };
+///   void f() { E e1 = E::V1; }
 ///
 /// Note that the respective project code might not compile anymore
 /// if it made use of the now-gone implicit conversion to int.
 /// This is out of scope for this tweak.
-///
-/// TODO: In the above example, we could detect that the values
-///   start with the enum name, and remove that prefix.
 
 class ScopifyEnum : public Tweak {
   const char *id() const final;
@@ -63,7 +60,8 @@ class ScopifyEnum : public Tweak {
   std::function;
   llvm::Error addClassKeywordToDeclarations();
   llvm::Error scopifyEnumValues();
-  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef Prefix);
+  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef EnumName,
+   bool StripPrefix);
   llvm::Expected getContentForFile(StringRef FilePath);
   unsigned getOffsetFromPosition(const Position &Pos, StringRef Content) const;
   llvm::Error addReplacementForReference(const ReferencesResult::Reference 
&Ref,
@@ -125,25 +123,42 @@ llvm::Error ScopifyEnum::addClassKeywordToDeclarations() {
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValues() {
-  std::string PrefixToInsert(D->getName());
-  PrefixToInsert += "::";
+  StringRef EnumName(D->getName());
+  bool StripPrefix = true;
+  for (auto E : D->enumerators()) {
+if (!E->getName().starts_with(EnumName)) {
+  StripPrefix = false;
+  break;
+}
+  }
   for (auto E : D->enumerators()) {
-if (auto Err = scopifyEnumValue(*E, PrefixToInsert))
+if (auto Err = scopifyEnumValue(*E, EnumName, StripPrefix))
   return Err;
   }
   return llvm::Error::success();
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValue(const EnumConstantDecl &CD,
-  StringRef Prefix) {
+  StringRef EnumName,
+  bool StripPrefix) {
   for (const auto &Ref :
findReferences(*S->AST, getPosition(CD), 0, S->Index, false)
.References) {
-if (Ref.Attributes & ReferencesResult::Declaration)
+if (Ref.Attributes & ReferencesResult::Declaration) {
+  if (StripPrefix) {
+const auto MakeReplacement = [&EnumName](StringRef FilePath,
+ StringRef /* Content */,
+ unsigned Offset) {
+  return tooling::Replacement(FilePath, Offset, EnumName.size(), {});
+};
+if (auto Err = addReplacementForReference(Ref, MakeReplacement))
+  return Err;
+  }
   continue;
+}
 
-const auto MakeReplacement = [&Prefix](StringRef FilePath,
-   StringRef Content, unsigned Offset) 
{
+const auto MakeReplacement = [&](StringRef FilePath, StringRef Content,
+ unsigned Offset) {
   const auto IsAlreadyScoped = [Content, Offset] {
 if (Offset < 2)
   return false;
@@ -164,9 +179,15 @@ llvm::Error ScopifyEnum::scopifyEnumValue(const 
EnumConstantDecl &CD,
 }
 return false;
   };
+  if (StripPrefix) {
+if (IsAlreadyScoped())
+  return tooling::Replacement(FilePath, O

[clang-tools-extra] [clangd] Remove potential prefix from enum value names (PR #83412)

2024-02-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clangd

Author: Christian Kandeler (ckandeler)


Changes

... when converting unscoped to scoped enums.
With traditional enums, a popular technique to guard against potential name 
clashes is to use the enum name as a pseudo-namespace, like this:
  enum MyEnum { MyEnumValue1, MyEnumValue2 };
With scoped enums, this makes no sense, making it extremely unlikely that the 
user wants to keep such a prefix when modernizing. Therefore, our tweak now 
removes it.

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


2 Files Affected:

- (modified) clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp (+35-14) 
- (modified) clang-tools-extra/clangd/unittests/tweaks/ScopifyEnumTests.cpp 
(+4-4) 


``diff
diff --git a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
index e36b3249bc7b92..5c042ee7b782b9 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ScopifyEnum.cpp
@@ -40,15 +40,12 @@ namespace {
 ///   void f() { E e1 = EV1; }
 ///
 /// After:
-///   enum class E { EV1, EV2 };
-///   void f() { E e1 = E::EV1; }
+///   enum class E { V1, V2 };
+///   void f() { E e1 = E::V1; }
 ///
 /// Note that the respective project code might not compile anymore
 /// if it made use of the now-gone implicit conversion to int.
 /// This is out of scope for this tweak.
-///
-/// TODO: In the above example, we could detect that the values
-///   start with the enum name, and remove that prefix.
 
 class ScopifyEnum : public Tweak {
   const char *id() const final;
@@ -63,7 +60,8 @@ class ScopifyEnum : public Tweak {
   std::function;
   llvm::Error addClassKeywordToDeclarations();
   llvm::Error scopifyEnumValues();
-  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef Prefix);
+  llvm::Error scopifyEnumValue(const EnumConstantDecl &CD, StringRef EnumName,
+   bool StripPrefix);
   llvm::Expected getContentForFile(StringRef FilePath);
   unsigned getOffsetFromPosition(const Position &Pos, StringRef Content) const;
   llvm::Error addReplacementForReference(const ReferencesResult::Reference 
&Ref,
@@ -125,25 +123,42 @@ llvm::Error ScopifyEnum::addClassKeywordToDeclarations() {
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValues() {
-  std::string PrefixToInsert(D->getName());
-  PrefixToInsert += "::";
+  StringRef EnumName(D->getName());
+  bool StripPrefix = true;
+  for (auto E : D->enumerators()) {
+if (!E->getName().starts_with(EnumName)) {
+  StripPrefix = false;
+  break;
+}
+  }
   for (auto E : D->enumerators()) {
-if (auto Err = scopifyEnumValue(*E, PrefixToInsert))
+if (auto Err = scopifyEnumValue(*E, EnumName, StripPrefix))
   return Err;
   }
   return llvm::Error::success();
 }
 
 llvm::Error ScopifyEnum::scopifyEnumValue(const EnumConstantDecl &CD,
-  StringRef Prefix) {
+  StringRef EnumName,
+  bool StripPrefix) {
   for (const auto &Ref :
findReferences(*S->AST, getPosition(CD), 0, S->Index, false)
.References) {
-if (Ref.Attributes & ReferencesResult::Declaration)
+if (Ref.Attributes & ReferencesResult::Declaration) {
+  if (StripPrefix) {
+const auto MakeReplacement = [&EnumName](StringRef FilePath,
+ StringRef /* Content */,
+ unsigned Offset) {
+  return tooling::Replacement(FilePath, Offset, EnumName.size(), {});
+};
+if (auto Err = addReplacementForReference(Ref, MakeReplacement))
+  return Err;
+  }
   continue;
+}
 
-const auto MakeReplacement = [&Prefix](StringRef FilePath,
-   StringRef Content, unsigned Offset) 
{
+const auto MakeReplacement = [&](StringRef FilePath, StringRef Content,
+ unsigned Offset) {
   const auto IsAlreadyScoped = [Content, Offset] {
 if (Offset < 2)
   return false;
@@ -164,9 +179,15 @@ llvm::Error ScopifyEnum::scopifyEnumValue(const 
EnumConstantDecl &CD,
 }
 return false;
   };
+  if (StripPrefix) {
+if (IsAlreadyScoped())
+  return tooling::Replacement(FilePath, Offset, EnumName.size(), {});
+return tooling::Replacement(FilePath, Offset + EnumName.size(), 0,
+"::");
+  }
   return IsAlreadyScoped()
  ? tooling::Replacement()
- : tooling::Replacement(FilePath, Offset, 0, Prefix);
+ : tooling::Replacement(FilePath, Offset, 0, EnumName);
 };
 if (auto Err = addReplacementForReference(Ref, MakeReplacement))
   return Err;
diff --git a/clang-tools-extra/clangd/

[clang] [llvm] [AMDGPU] Add code model (#70760) test for amdgpu target. (PR #71019)

2024-02-29 Thread Matt Arsenault via cfe-commits

arsenm wrote:

reverse ping 

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


[clang] [clang][Documentation] fix documentation for clang-format (PR #83415)

2024-02-29 Thread via cfe-commits

https://github.com/PeterChou1 created 
https://github.com/llvm/llvm-project/pull/83415

Fixes typo in documentation for clang-format 

see: https://github.com/llvm/llvm-project/issues/83207

>From 67154ff4388447ff78b2912e5635231778ed23d4 Mon Sep 17 00:00:00 2001
From: PeterChou1 <4355+peterch...@users.noreply.github.com>
Date: Thu, 29 Feb 2024 06:55:18 -0500
Subject: [PATCH] [clang][Documentation] fix documentation for clang-format

Fixes typo related to clang-format

see: https://github.com/llvm/llvm-project/issues/83207
---
 clang/docs/ClangFormatStyleOptions.rst | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index df399a229d8d4f..5b00a8f4c00fb8 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -318,9 +318,9 @@ the configuration (without a prefix: ``Auto``).
 
   .. code-block:: c++
 
-AlignConsecutiveMacros: AcrossEmptyLines
+AlignConsecutiveAssignments: AcrossEmptyLines
 
-AlignConsecutiveMacros:
+AlignConsecutiveAssignments:
   Enabled: true
   AcrossEmptyLines: true
   AcrossComments: false
@@ -460,9 +460,9 @@ the configuration (without a prefix: ``Auto``).
 
   .. code-block:: c++
 
-AlignConsecutiveMacros: AcrossEmptyLines
+AlignConsecutiveBitFields: AcrossEmptyLines
 
-AlignConsecutiveMacros:
+AlignConsecutiveBitFields:
   Enabled: true
   AcrossEmptyLines: true
   AcrossComments: false
@@ -602,9 +602,9 @@ the configuration (without a prefix: ``Auto``).
 
   .. code-block:: c++
 
-AlignConsecutiveMacros: AcrossEmptyLines
+AlignConsecutiveDeclarations: AcrossEmptyLines
 
-AlignConsecutiveMacros:
+AlignConsecutiveDeclarations:
   Enabled: true
   AcrossEmptyLines: true
   AcrossComments: false
@@ -983,9 +983,9 @@ the configuration (without a prefix: ``Auto``).
 
   .. code-block:: c++
 
-AlignConsecutiveMacros: AcrossEmptyLines
+AlignConsecutiveTableGenCondOperatorColons: AcrossEmptyLines
 
-AlignConsecutiveMacros:
+AlignConsecutiveTableGenCondOperatorColons:
   Enabled: true
   AcrossEmptyLines: true
   AcrossComments: false
@@ -1123,9 +1123,9 @@ the configuration (without a prefix: ``Auto``).
 
   .. code-block:: c++
 
-AlignConsecutiveMacros: AcrossEmptyLines
+AlignConsecutiveTableGenDefinitionColons: AcrossEmptyLines
 
-AlignConsecutiveMacros:
+AlignConsecutiveTableGenDefinitionColons:
   Enabled: true
   AcrossEmptyLines: true
   AcrossComments: false

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


[clang] [clang][Documentation] fix documentation for clang-format (PR #83415)

2024-02-29 Thread via cfe-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from 
other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

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


[clang] [clang][Documentation] fix documentation for clang-format (PR #83415)

2024-02-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (PeterChou1)


Changes

Fixes typo in documentation for clang-format 

see: https://github.com/llvm/llvm-project/issues/83207

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


1 Files Affected:

- (modified) clang/docs/ClangFormatStyleOptions.rst (+10-10) 


``diff
diff --git a/clang/docs/ClangFormatStyleOptions.rst 
b/clang/docs/ClangFormatStyleOptions.rst
index df399a229d8d4f..5b00a8f4c00fb8 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -318,9 +318,9 @@ the configuration (without a prefix: ``Auto``).
 
   .. code-block:: c++
 
-AlignConsecutiveMacros: AcrossEmptyLines
+AlignConsecutiveAssignments: AcrossEmptyLines
 
-AlignConsecutiveMacros:
+AlignConsecutiveAssignments:
   Enabled: true
   AcrossEmptyLines: true
   AcrossComments: false
@@ -460,9 +460,9 @@ the configuration (without a prefix: ``Auto``).
 
   .. code-block:: c++
 
-AlignConsecutiveMacros: AcrossEmptyLines
+AlignConsecutiveBitFields: AcrossEmptyLines
 
-AlignConsecutiveMacros:
+AlignConsecutiveBitFields:
   Enabled: true
   AcrossEmptyLines: true
   AcrossComments: false
@@ -602,9 +602,9 @@ the configuration (without a prefix: ``Auto``).
 
   .. code-block:: c++
 
-AlignConsecutiveMacros: AcrossEmptyLines
+AlignConsecutiveDeclarations: AcrossEmptyLines
 
-AlignConsecutiveMacros:
+AlignConsecutiveDeclarations:
   Enabled: true
   AcrossEmptyLines: true
   AcrossComments: false
@@ -983,9 +983,9 @@ the configuration (without a prefix: ``Auto``).
 
   .. code-block:: c++
 
-AlignConsecutiveMacros: AcrossEmptyLines
+AlignConsecutiveTableGenCondOperatorColons: AcrossEmptyLines
 
-AlignConsecutiveMacros:
+AlignConsecutiveTableGenCondOperatorColons:
   Enabled: true
   AcrossEmptyLines: true
   AcrossComments: false
@@ -1123,9 +1123,9 @@ the configuration (without a prefix: ``Auto``).
 
   .. code-block:: c++
 
-AlignConsecutiveMacros: AcrossEmptyLines
+AlignConsecutiveTableGenDefinitionColons: AcrossEmptyLines
 
-AlignConsecutiveMacros:
+AlignConsecutiveTableGenDefinitionColons:
   Enabled: true
   AcrossEmptyLines: true
   AcrossComments: false

``




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


[clang] [clang][Documentation] fix documentation for clang-format (PR #83415)

2024-02-29 Thread via cfe-commits

github-actions[bot] wrote:

⚠️ We detected that you are using a GitHub private e-mail address to contribute 
to the repo.
  Please turn off [Keep my email addresses 
private](https://github.com/settings/emails) setting in your account.
  See [LLVM 
Discourse](https://discourse.llvm.org/t/hidden-emails-on-github-should-we-do-something-about-it)
 for more information.


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


[clang] [llvm] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2024-02-29 Thread Matt Arsenault via cfe-commits

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


[clang] [llvm] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -2550,6 +2550,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
   &getTarget().getLongDoubleFormat() == &llvm::APFloat::IEEEquad())
 BuiltinID = mutateLongDoubleBuiltin(BuiltinID);
 
+  // Mutate the printf builtin ID so that we use the same CodeGen path for
+  // HIP and OpenCL with AMDGPU targets.
+  if (getTarget().getTriple().isAMDGCN() && BuiltinID == AMDGPU::BIprintf)
+BuiltinID = Builtin::BIprintf;

arsenm wrote:

You should not need to remap builtins 

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


[clang] [llvm] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -3616,6 +3617,12 @@ unsigned FunctionDecl::getBuiltinID(bool 
ConsiderWrapperFunctions) const {
   if (!ConsiderWrapperFunctions && getStorageClass() == SC_Static)
 return 0;
 
+  // AMDGCN implementation supports printf as a builtin
+  // for OpenCL
+  if (Context.getTargetInfo().getTriple().isAMDGCN() &&
+  Context.getLangOpts().OpenCL && BuiltinID == AMDGPU::BIprintf)
+return BuiltinID;

arsenm wrote:

This does not belong here and has nothing to do with AMDGPU 

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


[clang] [llvm] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -406,5 +410,9 @@ TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_fp8_f32, "iffiIb", 
"nc", "fp8-insts")
 TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_bf8_f32, "ifiiIi", "nc", "fp8-insts")
 TARGET_BUILTIN(__builtin_amdgcn_cvt_sr_fp8_f32, "ifiiIi", "nc", "fp8-insts")
 
+// OpenCL
+LANGBUILTIN(printf, "icC*4.", "fp:0:", ALL_OCL_LANGUAGES)

arsenm wrote:

This does not belong here. This has nothing to do with AMDGPU 

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


[clang] [llvm] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2024-02-29 Thread Matt Arsenault via cfe-commits

https://github.com/arsenm requested changes to this pull request.


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


[clang] [llvm] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -202,12 +207,20 @@ RValue 
CodeGenFunction::EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E) {
 Args.push_back(Arg);
   }
 
-  llvm::IRBuilder<> IRB(Builder.GetInsertBlock(), Builder.GetInsertPoint());
-  IRB.SetCurrentDebugLocation(Builder.getCurrentDebugLocation());
+  auto PFK = CGM.getTarget().getTargetOpts().AMDGPUPrintfKindVal;
+  bool isBuffered = (PFK == clang::TargetOptions::AMDGPUPrintfKind::Buffered);
+
+  StringRef FmtStr;
+  if (llvm::getConstantStringInfo(Args[0], FmtStr)) {
+if (FmtStr.empty())
+  FmtStr = StringRef("", 1);

arsenm wrote:

This is producing an invalid StringRef?

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


[clang] [llvm] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -202,12 +207,20 @@ RValue 
CodeGenFunction::EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E) {
 Args.push_back(Arg);
   }
 
-  llvm::IRBuilder<> IRB(Builder.GetInsertBlock(), Builder.GetInsertPoint());
-  IRB.SetCurrentDebugLocation(Builder.getCurrentDebugLocation());
+  auto PFK = CGM.getTarget().getTargetOpts().AMDGPUPrintfKindVal;
+  bool isBuffered = (PFK == clang::TargetOptions::AMDGPUPrintfKind::Buffered);
+
+  StringRef FmtStr;
+  if (llvm::getConstantStringInfo(Args[0], FmtStr)) {
+if (FmtStr.empty())
+  FmtStr = StringRef("", 1);
+  } else {
+assert(!CGM.getLangOpts().OpenCL &&
+   "OpenCL needs compile time resolvable format string");

arsenm wrote:

I would remove this assert. It's supposed to be enforced by the frontend, and 
the emit function should try to gracefully handle the non-literal case 

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


[clang] [llvm] [AMDGPU] Enable OpenCL hostcall printf (WIP) (PR #72556)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -170,20 +173,46 @@ static Value *appendString(IRBuilder<> &Builder, Value 
*Desc, Value *Arg,
   return callAppendStringN(Builder, Desc, Arg, Length, IsLast);
 }
 
+static Value *appendVectorArg(IRBuilder<> &Builder, Value *Desc, Value *Arg,

arsenm wrote:

These are all still in this PR?

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


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-29 Thread Botond István Horváth via cfe-commits


@@ -5548,13 +5504,100 @@ static bool isAtLeastAsSpecializedAs(Sema &S,
 FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
 FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
 TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-unsigned NumCallArguments2, bool Reversed) {
+unsigned NumCallArguments2, QualType RawObjType1, QualType RawObjType2,
+bool Reversed) {
+  SmallVector Args1;
+  SmallVector Args2;
+  const FunctionDecl *FD1 = FT1->getTemplatedDecl();
+  const FunctionDecl *FD2 = FT2->getTemplatedDecl();
+  bool shouldConvert1 = false;
+  bool shouldConvert2 = false;
+  QualType ObjType1;
+  QualType ObjType2;
+  if (TPOC == TPOC_Call) {
+const FunctionProtoType *Proto1 =
+FD1->getType()->getAs();
+const FunctionProtoType *Proto2 =
+FD2->getType()->getAs();
+
+//   - In the context of a function call, the function parameter types are
+// used.
+const CXXMethodDecl *Method1 = dyn_cast(FD1);
+const CXXMethodDecl *Method2 = dyn_cast(FD2);
+
+if (getLangOpts().CPlusPlus20) {
+  // C++20 [temp.func.order]p3
+  //   [...] Each function template M that is a member function is
+  //   considered to have a new first parameter of type
+  //   X(M), described below, inserted in its function parameter list.
+  //
+  // Note that we interpret "that is a member function" as
+  // "that is a member function with no expicit object argument".
+  // Otherwise the ordering rules for methods with expicit objet arguments
+  // against anything else make no sense.
+  shouldConvert1 = Method1 && !Method1->isExplicitObjectMemberFunction();
+  shouldConvert2 = Method2 && !Method2->isExplicitObjectMemberFunction();
+} else {
+  // C++11 [temp.func.order]p3:
+  //   [...] If only one of the function templates is a non-static
+  //   member, that function template is considered to have a new
+  //   first parameter inserted in its function parameter list.
+  //
+  // Note that we interpret this to mean "if one of the function
+  // templates is a non-static member and the other is a non-member";
+  // otherwise, the ordering rules for static functions against non-static
+  // functions don't make any sense.
+  //
+  // C++98/03 doesn't have this provision but we've extended DR532 to cover
+  // it as wording was broken prior to it.
+  shouldConvert1 =
+  !Method2 && Method1 && Method1->isImplicitObjectMemberFunction();
+  shouldConvert2 =
+  !Method1 && Method2 && Method2->isImplicitObjectMemberFunction();
+}
+if (shouldConvert1) {
+  bool isR2 =
+  getLangOpts().CPlusPlus20 &&
+  (shouldConvert1
+   ? Method2->getRefQualifier() == RQ_RValue
+   : Proto2->param_type_begin()[0]->isRValueReferenceType());
+  // Compare 'this' from Method1 against first parameter from Method2.
+  ObjType1 = GetImplicitObjectParameterType(this->Context, Method1,
+RawObjType1, isR2);
+  Args1.push_back(ObjType1);
+}
+if (shouldConvert2) {
+  bool isR1 =
+  getLangOpts().CPlusPlus20 &&
+  (shouldConvert2
+   ? Method1->getRefQualifier() == RQ_RValue
+   : Proto1->param_type_begin()[0]->isRValueReferenceType());
+  // Compare 'this' from Method2 against first parameter from Method1.
+  ObjType2 = GetImplicitObjectParameterType(this->Context, Method2,
+RawObjType2, isR1);
+  Args2.push_back(ObjType2);
+}
+unsigned NumComparedArguments = NumCallArguments1 + shouldConvert1;
 
-  bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC,
-  NumCallArguments1, Reversed);
-  bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC,
-  NumCallArguments2, Reversed);
+Args1.insert(Args1.end(), Proto1->param_type_begin(),
+ Proto1->param_type_end());
+Args2.insert(Args2.end(), Proto2->param_type_begin(),
+ Proto2->param_type_end());
 
+// C++ [temp.func.order]p5:
+//   The presence of unused ellipsis and default arguments has no effect on
+//   the partial ordering of function templates.
+if (Args1.size() > NumComparedArguments)

HoBoIs wrote:

   `Args1.resize(std::max(Args1.size(), NumComparedArguments));` is not 
functionally equivalent to what I wrote, and will not work as intended. I need 
to drop elements, not to add new default constructed ones. I think you meant to 
write `min` instead of `max`. 
 Still I don't see why `Args1.resize(min(Args1.size(), NumComparedArguments));` 
is preferable to the original.

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits m

[clang] [clang][analyzer] Add StreamChecker note tags for "indeterminate stream position". (PR #83288)

2024-02-29 Thread via cfe-commits


@@ -313,6 +232,9 @@ class StreamChecker : public Checkerhttps://github.com/llvm/llvm-project/pull/83288
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][analyzer] Add StreamChecker note tags for "indeterminate stream position". (PR #83288)

2024-02-29 Thread via cfe-commits

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


[clang] [clang][analyzer] Add StreamChecker note tags for "indeterminate stream position". (PR #83288)

2024-02-29 Thread via cfe-commits


@@ -607,6 +564,103 @@ class StreamChecker : public Checkerget(StreamSym);
+if (!SS)
+  return false;
+NewES = SS->ErrorState;
+CE = dyn_cast_or_null(Call.getOriginExpr());
+if (!CE)
+  return false;
+
+assertStreamStateOpened(SS);
+
+return true;
+  }
+
+  bool isStreamEof() const { return SS->ErrorState == ErrorFEof; }
+
+  NonLoc getZeroVal(const CallEvent &Call) {
+return *SVB.makeZeroVal(Call.getResultType()).getAs();
+  }
+
+  ProgramStateRef setStreamState(ProgramStateRef State,
+ const StreamState &NewSS) {
+NewES = NewSS.ErrorState;
+return State->set(StreamSym, NewSS);
+  }
+
+  ProgramStateRef makeAndBindRetVal(ProgramStateRef State, CheckerContext &C) {
+NonLoc RetVal = makeRetVal(C, CE).castAs();
+return State->BindExpr(CE, C.getLocationContext(), RetVal);
+  }
+
+  ProgramStateRef bindReturnValue(ProgramStateRef State, CheckerContext &C,
+  uint64_t Val) {
+return State->BindExpr(CE, C.getLocationContext(),
+   SVB.makeIntVal(Val, CE->getCallReturnType(ACtx)));
+  }
+
+  ProgramStateRef bindReturnValue(ProgramStateRef State, CheckerContext &C,
+  SVal Val) {
+return State->BindExpr(CE, C.getLocationContext(), Val);
+  }
+
+  ProgramStateRef bindNullReturnValue(ProgramStateRef State,
+  CheckerContext &C) {
+return State->BindExpr(CE, C.getLocationContext(),
+   C.getSValBuilder().makeNullWithType(CE->getType()));
+  }
+
+  ProgramStateRef assumeBinOpNN(ProgramStateRef State,
+BinaryOperator::Opcode Op, NonLoc LHS,
+NonLoc RHS) {
+auto Cond = SVB.evalBinOpNN(State, Op, LHS, RHS, SVB.getConditionType())
+.getAs();
+if (!Cond)
+  return nullptr;
+return State->assume(*Cond, true);
+  }
+
+  ConstraintManager::ProgramStatePair
+  makeRetValAndAssumeDual(ProgramStateRef State, CheckerContext &C) {
+DefinedSVal RetVal = makeRetVal(C, CE);
+State = State->BindExpr(CE, C.getLocationContext(), RetVal);
+return C.getConstraintManager().assumeDual(State, RetVal);
+  }
+
+  const NoteTag *getStreamErrorNoteTag(const StreamChecker *Ch,

NagyDonat wrote:

It's a bit misleading that the name of this function refers to "Error" while it 
can place both the "Eof" and the "Error" note tags (depending on the 
situation). Try to find a more neutral name like `getStreamStateNoteTag` (or 
something better -- `State` is neutral between `Error` and `Eof`, but is an 
overused word).

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


[clang] [clang][analyzer] Add StreamChecker note tags for "indeterminate stream position". (PR #83288)

2024-02-29 Thread via cfe-commits

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

The change looks reasonable, I only have minor remarks.

Re: your question about changing the warning message, I think that removing the 
single quotes around 'indeterminate' is probably a good idea, but the current 
message is also OK. 

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


[clang] [clang][analyzer] Add StreamChecker note tags for "indeterminate stream position". (PR #83288)

2024-02-29 Thread via cfe-commits


@@ -218,87 +218,6 @@ inline void assertStreamStateOpened(const StreamState *SS) 
{
   assert(SS->isOpened() && "Stream is expected to be opened");
 }
 
-struct StreamOperationEvaluator {

NagyDonat wrote:

Why are you moving the definition of this struct? (Feel free to move it if you 
want, I'm just curious.)

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


[clang] [clang][analyzer] Change default value of checker option in unix.StdCLibraryFunctions. (PR #80457)

2024-02-29 Thread via cfe-commits

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


[clang] [clang][analyzer] Change default value of checker option in unix.StdCLibraryFunctions. (PR #80457)

2024-02-29 Thread via cfe-commits

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

LGTM, I think that it isn't necessary to rerun the tests.

I have one very minor suggestion to slightly improve the documentation. 

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


[clang] [clang][analyzer] Change default value of checker option in unix.StdCLibraryFunctions. (PR #80457)

2024-02-29 Thread via cfe-commits


@@ -1299,10 +1299,21 @@ range of the argument.
 
 **Parameters**
 
-The checker models functions (and emits diagnostics) from the C standard by
-default. The ``ModelPOSIX`` option enables modeling (and emit diagnostics) of
-additional functions that are defined in the POSIX standard. This option is
-disabled by default.
+The ``ModelPOSIX`` option controls if functions from the POSIX standard are
+recognized by the checker. If ``true``, a big amount of POSIX functions is
+modeled according to the
+`POSIX standard`_. This
+includes ranges of parameters and possible return values. Furthermore the
+behavior related to ``errno`` in the POSIX case is often that ``errno`` is set
+only if a function call fails, and it becomes undefined after a successful
+function call.
+If ``false``, functions are modeled according to the C99 language standard.
+This includes far less functions than the POSIX case. It is possible that the
+same functions are modeled differently in the two cases because differences in
+the standards. The C standard specifies less aspects of the functions, for
+example exact ``errno`` behavior is often unspecified (and not modeled by the
+checker).
+Default value of the option is ``true``.

NagyDonat wrote:

```suggestion
The ``ModelPOSIX`` option controls if functions from the POSIX standard are
recognized by the checker.

With ``ModelPOSIX=true``, lots of POSIX functions are modeled according to the
`POSIX standard`_. This includes ranges of parameters and possible return
values. Furthermore the behavior related to ``errno`` in the POSIX case is
often that ``errno`` is set only if a function call fails, and it becomes
undefined after a successful function call.

With ``ModelPOSIX=false``, this checker follows the C99 language standard and
only models the functions that are described there. It is possible that the
same functions are modeled differently in the two cases because differences in
the standards. The C standard specifies less aspects of the functions, for
example exact ``errno`` behavior is often unspecified (and not modeled by the
checker).

Default value of the option is ``true``.
```


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


[clang] [Concepts] Consider outer scope Decls for conversion function constraints (PR #83420)

2024-02-29 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 created 
https://github.com/llvm/llvm-project/pull/83420

This fixes the case shown by 
https://github.com/llvm/llvm-project/issues/64808#issuecomment-1929129271.

Similar to 
https://github.com/llvm/llvm-project/commit/f9caa12328b265b77221fe7a310d4504673d814a,
 we have some calls to constraint checking for a lambda's conversion function 
while determining the conversion sequence.

This patch addresses the problem where the requires-expression within such a 
lambda references to a Decl outside of the lambda by adding these Decls to the 
current instantiation scope.

I'm abusing the flag `ForOverloadResolution` of CheckFunctionConstraints, which 
is actually meant to consider the Decls from parent DeclContexts.

>From 072d2aa8b758d61e0459bd626fbea881c3e1596c Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Thu, 29 Feb 2024 19:47:01 +0800
Subject: [PATCH] [Concepts] Consider outer scope Decls for conversion function
 constraints

This fixes the case shown by 
https://github.com/llvm/llvm-project/issues/64808#issuecomment-1929129271.

Similar to 
https://github.com/llvm/llvm-project/commit/f9caa12328b265b77221fe7a310d4504673d814a,
we have some calls to constraint checking for a lambda's conversion
function while determining the conversion sequence.

This patch addresses the problem where the requires-expression within
such a lambda references to a Decl outside of the lambda by adding
these Decls to the current instantiation scope.

I'm abusing the flag 'ForOverloadResolution' of CheckFunctionConstraints,
which is actually meant to consider the Decls from parent DeclContexts.
---
 clang/docs/ReleaseNotes.rst  |  3 +++
 clang/lib/Sema/SemaOverload.cpp  |  3 ++-
 clang/test/SemaTemplate/concepts.cpp | 29 
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bac166e6c35627..53f8395b6de69d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -275,6 +275,9 @@ Bug Fixes to C++ Support
   (`#82258 `_)
 - Correctly immediate-escalate lambda conversion functions.
   (`#82258 `_)
+- Fixed a crash while checking constraints of a trailing requires-expression 
of a lambda, that the
+  expression references to an entity declared outside of the lambda. This is a 
reduction from
+  (`#64808 `_).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f7645422348b65..40c7d0e17890d0 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7976,7 +7976,8 @@ void Sema::AddConversionCandidate(
 
   if (Conversion->getTrailingRequiresClause()) {
 ConstraintSatisfaction Satisfaction;
-if (CheckFunctionConstraints(Conversion, Satisfaction) ||
+if (CheckFunctionConstraints(Conversion, Satisfaction, /*UsageLoc=*/{},
+ /*ShouldAddDeclsFromParentScope=*/true) ||
 !Satisfaction.IsSatisfied) {
   Candidate.Viable = false;
   Candidate.FailureKind = ovl_fail_constraints_not_satisfied;
diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index bac209a28da912..b7ea0d003a52d7 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1085,3 +1085,32 @@ template void Struct::bar<>();
 template int Struct::field<1, 2>;
 
 }
+
+namespace GH64808 {
+
+template  struct basic_sender {
+  T func;
+  basic_sender(T) : func(T()) {}
+};
+
+auto a = basic_sender{[](auto... __captures) {
+  return []() // #note-a-1
+requires((__captures, ...), false) // #note-a-2
+  {};
+}()};
+
+auto b = basic_sender{[](auto... __captures) {
+  return []()
+requires([](int, double) { return true; }(decltype(__captures)()...))
+  {};
+}(1, 2.33)};
+
+void foo() {
+  a.func();
+  // expected-error@-1{{no matching function for call}}
+  // expected-note@#note-a-1{{constraints not satisfied}}
+  // expected-note@#note-a-2{{evaluated to false}}
+  b.func();
+}
+
+} // namespace GH64808

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


[clang] [llvm] [clang] Use separator for large numeric values in overflow diagnostic (PR #80939)

2024-02-29 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman commented:

You should also add a release note to `clang/docs/ReleaseNotes.rst` to tell 
users about the improved diagnostic behavior.

Aside from some small nits, this looks really close to ready!

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


[clang] [llvm] [clang] Use separator for large numeric values in overflow diagnostic (PR #80939)

2024-02-29 Thread Aaron Ballman via cfe-commits

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


[clang] [llvm] [clang] Use separator for large numeric values in overflow diagnostic (PR #80939)

2024-02-29 Thread Aaron Ballman via cfe-commits


@@ -2223,9 +2227,14 @@ void APInt::toString(SmallVectorImpl &Str, 
unsigned Radix, bool Signed,
   ++Prefix;
 };
 
+int Pos = 0;
 while (N) {
+  if (insertSeparators && Pos % Grouping == 0 && Pos > 0) {
+*--BufPtr = '\'';
+  }

AaronBallman wrote:

```suggestion
  if (insertSeparators && Pos % Grouping == 0 && Pos > 0)
*--BufPtr = '\'';
```
Our coding style guideline is rather unintuitive in that it requires leaving 
braces off single-line substatements like this.

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


[clang] [llvm] [clang] Use separator for large numeric values in overflow diagnostic (PR #80939)

2024-02-29 Thread Aaron Ballman via cfe-commits


@@ -2161,7 +2161,8 @@ void APInt::fromString(unsigned numbits, StringRef str, 
uint8_t radix) {
 }
 
 void APInt::toString(SmallVectorImpl &Str, unsigned Radix, bool Signed,
- bool formatAsCLiteral, bool UpperCase) const {
+ bool formatAsCLiteral, bool UpperCase,
+ bool insertSeparators) const {

AaronBallman wrote:

And here too!

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


[clang] [llvm] [clang] Use separator for large numeric values in overflow diagnostic (PR #80939)

2024-02-29 Thread Aaron Ballman via cfe-commits


@@ -329,9 +329,10 @@ inline std::string itostr(int64_t X) {
 }
 
 inline std::string toString(const APInt &I, unsigned Radix, bool Signed,
-bool formatAsCLiteral = false) {
+bool formatAsCLiteral = false,
+bool upperCase = true, bool addSeparators = false) 
{

AaronBallman wrote:

Same suggestion here as above (amusing that `upperCase` changed styles...).

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


[clang] [llvm] [clang] Use separator for large numeric values in overflow diagnostic (PR #80939)

2024-02-29 Thread Aaron Ballman via cfe-commits


@@ -2257,17 +2266,27 @@ void APInt::toString(SmallVectorImpl &Str, 
unsigned Radix, bool Signed,
 unsigned ShiftAmt = (Radix == 16 ? 4 : (Radix == 8 ? 3 : 1));
 unsigned MaskAmt = Radix - 1;
 
+int Pos = 0;
 while (Tmp.getBoolValue()) {
   unsigned Digit = unsigned(Tmp.getRawData()[0]) & MaskAmt;
+  if (insertSeparators && Pos % Grouping == 0 && Pos > 0) {
+Str.push_back('\'');
+  }

AaronBallman wrote:

Same here as above

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


[clang] [llvm] [clang] Use separator for large numeric values in overflow diagnostic (PR #80939)

2024-02-29 Thread Aaron Ballman via cfe-commits


@@ -1626,7 +1626,8 @@ class [[nodiscard]] APInt {
   /// SmallString. If Radix > 10, UpperCase determine the case of letter
   /// digits.
   void toString(SmallVectorImpl &Str, unsigned Radix, bool Signed,
-bool formatAsCLiteral = false, bool UpperCase = true) const;
+bool formatAsCLiteral = false, bool UpperCase = true,
+bool insertSeparators = false) const;

AaronBallman wrote:

```suggestion
bool InsertSeparators = false) const;
```
This matches our usual coding style and is the prevailing style in the function 
signature (a follow-up NFC change could rename `formatAsCLiteral`).

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


[clang] [llvm] [clang] Use separator for large numeric values in overflow diagnostic (PR #80939)

2024-02-29 Thread Aaron Ballman via cfe-commits


@@ -2257,17 +2266,27 @@ void APInt::toString(SmallVectorImpl &Str, 
unsigned Radix, bool Signed,
 unsigned ShiftAmt = (Radix == 16 ? 4 : (Radix == 8 ? 3 : 1));
 unsigned MaskAmt = Radix - 1;
 
+int Pos = 0;
 while (Tmp.getBoolValue()) {
   unsigned Digit = unsigned(Tmp.getRawData()[0]) & MaskAmt;
+  if (insertSeparators && Pos % Grouping == 0 && Pos > 0) {
+Str.push_back('\'');
+  }
   Str.push_back(Digits[Digit]);
   Tmp.lshrInPlace(ShiftAmt);
+  Pos++;
 }
   } else {
+int Pos = 0;
 while (Tmp.getBoolValue()) {
   uint64_t Digit;
   udivrem(Tmp, Radix, Tmp, Digit);
   assert(Digit < Radix && "divide failed");
+  if (insertSeparators && Pos % Grouping == 0 && Pos > 0) {
+Str.push_back('\'');
+  }

AaronBallman wrote:

Here too

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


[clang] [llvm] [clang] Use separator for large numeric values in overflow diagnostic (PR #80939)

2024-02-29 Thread Aaron Ballman via cfe-commits


@@ -1379,6 +1379,23 @@ TEST(APIntTest, toString) {
   EXPECT_EQ(std::string(S), "0");
   S.clear();
 
+  // with separators
+  APInt(64, 140).toString(S, 2, false, true, false, true);
+  EXPECT_EQ(std::string(S), "0b1000'1100");
+  S.clear();
+  APInt(64, 1024).toString(S, 8, false, true, false, true);
+  EXPECT_EQ(std::string(S), "02'000");
+  S.clear();
+  APInt(64, 100).toString(S, 10, false, true, false, true);
+  EXPECT_EQ(std::string(S), "1'000'000");
+  S.clear();
+  APInt(64, 100).toString(S, 16, false, true, true, true);
+  EXPECT_EQ(std::string(S), "0xF'4240");
+  S.clear();
+  APInt(64, 1'000'000'000).toString(S, 36, false, false, false, true);
+  EXPECT_EQ(std::string(S), "gj'dgxs");

AaronBallman wrote:

lol, I love it (it took me a minute when I saw the expected string).

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


[clang] [clang][analyzer] Change default value of checker option in unix.StdCLibraryFunctions. (PR #80457)

2024-02-29 Thread via cfe-commits

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


[clang] [clang] Clang should detect illegal copy constructor with template class as its parameter (PR #81251)

2024-02-29 Thread Rajveer Singh Bharadwaj via cfe-commits

Rajveer100 wrote:

I have removed this entirely, although it still may not be optimal, it did 
reduce few more test failures:

```C++
Constructor->getTemplateSpecializationKind() !=
  TSK_ImplicitInstantiation
```

Any particular suggestions apart from updating the tests?

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


[clang] [Concepts] Add Decls from the outer scope of the current lambda for conversion function constraints (PR #83420)

2024-02-29 Thread Younan Zhang via cfe-commits

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


[clang] [Concepts] Add Decls from the outer scope of the current lambda for conversion function constraints (PR #83420)

2024-02-29 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/83420

>From 072d2aa8b758d61e0459bd626fbea881c3e1596c Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Thu, 29 Feb 2024 19:47:01 +0800
Subject: [PATCH] [Concepts] Consider outer scope Decls for conversion function
 constraints

This fixes the case shown by 
https://github.com/llvm/llvm-project/issues/64808#issuecomment-1929129271.

Similar to 
https://github.com/llvm/llvm-project/commit/f9caa12328b265b77221fe7a310d4504673d814a,
we have some calls to constraint checking for a lambda's conversion
function while determining the conversion sequence.

This patch addresses the problem where the requires-expression within
such a lambda references to a Decl outside of the lambda by adding
these Decls to the current instantiation scope.

I'm abusing the flag 'ForOverloadResolution' of CheckFunctionConstraints,
which is actually meant to consider the Decls from parent DeclContexts.
---
 clang/docs/ReleaseNotes.rst  |  3 +++
 clang/lib/Sema/SemaOverload.cpp  |  3 ++-
 clang/test/SemaTemplate/concepts.cpp | 29 
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bac166e6c35627..53f8395b6de69d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -275,6 +275,9 @@ Bug Fixes to C++ Support
   (`#82258 `_)
 - Correctly immediate-escalate lambda conversion functions.
   (`#82258 `_)
+- Fixed a crash while checking constraints of a trailing requires-expression 
of a lambda, that the
+  expression references to an entity declared outside of the lambda. This is a 
reduction from
+  (`#64808 `_).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index f7645422348b65..40c7d0e17890d0 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7976,7 +7976,8 @@ void Sema::AddConversionCandidate(
 
   if (Conversion->getTrailingRequiresClause()) {
 ConstraintSatisfaction Satisfaction;
-if (CheckFunctionConstraints(Conversion, Satisfaction) ||
+if (CheckFunctionConstraints(Conversion, Satisfaction, /*UsageLoc=*/{},
+ /*ShouldAddDeclsFromParentScope=*/true) ||
 !Satisfaction.IsSatisfied) {
   Candidate.Viable = false;
   Candidate.FailureKind = ovl_fail_constraints_not_satisfied;
diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index bac209a28da912..b7ea0d003a52d7 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1085,3 +1085,32 @@ template void Struct::bar<>();
 template int Struct::field<1, 2>;
 
 }
+
+namespace GH64808 {
+
+template  struct basic_sender {
+  T func;
+  basic_sender(T) : func(T()) {}
+};
+
+auto a = basic_sender{[](auto... __captures) {
+  return []() // #note-a-1
+requires((__captures, ...), false) // #note-a-2
+  {};
+}()};
+
+auto b = basic_sender{[](auto... __captures) {
+  return []()
+requires([](int, double) { return true; }(decltype(__captures)()...))
+  {};
+}(1, 2.33)};
+
+void foo() {
+  a.func();
+  // expected-error@-1{{no matching function for call}}
+  // expected-note@#note-a-1{{constraints not satisfied}}
+  // expected-note@#note-a-2{{evaluated to false}}
+  b.func();
+}
+
+} // namespace GH64808

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


[clang] [Concepts] Add Decls from the outer scope of the current lambda for conversion function constraints (PR #83420)

2024-02-29 Thread Younan Zhang via cfe-commits

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


[clang] e08fe57 - [NFC][ARM][AArch64] Deduplicated code. (#82785)

2024-02-29 Thread via cfe-commits

Author: Dani
Date: 2024-02-29T14:05:37+01:00
New Revision: e08fe575d5953b6ca0d7a578c1afa00247f0a12f

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

LOG: [NFC][ARM][AArch64] Deduplicated code. (#82785)

Add the SignReturnAddressScopeKind to the BranchProtectionInfo class.

Added: 


Modified: 
clang/include/clang/Basic/TargetInfo.h
clang/lib/CodeGen/Targets/AArch64.cpp
clang/lib/CodeGen/Targets/ARM.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 48e9cec482755c..b94d13609c3dd2 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1369,13 +1369,35 @@ class TargetInfo : public TransferrableTargetInfo,
   }
 
   struct BranchProtectionInfo {
-LangOptions::SignReturnAddressScopeKind SignReturnAddr =
-LangOptions::SignReturnAddressScopeKind::None;
-LangOptions::SignReturnAddressKeyKind SignKey =
-LangOptions::SignReturnAddressKeyKind::AKey;
-bool BranchTargetEnforcement = false;
-bool BranchProtectionPAuthLR = false;
-bool GuardedControlStack = false;
+LangOptions::SignReturnAddressScopeKind SignReturnAddr;
+LangOptions::SignReturnAddressKeyKind SignKey;
+bool BranchTargetEnforcement;
+bool BranchProtectionPAuthLR;
+bool GuardedControlStack;
+
+BranchProtectionInfo() = default;
+
+const char *getSignReturnAddrStr() const {
+  switch (SignReturnAddr) {
+  case LangOptions::SignReturnAddressScopeKind::None:
+return "none";
+  case LangOptions::SignReturnAddressScopeKind::NonLeaf:
+return "non-leaf";
+  case LangOptions::SignReturnAddressScopeKind::All:
+return "all";
+  }
+  assert(false && "Unexpected SignReturnAddressScopeKind");
+}
+
+const char *getSignKeyStr() const {
+  switch (SignKey) {
+  case LangOptions::SignReturnAddressKeyKind::AKey:
+return "a_key";
+  case LangOptions::SignReturnAddressKeyKind::BKey:
+return "b_key";
+  }
+  assert(false && "Unexpected SignReturnAddressKeyKind");
+}
   };
 
   /// Determine if the Architecture in this TargetInfo supports branch

diff  --git a/clang/lib/CodeGen/Targets/AArch64.cpp 
b/clang/lib/CodeGen/Targets/AArch64.cpp
index adfdd516351901..2b8e2aeb4265f3 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -132,8 +132,7 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
 assert(Error.empty());
 
 auto *Fn = cast(GV);
-static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"};
-Fn->addFnAttr("sign-return-address", 
SignReturnAddrStr[static_cast(BPI.SignReturnAddr)]);
+Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
 
 if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
   Fn->addFnAttr("sign-return-address-key",

diff  --git a/clang/lib/CodeGen/Targets/ARM.cpp 
b/clang/lib/CodeGen/Targets/ARM.cpp
index d7d175ff1724f7..5d42e6286e525b 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -152,13 +152,7 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
   diag::warn_target_unsupported_branch_protection_attribute)
   << Arch;
 } else {
-  static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"};
-  assert(static_cast(BPI.SignReturnAddr) <= 2 &&
- "Unexpected SignReturnAddressScopeKind");
-  Fn->addFnAttr(
-  "sign-return-address",
-  SignReturnAddrStr[static_cast(BPI.SignReturnAddr)]);
-
+  Fn->addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
   Fn->addFnAttr("branch-target-enforcement",
 BPI.BranchTargetEnforcement ? "true" : "false");
 }



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


[clang] [NFC][ARM][AArch64] Deduplicated code. (PR #82785)

2024-02-29 Thread via cfe-commits

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


[clang] [llvm] [AMDGPU] Add an option to disable unsafe uses of atomic xor (PR #69229)

2024-02-29 Thread Pierre-Andre Saulais via cfe-commits

pasaulais wrote:

> > In this case, MMRAs would only help in the sense that you won't need any 
> > new attributes and can just add an MMRA such as 
> > `atomic-lowering:fine-grained`. It's not really what MMRAs were made for 
> > (because this attribute doesn't affect semantics, just lowering style I 
> > think?),
> 
> It is semantics. You get undefined behavior if you access fine grained memory 
> for an atomic where the instruction doesn't handle it. I don't think it quite 
> fits into the MMRA box, since it isn't about the synchronization properties 
> of the memory access but where the underlying memory is

@arsenm That makes sense, I don't think MMRA fits the fine-grained use case 
either. Does that mean we can stick with the approach from this PR? @b-sumner 
mentioned there was another similar approach being worked on.

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


[clang] [clang][dataflow] Correctly treat empty initializer lists for unions. (PR #82986)

2024-02-29 Thread via cfe-commits


@@ -685,9 +685,22 @@ class TransferVisitor : public 
ConstStmtVisitor {
 
 // `S->inits()` contains all the initializer expressions, including the
 // ones for direct base classes.
-auto Inits = S->inits();
+ArrayRef Inits = S->inits();
 size_t InitIdx = 0;
 
+// Unions initialized with an empty initializer list need special 
treatment.

martinboehme wrote:

It appears that CodeGen also appears to special-case this like we do:

https://github.com/llvm/llvm-project/blob/e08fe575d5953b6ca0d7a578c1afa00247f0a12f/clang/lib/CodeGen/CGExprAgg.cpp#L1760

And if we changed the AST so that we had an `ImplicitValueInitExpr` here, it 
looks as if the general case in CodeGen would do the right thing.

I'll make a note of this for myself.

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


[clang] [clang][dataflow] Correctly treat empty initializer lists for unions. (PR #82986)

2024-02-29 Thread via cfe-commits

https://github.com/martinboehme updated 
https://github.com/llvm/llvm-project/pull/82986

>From cd64b0e04026235283016eaf1cd601076ab7aeb2 Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Tue, 27 Feb 2024 18:23:36 +
Subject: [PATCH 1/3] Reapply "[clang][dataflow] Correctly handle
 `InitListExpr` of union type." (#82856)

This reverts commit c4e94633e8a48ee33115d5d3161ee142fc1c9700.
---
 .../FlowSensitive/DataflowEnvironment.h   |  9 ---
 .../FlowSensitive/DataflowEnvironment.cpp | 18 ++---
 clang/lib/Analysis/FlowSensitive/Transfer.cpp | 25 +++
 .../Analysis/FlowSensitive/TestingSupport.h   | 19 ++
 .../Analysis/FlowSensitive/TransferTest.cpp   | 14 +--
 5 files changed, 65 insertions(+), 20 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 7f8c70d169376e..62e7af7ac219bc 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -723,9 +723,12 @@ RecordStorageLocation *getImplicitObjectLocation(const 
CXXMemberCallExpr &MCE,
 RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
  const Environment &Env);
 
-/// Returns the fields of `RD` that are initialized by an `InitListExpr`, in 
the
-/// order in which they appear in `InitListExpr::inits()`.
-std::vector getFieldsForInitListExpr(const RecordDecl *RD);
+/// Returns the fields of a `RecordDecl` that are initialized by an
+/// `InitListExpr`, in the order in which they appear in
+/// `InitListExpr::inits()`.
+/// `Init->getType()` must be a record type.
+std::vector
+getFieldsForInitListExpr(const InitListExpr *InitList);
 
 /// Associates a new `RecordValue` with `Loc` and returns the new value.
 RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env);
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index d487944ce92111..0cfc26ea952cda 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -361,8 +361,8 @@ getFieldsGlobalsAndFuncs(const Stmt &S, FieldSet &Fields,
 if (const auto *FD = dyn_cast(VD))
   Fields.insert(FD);
   } else if (auto *InitList = dyn_cast(&S)) {
-if (RecordDecl *RD = InitList->getType()->getAsRecordDecl())
-  for (const auto *FD : getFieldsForInitListExpr(RD))
+if (InitList->getType()->isRecordType())
+  for (const auto *FD : getFieldsForInitListExpr(InitList))
 Fields.insert(FD);
   }
 }
@@ -1104,12 +1104,22 @@ RecordStorageLocation *getBaseObjectLocation(const 
MemberExpr &ME,
   return Env.get(*Base);
 }
 
-std::vector getFieldsForInitListExpr(const RecordDecl *RD) {
+std::vector
+getFieldsForInitListExpr(const InitListExpr *InitList) {
+  const RecordDecl *RD = InitList->getType()->getAsRecordDecl();
+  assert(RD != nullptr);
+
+  std::vector Fields;
+
+  if (InitList->getType()->isUnionType()) {
+Fields.push_back(InitList->getInitializedFieldInUnion());
+return Fields;
+  }
+
   // Unnamed bitfields are only used for padding and do not appear in
   // `InitListExpr`'s inits. However, those fields do appear in `RecordDecl`'s
   // field list, and we thus need to remove them before mapping inits to
   // fields to avoid mapping inits to the wrongs fields.
-  std::vector Fields;
   llvm::copy_if(
   RD->fields(), std::back_inserter(Fields),
   [](const FieldDecl *Field) { return !Field->isUnnamedBitfield(); });
diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp 
b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index 089854264f483a..3f7e2e27d25cfd 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -663,14 +663,7 @@ class TransferVisitor : public 
ConstStmtVisitor {
   void VisitInitListExpr(const InitListExpr *S) {
 QualType Type = S->getType();
 
-if (Type->isUnionType()) {
-  // FIXME: Initialize unions properly.
-  if (auto *Val = Env.createValue(Type))
-Env.setValue(*S, *Val);
-  return;
-}
-
-if (!Type->isStructureOrClassType()) {
+if (!Type->isRecordType()) {
   // Until array initialization is implemented, we skip arrays and don't
   // need to care about cases where `getNumInits() > 1`.
   if (!Type->isArrayType() && S->getNumInits() == 1)
@@ -688,10 +681,9 @@ class TransferVisitor : public 
ConstStmtVisitor {
 llvm::DenseMap FieldLocs;
 
 // This only contains the direct fields for the given type.
-std::vector FieldsForInit =
-getFieldsForInitListExpr(Type->getAsRecordDecl());
+std::vector FieldsForInit = getFieldsForInitListExpr(S);
 
-// `S->inits()` contains all the initializer epressions, including the
+// `S->inits

[clang] [clang][dataflow] Correctly treat empty initializer lists for unions. (PR #82986)

2024-02-29 Thread via cfe-commits


@@ -2392,14 +2392,88 @@ TEST(TransferTest, InitListExprAsUnion) {
   } F;
 
  public:
-  constexpr target() : F{nullptr} {}
+  constexpr target() : F{nullptr} {
+int *null = nullptr;
+F.b;  // Make sure we reference 'b' so it is modeled.
+// [[p]]
+  }
 };
   )cc";
   runDataflow(
   Code,
   [](const llvm::StringMap> &Results,
  ASTContext &ASTCtx) {
-// Just verify that it doesn't crash.
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto &FLoc = getFieldLoc(
+*Env.getThisPointeeStorageLocation(), "F", ASTCtx);
+auto *AVal = cast(getFieldValue(&FLoc, "a", ASTCtx, 
Env));
+EXPECT_EQ(AVal, &getValueForDecl(ASTCtx, Env, "null"));
+EXPECT_EQ(getFieldValue(&FLoc, "b", ASTCtx, Env), nullptr);
+  });
+}
+
+TEST(TransferTest, EmptyInitListExprForUnion) {
+  // This is a crash repro.
+  std::string Code = R"cc(
+class target {
+  union {
+int *a;
+bool *b;
+  } F;
+
+ public:
+  constexpr target() : F{} {
+int *null = nullptr;
+F.b;  // Make sure we reference 'b' so it is modeled.
+// [[p]]
+  }
+};
+  )cc";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto &FLoc = getFieldLoc(
+*Env.getThisPointeeStorageLocation(), "F", ASTCtx);
+auto *AVal = cast(getFieldValue(&FLoc, "a", ASTCtx, 
Env));
+EXPECT_EQ(AVal, &getValueForDecl(ASTCtx, Env, "null"));
+EXPECT_EQ(getFieldValue(&FLoc, "b", ASTCtx, Env), nullptr);
+  });
+}
+
+TEST(TransferTest, EmptyInitListExprForStruct) {
+  std::string Code = R"cc(
+class target {
+  struct {
+int *a;
+bool *b;
+  } F;
+
+ public:
+  constexpr target() : F{} {
+int *NullIntPtr = nullptr;
+bool *NullBoolPtr = nullptr;
+// [[p]]
+  }
+};
+  )cc";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto &FLoc = getFieldLoc(
+*Env.getThisPointeeStorageLocation(), "F", ASTCtx);
+auto *AVal = cast(getFieldValue(&FLoc, "a", ASTCtx, 
Env));
+ASSERT_EQ(AVal,

martinboehme wrote:

Good point -- these should have been `EXPECT_EQ`. Changed.

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


[clang] [clang][dataflow] Correctly treat empty initializer lists for unions. (PR #82986)

2024-02-29 Thread via cfe-commits


@@ -2392,14 +2392,88 @@ TEST(TransferTest, InitListExprAsUnion) {
   } F;
 
  public:
-  constexpr target() : F{nullptr} {}
+  constexpr target() : F{nullptr} {
+int *null = nullptr;
+F.b;  // Make sure we reference 'b' so it is modeled.
+// [[p]]
+  }
 };
   )cc";
   runDataflow(
   Code,
   [](const llvm::StringMap> &Results,
  ASTContext &ASTCtx) {
-// Just verify that it doesn't crash.
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto &FLoc = getFieldLoc(
+*Env.getThisPointeeStorageLocation(), "F", ASTCtx);
+auto *AVal = cast(getFieldValue(&FLoc, "a", ASTCtx, 
Env));
+EXPECT_EQ(AVal, &getValueForDecl(ASTCtx, Env, "null"));
+EXPECT_EQ(getFieldValue(&FLoc, "b", ASTCtx, Env), nullptr);
+  });
+}
+
+TEST(TransferTest, EmptyInitListExprForUnion) {
+  // This is a crash repro.
+  std::string Code = R"cc(
+class target {
+  union {
+int *a;
+bool *b;
+  } F;
+
+ public:
+  constexpr target() : F{} {
+int *null = nullptr;
+F.b;  // Make sure we reference 'b' so it is modeled.
+// [[p]]
+  }
+};
+  )cc";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+auto &FLoc = getFieldLoc(
+*Env.getThisPointeeStorageLocation(), "F", ASTCtx);
+auto *AVal = cast(getFieldValue(&FLoc, "a", ASTCtx, 
Env));

martinboehme wrote:

I've added a comment explaining what the language rules are that govern the 
behavior we expect here.

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


[clang] [llvm] [AMDGPU] Add an option to disable unsafe uses of atomic xor (PR #69229)

2024-02-29 Thread Matt Arsenault via cfe-commits

arsenm wrote:

> @arsenm That makes sense, I don't think MMRA fits the fine-grained use case 
> either. Does that mean we can stick with the approach from this PR? @b-sumner 
> mentioned there was another similar approach being worked on.

Something like this, but the naming and direction of this PR is backwards. The 
default should be assume fine grained memory is possible. We also have another 
orthogonal bit we need to track in addition to fine grained memory. I was 
envisioning this as a single integer interpreted as bitfields of the two, but 
this uses different key:value metadata pairs. It should be named 
"amdgpu.no.something" to assert the operation doesn't access fine grained 

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


[clang] [llvm] [AMDGPU] Emit a waitcnt instruction after each memory instruction (PR #79236)

2024-02-29 Thread Matt Arsenault via cfe-commits


@@ -2561,6 +2567,70 @@ bool SIMemoryLegalizer::expandAtomicCmpxchgOrRmw(const 
SIMemOpInfo &MOI,
   return Changed;
 }
 
+bool SIMemoryLegalizer::GFX9InsertWaitcntForPreciseMem(MachineFunction &MF) {
+  const GCNSubtarget &ST = MF.getSubtarget();
+  const SIInstrInfo *TII = ST.getInstrInfo();
+  IsaVersion IV = getIsaVersion(ST.getCPU());
+
+  bool Changed = false;
+
+  for (auto &MBB : MF) {
+for (auto MI = MBB.begin(); MI != MBB.end();) {
+  MachineInstr &Inst = *MI;
+  ++MI;
+  if (Inst.mayLoadOrStore() == false)
+continue;
+
+  // Todo: if next insn is an s_waitcnt
+  AMDGPU::Waitcnt Wait;
+
+  if (!(Inst.getDesc().TSFlags & SIInstrFlags::maybeAtomic)) {
+if (TII->isSMRD(Inst)) {  // scalar

arsenm wrote:

Both the memory legalizer and SIInsertWaitcnts are required passes. This 
feature is not optional if requested. I do think this makes more sense to 
belong in SIInsertWaitcnts

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


[clang] [HIP] fix host min/max in header (PR #82956)

2024-02-29 Thread Yaxun Liu via cfe-commits

yxsamliu wrote:

> > Probably I need to define those functions with mixed args by default to 
> > avoid regressions.
> 
> Are there any other regressions? Can hupCUB be fixed instead? While their use 
> case is probably benign, I'd rather fix the user code, than propagate CUDA 
> bugs into HIP.

So far we only found this issue in our internal CI. I will try asking hipCUB to 
fix it on their side.

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


[clang] [llvm] [AMDGPU]: Add and codegen sched_group_barrier_inst (PR #78775)

2024-02-29 Thread Matt Arsenault via cfe-commits

https://github.com/arsenm commented:

I don't really understand all of these manual scheduling control intrinsic. 
This brings the total up to 4? I think effort would be better spent making the 
scheduler better instead of giving users more footguns to shoot themselves (and 
the compiler) with

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


[clang] [clang-cl] Fix value of __FUNCTION__ in MSVC mode. (PR #67592)

2024-02-29 Thread Zahira Ammarguellat via cfe-commits

https://github.com/zahiraam updated 
https://github.com/llvm/llvm-project/pull/67592

>From 55b67a58ef8b9856e5f0a8f535b8617f59711dec Mon Sep 17 00:00:00 2001
From: Ammarguellat 
Date: Wed, 27 Sep 2023 11:59:04 -0700
Subject: [PATCH 01/19] Fix value of __FUNCTION__ and __func__ in MSVC mode.

---
 clang/lib/AST/Expr.cpp|  9 ++-
 clang/lib/AST/TypePrinter.cpp | 21 +-
 clang/test/Analysis/eval-predefined-exprs.cpp |  4 +-
 .../CodeGenCXX/mangle-nttp-anon-union.cpp |  2 +-
 clang/test/CodeGenCXX/predefined-expr.cpp | 18 -
 clang/test/SemaCXX/source_location.cpp| 72 +++
 6 files changed, 99 insertions(+), 27 deletions(-)

diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index af82ca0784af41..49f3495c090f19 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -773,8 +773,8 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const 
Decl *CurrentDecl) {
   }
   if (const FunctionDecl *FD = dyn_cast(CurrentDecl)) {
 const auto &LO = Context.getLangOpts();
-if (((IK == Func || IK == Function) && !LO.MicrosoftExt) ||
-(IK == LFunction && LO.MicrosoftExt))
+if (((IK == Function || IK == Func) && !LO.MicrosoftExt) ||
+((IK == LFunction || IK == Func) && LO.MicrosoftExt))
   return FD->getNameAsString();
 
 SmallString<256> Name;
@@ -804,7 +804,10 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, 
const Decl *CurrentDecl) {
 PrintingPolicy Policy(LO);
 PrettyCallbacks PrettyCB(LO);
 Policy.Callbacks = &PrettyCB;
-Policy.UseClassForTemplateArgument = LO.MicrosoftExt;
+if (IK == Function && LO.MicrosoftExt) {
+  Policy.UseClassForTemplateArgument = LO.MicrosoftExt;
+  Policy.MSVCFormatting = LO.MicrosoftExt;
+}
 std::string Proto;
 llvm::raw_string_ostream POut(Proto);
 
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 3771a29f26b173..8a7cf85cdf126b 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -2195,6 +2195,7 @@ printTo(raw_ostream &OS, ArrayRef Args, const 
PrintingPolicy &Policy,
 llvm::SmallVector OrigArgs;
 for (const TA &A : Args)
   OrigArgs.push_back(getArgument(A));
+
 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())
   Args = Args.drop_back();
   }
@@ -2218,10 +2219,24 @@ printTo(raw_ostream &OS, ArrayRef Args, const 
PrintingPolicy &Policy,
 } else {
   if (!FirstArg)
 OS << Comma;
-  if (Policy.UseClassForTemplateArgument &&
-  Argument.getKind() == TemplateArgument::Type)
-OS << "class ";
 
+  if (Policy.MSVCFormatting && Policy.UseClassForTemplateArgument &&
+  Argument.getKind() == TemplateArgument::Type &&
+  !Argument.getAsType()->isBuiltinType()) {
+const Type *Ty = Argument.getAsType().getTypePtr();
+const char *kw;
+if (Ty->isStructureType())
+  kw = "struct ";
+else if (Ty->isClassType())
+  kw = "class ";
+else if (Ty->isUnionType())
+  kw = "union ";
+else if (Ty->isEnumeralType())
+  kw = "enum ";
+else
+  llvm_unreachable("argument type not expected");
+OS << kw;
+  }
   // Tries to print the argument with location info if exists.
   printArgument(Arg, Policy, ArgOS,
 TemplateParameterList::shouldIncludeTypeForArgument(
diff --git a/clang/test/Analysis/eval-predefined-exprs.cpp 
b/clang/test/Analysis/eval-predefined-exprs.cpp
index 7be441eb5bad94..a6bac5ee9d486d 100644
--- a/clang/test/Analysis/eval-predefined-exprs.cpp
+++ b/clang/test/Analysis/eval-predefined-exprs.cpp
@@ -56,7 +56,7 @@ struct A {
 clang_analyzer_dump(__FUNCTION__);
 clang_analyzer_dump(__PRETTY_FUNCTION__);
 #ifdef ANALYZER_MS
-// expected-warning@-4 {{&Element{"A::A",0 S64b,char}}}
+// expected-warning@-4 {{&Element{"A",0 S64b,char}}}
 // expected-warning@-4 {{&Element{"A::A",0 S64b,char}}}
 #else
 // expected-warning@-7 {{&Element{"A",0 S64b,char}}}
@@ -80,7 +80,7 @@ struct A {
 clang_analyzer_dump(__FUNCTION__);
 clang_analyzer_dump(__PRETTY_FUNCTION__);
 #ifdef ANALYZER_MS
-// expected-warning@-4 {{&Element{"A::~A",0 S64b,char}}}
+// expected-warning@-4 {{&Element{"~A",0 S64b,char}}}
 // expected-warning@-4 {{&Element{"A::~A",0 S64b,char}}}
 #else
 // expected-warning@-7 {{&Element{"~A",0 S64b,char}}}
diff --git a/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp 
b/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp
index 78fa7c378c88d5..1982a3eeb94129 100644
--- a/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp
+++ b/clang/test/CodeGenCXX/mangle-nttp-anon-union.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o - -triple=x86_64-linux-gnu | 
FileCheck %s
-// RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o - -triple=x86_64-linux-gnu | 
llvm-cxxfilt -n | FileCheck %s --check-prefix D

[clang] [Concepts] Add Decls from the outer scope of the current lambda for conversion function constraints (PR #83420)

2024-02-29 Thread Younan Zhang via cfe-commits

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


[clang] [Concepts] Add Decls from the outer scope of the current lambda for conversion function constraints (PR #83420)

2024-02-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)


Changes

This fixes the case shown by 
https://github.com/llvm/llvm-project/issues/64808#issuecomment-1929131611.

Similar to 
https://github.com/llvm/llvm-project/commit/f9caa12328b265b77221fe7a310d4504673d814a,
 we have some calls to constraint checking for a lambda's conversion function 
while determining the conversion sequence.

This patch addresses the problem where the requires-expression within such a 
lambda references to a Decl outside of the lambda by adding these Decls to the 
current instantiation scope.

I'm abusing the flag `ForOverloadResolution` of CheckFunctionConstraints, which 
is actually meant to consider the Decls from parent DeclContexts.

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


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+3) 
- (modified) clang/lib/Sema/SemaOverload.cpp (+2-1) 
- (modified) clang/test/SemaTemplate/concepts.cpp (+29) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7e16b9f0c67dbd..10f7e7129e97ac 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -290,6 +290,9 @@ Bug Fixes to C++ Support
   lookup searches the bases of an incomplete class.
 - Fix a crash when an unresolved overload set is encountered on the RHS of a 
``.*`` operator.
   (`#53815 `_)
+- Fixed a crash while checking constraints of a trailing requires-expression 
of a lambda, that the
+  expression references to an entity declared outside of the lambda. This is a 
reduction from
+  (`#64808 `_).
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..f6a2cfa60892f9 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7976,7 +7976,8 @@ void Sema::AddConversionCandidate(
 
   if (Conversion->getTrailingRequiresClause()) {
 ConstraintSatisfaction Satisfaction;
-if (CheckFunctionConstraints(Conversion, Satisfaction) ||
+if (CheckFunctionConstraints(Conversion, Satisfaction, /*UsageLoc=*/{},
+ /*ShouldAddDeclsFromParentScope=*/true) ||
 !Satisfaction.IsSatisfied) {
   Candidate.Viable = false;
   Candidate.FailureKind = ovl_fail_constraints_not_satisfied;
diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index bac209a28da912..b7ea0d003a52d7 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1085,3 +1085,32 @@ template void Struct::bar<>();
 template int Struct::field<1, 2>;
 
 }
+
+namespace GH64808 {
+
+template  struct basic_sender {
+  T func;
+  basic_sender(T) : func(T()) {}
+};
+
+auto a = basic_sender{[](auto... __captures) {
+  return []() // #note-a-1
+requires((__captures, ...), false) // #note-a-2
+  {};
+}()};
+
+auto b = basic_sender{[](auto... __captures) {
+  return []()
+requires([](int, double) { return true; }(decltype(__captures)()...))
+  {};
+}(1, 2.33)};
+
+void foo() {
+  a.func();
+  // expected-error@-1{{no matching function for call}}
+  // expected-note@#note-a-1{{constraints not satisfied}}
+  // expected-note@#note-a-2{{evaluated to false}}
+  b.func();
+}
+
+} // namespace GH64808

``




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


[clang] 86f4b4d - [OpenACC] Implement Compute Construct 'goto' in/out logic (#83326)

2024-02-29 Thread via cfe-commits

Author: Erich Keane
Date: 2024-02-29T06:06:57-08:00
New Revision: 86f4b4dfde543287c1b29ecae27cc1bee470eebb

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

LOG: [OpenACC] Implement Compute Construct 'goto' in/out logic (#83326)

Compute Constructs do not permit jumping in/out of them, so this patch
implements this for 'goto' as a followup to the other patches that have
done the same thing.

It does this by modifying the JumpDiagnostics to work with this, plus
setting the function to needing jump diagnostics if we discover a goto
or label inside of a Compute Construct.

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/JumpDiagnostics.cpp
clang/lib/Sema/SemaStmt.cpp
clang/test/SemaOpenACC/no-branch-in-out.c

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f726805dc02bd9..378b537e029710 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12214,4 +12214,8 @@ def err_acc_construct_appertainment
 def err_acc_branch_in_out_compute_construct
 : Error<"invalid %select{branch|return}0 %select{out of|into}1 OpenACC "
 "Compute Construct">;
+def note_acc_branch_into_compute_construct
+: Note<"invalid branch into OpenACC Compute Construct">;
+def note_acc_branch_out_of_compute_construct
+: Note<"invalid branch out of OpenACC Compute Construct">;
 } // end of sema component.

diff  --git a/clang/lib/Sema/JumpDiagnostics.cpp 
b/clang/lib/Sema/JumpDiagnostics.cpp
index ec3892e92f3c3b..6722878883be8e 100644
--- a/clang/lib/Sema/JumpDiagnostics.cpp
+++ b/clang/lib/Sema/JumpDiagnostics.cpp
@@ -604,6 +604,16 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S,
 break;
   }
 
+  case Stmt::OpenACCComputeConstructClass: {
+unsigned NewParentScope = Scopes.size();
+OpenACCComputeConstruct *CC = cast(S);
+Scopes.push_back(GotoScope(
+ParentScope, diag::note_acc_branch_into_compute_construct,
+diag::note_acc_branch_out_of_compute_construct, CC->getBeginLoc()));
+BuildScopeInformation(CC->getStructuredBlock(), NewParentScope);
+return;
+  }
+
   default:
 if (auto *ED = dyn_cast(S)) {
   if (!ED->isStandaloneDirective()) {
@@ -936,11 +946,16 @@ void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, 
SourceLocation DiagLoc,
   if (Scopes[I].InDiag == diag::note_protected_by_seh_finally) {
 S.Diag(From->getBeginLoc(), diag::warn_jump_out_of_seh_finally);
 break;
-  }
-  if (Scopes[I].InDiag == diag::note_omp_protected_structured_block) {
+  } else if (Scopes[I].InDiag ==
+ diag::note_omp_protected_structured_block) {
 S.Diag(From->getBeginLoc(), diag::err_goto_into_protected_scope);
 S.Diag(To->getBeginLoc(), diag::note_omp_exits_structured_block);
 break;
+  } else if (Scopes[I].InDiag ==
+ diag::note_acc_branch_into_compute_construct) {
+S.Diag(From->getBeginLoc(), diag::err_goto_into_protected_scope);
+S.Diag(Scopes[I].Loc, diag::note_acc_branch_out_of_compute_construct);
+return;
   }
 }
   }

diff  --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 0a5c2b23a90c8e..ca2d206752744c 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -567,6 +567,11 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl 
*TheDecl,
 Diag(IdentLoc, diag::warn_reserved_extern_symbol)
 << TheDecl << static_cast(Status);
 
+  // If this label is in a compute construct scope, we need to make sure we
+  // check gotos in/out.
+  if (getCurScope()->isInOpenACCComputeConstructScope())
+setFunctionHasBranchProtectedScope();
+
   // Otherwise, things are good.  Fill in the declaration and return it.
   LabelStmt *LS = new (Context) LabelStmt(IdentLoc, TheDecl, SubStmt);
   TheDecl->setStmt(LS);
@@ -3304,6 +3309,12 @@ StmtResult Sema::ActOnGotoStmt(SourceLocation GotoLoc,
SourceLocation LabelLoc,
LabelDecl *TheDecl) {
   setFunctionHasBranchIntoScope();
+
+  // If this goto is in a compute construct scope, we need to make sure we 
check
+  // gotos in/out.
+  if (getCurScope()->isInOpenACCComputeConstructScope())
+setFunctionHasBranchProtectedScope();
+
   TheDecl->markUsed(Context);
   return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);
 }
@@ -3332,6 +3343,11 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, 
SourceLocation StarLoc,
 
   setFunctionHasIndirectGoto();
 
+  // If this goto is in a compute construct scope, we need to make sure we
+  // check gotos in/out.
+  if (getCurScope()->

[clang] [OpenACC] Implement Compute Construct 'goto' in/out logic (PR #83326)

2024-02-29 Thread Erich Keane via cfe-commits

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


[clang] 6f7d824 - [Clang][Sema]: Diagnose lambda to bool implicit casts (#83152)

2024-02-29 Thread via cfe-commits

Author: Vinayak Dev
Date: 2024-02-29T09:09:39-05:00
New Revision: 6f7d824b804b272335d55f5b899295db833f3829

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

LOG: [Clang][Sema]: Diagnose lambda to bool implicit casts (#83152)

Adds diagnostics for lambda expressions being cast to boolean values,
which results in the expression always evaluating to true.
Earlier, Clang allowed compilation of such erroneous programs, but now
emits a warning through `-Wpointer-bool-conversion`.

Fixes #82512

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaChecking.cpp
clang/test/CXX/drs/dr18xx.cpp
clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
clang/test/SemaCXX/warn-bool-conversion.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7e16b9f0c67dbd..a5c6b80c4e99e1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -192,6 +192,9 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses declarative nested name specifiers that name alias 
templates.
 
+- Clang now diagnoses lambda function expressions being implicitly cast to 
boolean values, under ``-Wpointer-bool-conversion``.
+  Fixes `#82512 `_.
+
 Improvements to Clang's time-trace
 --
 

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 378b537e029710..ff88c4f293abfd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4127,8 +4127,8 @@ def ext_ms_impcast_fn_obj : ExtWarn<
   "Microsoft extension">, InGroup;
 
 def warn_impcast_pointer_to_bool : Warning<
-"address of%select{| function| array}0 '%1' will always evaluate to "
-"'true'">,
+"address of %select{'%1'|function '%1'|array '%1'|lambda function pointer "
+"conversion operator}0 will always evaluate to 'true'">,
 InGroup;
 def warn_cast_nonnull_to_bool : Warning<
 "nonnull %select{function call|parameter}0 '%1' will evaluate to "

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 979b63884359fc..35d453e013e84b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16544,6 +16544,17 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (const auto *MRecordDecl = MCallExpr->getRecordDecl();
+MRecordDecl && MRecordDecl->isLambda()) {
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*LambdaPointerConversionOperatorType=*/3
+  << MRecordDecl->getSourceRange() << Range << IsEqual;
+  return;
+}
+  }
+
   // Expect to find a single Decl.  Skip anything more complicated.
   ValueDecl *D = nullptr;
   if (DeclRefExpr *R = dyn_cast(E)) {

diff  --git a/clang/test/CXX/drs/dr18xx.cpp b/clang/test/CXX/drs/dr18xx.cpp
index a7cee4ef8902f9..e78730e8992cf8 100644
--- a/clang/test/CXX/drs/dr18xx.cpp
+++ b/clang/test/CXX/drs/dr18xx.cpp
@@ -282,6 +282,7 @@ namespace dr1837 { // dr1837: 3.3
   struct A {
 int f();
 bool b = [] {
+  // since-cxx11-warning@-1 {{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
   struct Local {
 static_assert(sizeof(this->f()) == sizeof(int), "");
   };

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm 
b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
index cb56f6816ad036..e93c37f3b9ae12 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
@@ -65,10 +65,10 @@ void nesting() {
 
 namespace overloading {
   void bool_conversion() {
-if ([](){}) {
+if ([](){}) { // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 }
 
-bool b = []{};
+bool b = []{}; // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 b = (bool)[]{};
   }
 
@@ -108,8 +108,9 @@ void call_with_lambda() {
 using decltype(a)::operator id; // expected-note {{here}}
   } extern d;
 
-  bool r1 = c;
-  bool r2 = d; // expected-error {{private}}
+  bool r1 = c; // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
+  bool r2 = d; // expected-error {{private}} \
+  expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 

[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-29 Thread Aaron Ballman via cfe-commits

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


[clang] [OpenMP] Clang Codegen Interop : Accept multiple use & destroy clauses (PR #83398)

2024-02-29 Thread Alexey Bataev via cfe-commits

https://github.com/alexey-bataev approved this pull request.

LG

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


[clang] [clang][analyzer]Add C++ polymorphic ptr arithmetic checker (PR #82977)

2024-02-29 Thread via cfe-commits

Discookie wrote:

That's a great heuristic! I wonder if there are false positives for this in the 
wild, will need to test on some projects.

I don't know about implementing it as a Clang warning - it probably wouldn't 
cause much of a performance penalty, but I'm not sure about the other 
requirements for such a warning. Would you recommend to implement the heuristic 
as a Tidy checker first, or go implement it as a warning directly? I think the 
required type info is also visible to Tidy.

I guess if I'm also going through with the heuristic, then I can mark this 
patch as abandoned.

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


[clang] [HIP] fix host min/max in header (PR #82956)

2024-02-29 Thread Yaxun Liu via cfe-commits

yxsamliu wrote:

> > > Probably I need to define those functions with mixed args by default to 
> > > avoid regressions.
> > 
> > 
> > Are there any other regressions? Can hupCUB be fixed instead? While their 
> > use case is probably benign, I'd rather fix the user code, than propagate 
> > CUDA bugs into HIP.
> 
> So far we only found this issue in our internal CI. I will try asking hipCUB 
> to fix it on their side.

hipCUB issue opened https://github.com/ROCm/hipCUB/issues/343

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


[clang] [Clang][Sema] Fix NULL dereferences for invalid references (PR #77703)

2024-02-29 Thread Erich Keane via cfe-commits

erichkeane wrote:

Yeah, this doesn't seem right to me.  Info is a reference, and thus cannot be 
null by language rule.  A sufficiently smart compiler will remove your check.  
If we're SOMEHOW (though I don't see how?) setting it to nullptr, we need to 
fix that as that is not intended, nor particularly easy from what I can tell.



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


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-29 Thread Erich Keane via cfe-commits
Botond =?utf-8?q?István_Horváth?=,Botond Istvan Horvath
 
Message-ID:
In-Reply-To: 



@@ -5548,13 +5504,100 @@ static bool isAtLeastAsSpecializedAs(Sema &S,
 FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
 FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
 TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-unsigned NumCallArguments2, bool Reversed) {
+unsigned NumCallArguments2, QualType RawObjType1, QualType RawObjType2,
+bool Reversed) {
+  SmallVector Args1;
+  SmallVector Args2;
+  const FunctionDecl *FD1 = FT1->getTemplatedDecl();
+  const FunctionDecl *FD2 = FT2->getTemplatedDecl();
+  bool shouldConvert1 = false;
+  bool shouldConvert2 = false;
+  QualType ObjType1;
+  QualType ObjType2;
+  if (TPOC == TPOC_Call) {
+const FunctionProtoType *Proto1 =
+FD1->getType()->getAs();
+const FunctionProtoType *Proto2 =
+FD2->getType()->getAs();
+
+//   - In the context of a function call, the function parameter types are
+// used.
+const CXXMethodDecl *Method1 = dyn_cast(FD1);
+const CXXMethodDecl *Method2 = dyn_cast(FD2);
+
+if (getLangOpts().CPlusPlus20) {
+  // C++20 [temp.func.order]p3
+  //   [...] Each function template M that is a member function is
+  //   considered to have a new first parameter of type
+  //   X(M), described below, inserted in its function parameter list.
+  //
+  // Note that we interpret "that is a member function" as
+  // "that is a member function with no expicit object argument".
+  // Otherwise the ordering rules for methods with expicit objet arguments
+  // against anything else make no sense.
+  shouldConvert1 = Method1 && !Method1->isExplicitObjectMemberFunction();
+  shouldConvert2 = Method2 && !Method2->isExplicitObjectMemberFunction();
+} else {
+  // C++11 [temp.func.order]p3:
+  //   [...] If only one of the function templates is a non-static
+  //   member, that function template is considered to have a new
+  //   first parameter inserted in its function parameter list.
+  //
+  // Note that we interpret this to mean "if one of the function
+  // templates is a non-static member and the other is a non-member";
+  // otherwise, the ordering rules for static functions against non-static
+  // functions don't make any sense.
+  //
+  // C++98/03 doesn't have this provision but we've extended DR532 to cover
+  // it as wording was broken prior to it.
+  shouldConvert1 =
+  !Method2 && Method1 && Method1->isImplicitObjectMemberFunction();
+  shouldConvert2 =
+  !Method1 && Method2 && Method2->isImplicitObjectMemberFunction();
+}
+if (shouldConvert1) {
+  bool isR2 =
+  getLangOpts().CPlusPlus20 &&
+  (shouldConvert1
+   ? Method2->getRefQualifier() == RQ_RValue
+   : Proto2->param_type_begin()[0]->isRValueReferenceType());
+  // Compare 'this' from Method1 against first parameter from Method2.
+  ObjType1 = GetImplicitObjectParameterType(this->Context, Method1,
+RawObjType1, isR2);
+  Args1.push_back(ObjType1);
+}
+if (shouldConvert2) {
+  bool isR1 =
+  getLangOpts().CPlusPlus20 &&
+  (shouldConvert2
+   ? Method1->getRefQualifier() == RQ_RValue
+   : Proto1->param_type_begin()[0]->isRValueReferenceType());
+  // Compare 'this' from Method2 against first parameter from Method1.
+  ObjType2 = GetImplicitObjectParameterType(this->Context, Method2,
+RawObjType2, isR1);
+  Args2.push_back(ObjType2);
+}
+unsigned NumComparedArguments = NumCallArguments1 + shouldConvert1;
 
-  bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC,
-  NumCallArguments1, Reversed);
-  bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC,
-  NumCallArguments2, Reversed);
+Args1.insert(Args1.end(), Proto1->param_type_begin(),
+ Proto1->param_type_end());
+Args2.insert(Args2.end(), Proto2->param_type_begin(),
+ Proto2->param_type_end());
 
+// C++ [temp.func.order]p5:
+//   The presence of unused ellipsis and default arguments has no effect on
+//   the partial ordering of function templates.
+if (Args1.size() > NumComparedArguments)

erichkeane wrote:

Seemingly the original is more confusing as to what it is doing than I thought 
:)I thought that the 'if' statements were overly verbose for something 
pretty trivial and the 1 liners made this less distracting along with reading 
the rest of the function.

https://github.com/llvm/llvm-project/pull/83279
___
cfe-commits mailing list
cfe-commits@lis

[clang] [Concepts] Add Decls from the outer scope of the current lambda for conversion function constraints (PR #83420)

2024-02-29 Thread Erich Keane via cfe-commits


@@ -7976,7 +7976,8 @@ void Sema::AddConversionCandidate(
 
   if (Conversion->getTrailingRequiresClause()) {
 ConstraintSatisfaction Satisfaction;
-if (CheckFunctionConstraints(Conversion, Satisfaction) ||
+if (CheckFunctionConstraints(Conversion, Satisfaction, /*UsageLoc=*/{},

erichkeane wrote:

This isn't really specific to lambdas right?  Doing this on a function seems 
like it would do the wrong thing, right?

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


[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-29 Thread Botond István Horváth via cfe-commits


@@ -5548,13 +5504,100 @@ static bool isAtLeastAsSpecializedAs(Sema &S,
 FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
 FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
 TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-unsigned NumCallArguments2, bool Reversed) {
+unsigned NumCallArguments2, QualType RawObjType1, QualType RawObjType2,
+bool Reversed) {
+  SmallVector Args1;
+  SmallVector Args2;
+  const FunctionDecl *FD1 = FT1->getTemplatedDecl();
+  const FunctionDecl *FD2 = FT2->getTemplatedDecl();
+  bool shouldConvert1 = false;
+  bool shouldConvert2 = false;
+  QualType ObjType1;
+  QualType ObjType2;
+  if (TPOC == TPOC_Call) {
+const FunctionProtoType *Proto1 =
+FD1->getType()->getAs();
+const FunctionProtoType *Proto2 =
+FD2->getType()->getAs();
+
+//   - In the context of a function call, the function parameter types are
+// used.
+const CXXMethodDecl *Method1 = dyn_cast(FD1);
+const CXXMethodDecl *Method2 = dyn_cast(FD2);
+
+if (getLangOpts().CPlusPlus20) {
+  // C++20 [temp.func.order]p3
+  //   [...] Each function template M that is a member function is
+  //   considered to have a new first parameter of type
+  //   X(M), described below, inserted in its function parameter list.
+  //
+  // Note that we interpret "that is a member function" as
+  // "that is a member function with no expicit object argument".
+  // Otherwise the ordering rules for methods with expicit objet arguments
+  // against anything else make no sense.
+  shouldConvert1 = Method1 && !Method1->isExplicitObjectMemberFunction();
+  shouldConvert2 = Method2 && !Method2->isExplicitObjectMemberFunction();
+} else {
+  // C++11 [temp.func.order]p3:
+  //   [...] If only one of the function templates is a non-static
+  //   member, that function template is considered to have a new
+  //   first parameter inserted in its function parameter list.
+  //
+  // Note that we interpret this to mean "if one of the function
+  // templates is a non-static member and the other is a non-member";
+  // otherwise, the ordering rules for static functions against non-static
+  // functions don't make any sense.
+  //
+  // C++98/03 doesn't have this provision but we've extended DR532 to cover
+  // it as wording was broken prior to it.
+  shouldConvert1 =
+  !Method2 && Method1 && Method1->isImplicitObjectMemberFunction();
+  shouldConvert2 =
+  !Method1 && Method2 && Method2->isImplicitObjectMemberFunction();
+}
+if (shouldConvert1) {
+  bool isR2 =
+  getLangOpts().CPlusPlus20 &&
+  (shouldConvert1

HoBoIs wrote:

Actually I just mixed up `shouldConvert1` and `shouldConvert2`

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


[clang] [clang] Implement __builtin_{clzg,ctzg} (PR #83431)

2024-02-29 Thread via cfe-commits

https://github.com/overmighty created 
https://github.com/llvm/llvm-project/pull/83431

Fixes #83075, #83076.


>From 3dbfd1fb21ef0ddccef27e1ceffce16dc298e1cf Mon Sep 17 00:00:00 2001
From: OverMighty 
Date: Thu, 29 Feb 2024 14:23:40 +
Subject: [PATCH] [clang] Implement __builtin_{clzg,ctzg}

Fixes #83075, #83076.
---
 clang/docs/LanguageExtensions.rst |  41 
 clang/include/clang/Basic/Builtins.td |  12 ++
 .../clang/Basic/DiagnosticSemaKinds.td|  15 +-
 clang/lib/CodeGen/CGBuiltin.cpp   |  40 +++-
 clang/lib/Sema/SemaChecking.cpp   |  53 +
 clang/test/CodeGen/builtins.c | 204 ++
 clang/test/CodeGen/ubsan-builtin-checks.c |   6 +
 clang/test/Sema/builtin-popcountg.c   |  23 --
 clang/test/Sema/count-builtins.c  |  87 
 9 files changed, 445 insertions(+), 36 deletions(-)
 delete mode 100644 clang/test/Sema/builtin-popcountg.c
 create mode 100644 clang/test/Sema/count-builtins.c

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index bcd69198eafdbe..3d73d772f698ba 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3504,6 +3504,47 @@ argument can be of any unsigned integer type.
 ``__builtin_popcount{,l,ll}`` builtins, with support for other integer types,
 such as ``unsigned __int128`` and C23 ``unsigned _BitInt(N)``.
 
+``__builtin_clzg`` and ``__builtin_ctzg``
+-
+
+``__builtin_clzg`` (respectively ``__builtin_ctzg``) returns the number of
+leading (respectively trailing) 0 bits in the first argument. The first 
argument
+can be of any unsigned integer type.
+
+If the first argument is 0 and an optional second argument of ``int`` type is
+provided, then the second argument is returned. If the first argument is 0, but
+only one argument is provided, then the returned value is undefined.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  int __builtin_clzg(type x[, int fallback])
+  int __builtin_ctzg(type x[, int fallback])
+
+**Examples**:
+
+.. code-block:: c++
+
+  unsigned int x = 1;
+  int x_lz = __builtin_clzg(x);
+  int x_tz = __builtin_ctzg(x);
+
+  unsigned long y = 2;
+  int y_lz = __builtin_clzg(y);
+  int y_tz = __builtin_ctzg(y);
+
+  unsigned _BitInt(128) z = 4;
+  int z_lz = __builtin_clzg(z);
+  int z_tz = __builtin_ctzg(z);
+
+**Description**:
+
+``__builtin_clzg`` (respectively ``__builtin_ctzg``) is meant to be a
+type-generic alternative to the ``__builtin_clz{,l,ll}`` (respectively
+``__builtin_ctz{,l,ll}``) builtins, with support for other integer types, such
+as ``unsigned __int128`` and C23 ``unsigned _BitInt(N)``.
+
 Multiprecision Arithmetic Builtins
 --
 
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 2fbc56d49a59a1..ec5a8819ed4057 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -662,6 +662,12 @@ def Clz : Builtin, BitShort_Int_Long_LongLongTemplate {
 
 // FIXME: Add int clzimax(uintmax_t)
 
+def Clzg : Builtin {
+  let Spellings = ["__builtin_clzg"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "int(...)";
+}
+
 def Ctz : Builtin, BitShort_Int_Long_LongLongTemplate {
   let Spellings = ["__builtin_ctz"];
   let Attributes = [NoThrow, Const, Constexpr];
@@ -670,6 +676,12 @@ def Ctz : Builtin, BitShort_Int_Long_LongLongTemplate {
 
 // FIXME: Add int ctzimax(uintmax_t)
 
+def Ctzg : Builtin {
+  let Spellings = ["__builtin_ctzg"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "int(...)";
+}
+
 def FFS : Builtin, BitInt_Long_LongLongTemplate {
   let Spellings = ["__builtin_ffs"];
   let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f726805dc02bd9..d2a18b7bb9cfdd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11978,13 +11978,14 @@ def err_builtin_launder_invalid_arg : Error<
   "'__builtin_launder' is not allowed">;
 
 def err_builtin_invalid_arg_type: Error <
-  "%ordinal0 argument must be a "
-  "%select{vector, integer or floating point type|matrix|"
-  "pointer to a valid matrix element type|"
-  "signed integer or floating point type|vector type|"
-  "floating point type|"
-  "vector of integers|"
-  "type of unsigned integer}1 (was %2)">;
+  "%ordinal0 argument must be "
+  "%select{a vector, integer or floating point type|a matrix|"
+  "a pointer to a valid matrix element type|"
+  "a signed integer or floating point type|a vector type|"
+  "a floating point type|"
+  "a vector of integers|"
+  "an unsigned integer|"
+  "an 'int'}1 (was %2)">;
 
 def err_builtin_matrix_disabled: Error<
   "matrix types extension is disabled. Pass -fenable

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-29 Thread Botond István Horváth via cfe-commits

https://github.com/HoBoIs updated 
https://github.com/llvm/llvm-project/pull/83279

From 68200ecf3267d1b3940fa73c25c50ee706932a98 Mon Sep 17 00:00:00 2001
From: Botond Istvan Horvath 
Date: Wed, 28 Feb 2024 13:09:15 +0100
Subject: [PATCH 1/4] Bugfix for choosing the more specialized overload

There was a bug in clang where it couldn't choose which overload candidate is
more specialized if it was comparing a member-function to a non-member
function. Previously, this was detected as an ambigouity, now clang chooses 
correctly.

This patch fixes the bug by fully implementing CWG2445 and moving the template
transformation described in [temp.func.order] paragraph 3 from
isAtLeastAsSpecializedAs to Sema::getMoreSpecializedTemplate so we have the
transformed parameter list during the whole comperrassion. Also, to be able
to add the correct type for the implicit object parameter
Sema::getMoreSpecializedTemplate has new parameters for the object type.
---
 clang/include/clang/Sema/Sema.h  |   4 +-
 clang/lib/Sema/SemaOverload.cpp  |  12 +-
 clang/lib/Sema/SemaTemplateDeduction.cpp | 263 +++
 3 files changed, 186 insertions(+), 93 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ef4b93fac95ce5..1a2a3a6bebd95e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9463,7 +9463,9 @@ class Sema final {
   FunctionTemplateDecl *getMoreSpecializedTemplate(
   FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
   TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-  unsigned NumCallArguments2, bool Reversed = false);
+  unsigned NumCallArguments2, QualType ObjType1 = {},
+  QualType ObjType2 = {}, bool Reversed = false);
+
   UnresolvedSetIterator
   getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd,
  TemplateSpecCandidateSet &FailedCandidates,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7d38043890ca20..60138236abf1d8 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10526,14 +10526,24 @@ bool clang::isBetterOverloadCandidate(
   //  according to the partial ordering rules described in 14.5.5.2, or,
   //  if not that,
   if (Cand1IsSpecialization && Cand2IsSpecialization) {
+const auto *ObjContext1 =
+dyn_cast(Cand1.FoundDecl->getDeclContext());
+const auto *ObjContext2 =
+dyn_cast(Cand2.FoundDecl->getDeclContext());
 if (FunctionTemplateDecl *BetterTemplate = S.getMoreSpecializedTemplate(
 Cand1.Function->getPrimaryTemplate(),
 Cand2.Function->getPrimaryTemplate(), Loc,
 isa(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
 Cand1.ExplicitCallArguments, Cand2.ExplicitCallArguments,
-Cand1.isReversed() ^ Cand2.isReversed()))
+ObjContext1 ? QualType(ObjContext1->getTypeForDecl(), 0)
+: QualType{},
+ObjContext2 ? QualType(ObjContext2->getTypeForDecl(), 0)
+: QualType{},
+Cand1.isReversed() ^ Cand2.isReversed())) {
   return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+}
+
   }
 
   //   -— F1 and F2 are non-template functions with the same
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 563491f76f5478..2af3c29ae1f1c4 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -5333,11 +5333,31 @@ bool 
Sema::CheckIfFunctionSpecializationIsImmediate(FunctionDecl *FD,
   return false;
 }
 
+static QualType GetImplicitObjectParameterTypeCXX20(ASTContext &Context,
+const CXXMethodDecl 
*Method,
+QualType rawType,
+bool isOtherRvr) {
+  // C++20 [temp.func.order]p3.1, p3.2:
+  //- The type X(M ) is “rvalue reference to cv A” if the optional 
ref-qualifier
+  //  of M is && or if M has no ref-qualifier and the 
positionally-corresponding
+  //  parameter of the other transformed template has rvalue reference type;
+  //  if this determination depends recursively upon whether X(M ) is an rvalue
+  //  reference type, it is not considered to have rvalue reference type.
+  //- Otherwise, X(M ) is “lvalue reference to cv A”.
+  assert(Method && !Method->isExplicitObjectMemberFunction() &&
+ "expected a member function with no explicit object parameter");
+
+  rawType = Context.getQualifiedType(rawType, Method->getMethodQualifiers());
+  if (Method->getRefQualifier() == RQ_RValue ||
+  (isOtherRvr && Method->getRefQualifier() == RQ_None))
+return Context.getRValueReferenceType(rawType);
+  return Context.getLValueReferenceType(

[clang] [clang] Implement __builtin_{clzg,ctzg} (PR #83431)

2024-02-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: OverMighty (overmighty)


Changes

Fixes #83075, #83076.


---

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


9 Files Affected:

- (modified) clang/docs/LanguageExtensions.rst (+41) 
- (modified) clang/include/clang/Basic/Builtins.td (+12) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+8-7) 
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+34-6) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+53) 
- (modified) clang/test/CodeGen/builtins.c (+204) 
- (modified) clang/test/CodeGen/ubsan-builtin-checks.c (+6) 
- (removed) clang/test/Sema/builtin-popcountg.c (-23) 
- (added) clang/test/Sema/count-builtins.c (+87) 


``diff
diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index bcd69198eafdbe..3d73d772f698ba 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3504,6 +3504,47 @@ argument can be of any unsigned integer type.
 ``__builtin_popcount{,l,ll}`` builtins, with support for other integer types,
 such as ``unsigned __int128`` and C23 ``unsigned _BitInt(N)``.
 
+``__builtin_clzg`` and ``__builtin_ctzg``
+-
+
+``__builtin_clzg`` (respectively ``__builtin_ctzg``) returns the number of
+leading (respectively trailing) 0 bits in the first argument. The first 
argument
+can be of any unsigned integer type.
+
+If the first argument is 0 and an optional second argument of ``int`` type is
+provided, then the second argument is returned. If the first argument is 0, but
+only one argument is provided, then the returned value is undefined.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  int __builtin_clzg(type x[, int fallback])
+  int __builtin_ctzg(type x[, int fallback])
+
+**Examples**:
+
+.. code-block:: c++
+
+  unsigned int x = 1;
+  int x_lz = __builtin_clzg(x);
+  int x_tz = __builtin_ctzg(x);
+
+  unsigned long y = 2;
+  int y_lz = __builtin_clzg(y);
+  int y_tz = __builtin_ctzg(y);
+
+  unsigned _BitInt(128) z = 4;
+  int z_lz = __builtin_clzg(z);
+  int z_tz = __builtin_ctzg(z);
+
+**Description**:
+
+``__builtin_clzg`` (respectively ``__builtin_ctzg``) is meant to be a
+type-generic alternative to the ``__builtin_clz{,l,ll}`` (respectively
+``__builtin_ctz{,l,ll}``) builtins, with support for other integer types, such
+as ``unsigned __int128`` and C23 ``unsigned _BitInt(N)``.
+
 Multiprecision Arithmetic Builtins
 --
 
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 2fbc56d49a59a1..ec5a8819ed4057 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -662,6 +662,12 @@ def Clz : Builtin, BitShort_Int_Long_LongLongTemplate {
 
 // FIXME: Add int clzimax(uintmax_t)
 
+def Clzg : Builtin {
+  let Spellings = ["__builtin_clzg"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "int(...)";
+}
+
 def Ctz : Builtin, BitShort_Int_Long_LongLongTemplate {
   let Spellings = ["__builtin_ctz"];
   let Attributes = [NoThrow, Const, Constexpr];
@@ -670,6 +676,12 @@ def Ctz : Builtin, BitShort_Int_Long_LongLongTemplate {
 
 // FIXME: Add int ctzimax(uintmax_t)
 
+def Ctzg : Builtin {
+  let Spellings = ["__builtin_ctzg"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "int(...)";
+}
+
 def FFS : Builtin, BitInt_Long_LongLongTemplate {
   let Spellings = ["__builtin_ffs"];
   let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f726805dc02bd9..d2a18b7bb9cfdd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11978,13 +11978,14 @@ def err_builtin_launder_invalid_arg : Error<
   "'__builtin_launder' is not allowed">;
 
 def err_builtin_invalid_arg_type: Error <
-  "%ordinal0 argument must be a "
-  "%select{vector, integer or floating point type|matrix|"
-  "pointer to a valid matrix element type|"
-  "signed integer or floating point type|vector type|"
-  "floating point type|"
-  "vector of integers|"
-  "type of unsigned integer}1 (was %2)">;
+  "%ordinal0 argument must be "
+  "%select{a vector, integer or floating point type|a matrix|"
+  "a pointer to a valid matrix element type|"
+  "a signed integer or floating point type|a vector type|"
+  "a floating point type|"
+  "a vector of integers|"
+  "an unsigned integer|"
+  "an 'int'}1 (was %2)">;
 
 def err_builtin_matrix_disabled: Error<
   "matrix types extension is disabled. Pass -fenable-matrix to enable it">;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 2d16e7cdc06053..bd7cf9ae79f690 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3128

[clang] [clang] Implement __builtin_{clzg,ctzg} (PR #83431)

2024-02-29 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: OverMighty (overmighty)


Changes

Fixes #83075, #83076.


---

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


9 Files Affected:

- (modified) clang/docs/LanguageExtensions.rst (+41) 
- (modified) clang/include/clang/Basic/Builtins.td (+12) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+8-7) 
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+34-6) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+53) 
- (modified) clang/test/CodeGen/builtins.c (+204) 
- (modified) clang/test/CodeGen/ubsan-builtin-checks.c (+6) 
- (removed) clang/test/Sema/builtin-popcountg.c (-23) 
- (added) clang/test/Sema/count-builtins.c (+87) 


``diff
diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index bcd69198eafdbe..3d73d772f698ba 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3504,6 +3504,47 @@ argument can be of any unsigned integer type.
 ``__builtin_popcount{,l,ll}`` builtins, with support for other integer types,
 such as ``unsigned __int128`` and C23 ``unsigned _BitInt(N)``.
 
+``__builtin_clzg`` and ``__builtin_ctzg``
+-
+
+``__builtin_clzg`` (respectively ``__builtin_ctzg``) returns the number of
+leading (respectively trailing) 0 bits in the first argument. The first 
argument
+can be of any unsigned integer type.
+
+If the first argument is 0 and an optional second argument of ``int`` type is
+provided, then the second argument is returned. If the first argument is 0, but
+only one argument is provided, then the returned value is undefined.
+
+**Syntax**:
+
+.. code-block:: c++
+
+  int __builtin_clzg(type x[, int fallback])
+  int __builtin_ctzg(type x[, int fallback])
+
+**Examples**:
+
+.. code-block:: c++
+
+  unsigned int x = 1;
+  int x_lz = __builtin_clzg(x);
+  int x_tz = __builtin_ctzg(x);
+
+  unsigned long y = 2;
+  int y_lz = __builtin_clzg(y);
+  int y_tz = __builtin_ctzg(y);
+
+  unsigned _BitInt(128) z = 4;
+  int z_lz = __builtin_clzg(z);
+  int z_tz = __builtin_ctzg(z);
+
+**Description**:
+
+``__builtin_clzg`` (respectively ``__builtin_ctzg``) is meant to be a
+type-generic alternative to the ``__builtin_clz{,l,ll}`` (respectively
+``__builtin_ctz{,l,ll}``) builtins, with support for other integer types, such
+as ``unsigned __int128`` and C23 ``unsigned _BitInt(N)``.
+
 Multiprecision Arithmetic Builtins
 --
 
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 2fbc56d49a59a1..ec5a8819ed4057 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -662,6 +662,12 @@ def Clz : Builtin, BitShort_Int_Long_LongLongTemplate {
 
 // FIXME: Add int clzimax(uintmax_t)
 
+def Clzg : Builtin {
+  let Spellings = ["__builtin_clzg"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "int(...)";
+}
+
 def Ctz : Builtin, BitShort_Int_Long_LongLongTemplate {
   let Spellings = ["__builtin_ctz"];
   let Attributes = [NoThrow, Const, Constexpr];
@@ -670,6 +676,12 @@ def Ctz : Builtin, BitShort_Int_Long_LongLongTemplate {
 
 // FIXME: Add int ctzimax(uintmax_t)
 
+def Ctzg : Builtin {
+  let Spellings = ["__builtin_ctzg"];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
+  let Prototype = "int(...)";
+}
+
 def FFS : Builtin, BitInt_Long_LongLongTemplate {
   let Spellings = ["__builtin_ffs"];
   let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f726805dc02bd9..d2a18b7bb9cfdd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11978,13 +11978,14 @@ def err_builtin_launder_invalid_arg : Error<
   "'__builtin_launder' is not allowed">;
 
 def err_builtin_invalid_arg_type: Error <
-  "%ordinal0 argument must be a "
-  "%select{vector, integer or floating point type|matrix|"
-  "pointer to a valid matrix element type|"
-  "signed integer or floating point type|vector type|"
-  "floating point type|"
-  "vector of integers|"
-  "type of unsigned integer}1 (was %2)">;
+  "%ordinal0 argument must be "
+  "%select{a vector, integer or floating point type|a matrix|"
+  "a pointer to a valid matrix element type|"
+  "a signed integer or floating point type|a vector type|"
+  "a floating point type|"
+  "a vector of integers|"
+  "an unsigned integer|"
+  "an 'int'}1 (was %2)">;
 
 def err_builtin_matrix_disabled: Error<
   "matrix types extension is disabled. Pass -fenable-matrix to enable it">;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 2d16e7cdc06053..bd7cf9ae79f690 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3128,8 +3128

[clang] [clang] Bugfix for choosing the more specialized overload (PR #83279)

2024-02-29 Thread Botond István Horváth via cfe-commits


@@ -5548,13 +5504,100 @@ static bool isAtLeastAsSpecializedAs(Sema &S,
 FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
 FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
 TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
-unsigned NumCallArguments2, bool Reversed) {
+unsigned NumCallArguments2, QualType RawObjType1, QualType RawObjType2,
+bool Reversed) {
+  SmallVector Args1;
+  SmallVector Args2;
+  const FunctionDecl *FD1 = FT1->getTemplatedDecl();
+  const FunctionDecl *FD2 = FT2->getTemplatedDecl();
+  bool shouldConvert1 = false;
+  bool shouldConvert2 = false;
+  QualType ObjType1;
+  QualType ObjType2;
+  if (TPOC == TPOC_Call) {
+const FunctionProtoType *Proto1 =
+FD1->getType()->getAs();
+const FunctionProtoType *Proto2 =
+FD2->getType()->getAs();
+
+//   - In the context of a function call, the function parameter types are
+// used.
+const CXXMethodDecl *Method1 = dyn_cast(FD1);
+const CXXMethodDecl *Method2 = dyn_cast(FD2);
+
+if (getLangOpts().CPlusPlus20) {
+  // C++20 [temp.func.order]p3
+  //   [...] Each function template M that is a member function is
+  //   considered to have a new first parameter of type
+  //   X(M), described below, inserted in its function parameter list.
+  //
+  // Note that we interpret "that is a member function" as
+  // "that is a member function with no expicit object argument".
+  // Otherwise the ordering rules for methods with expicit objet arguments
+  // against anything else make no sense.
+  shouldConvert1 = Method1 && !Method1->isExplicitObjectMemberFunction();
+  shouldConvert2 = Method2 && !Method2->isExplicitObjectMemberFunction();
+} else {
+  // C++11 [temp.func.order]p3:
+  //   [...] If only one of the function templates is a non-static
+  //   member, that function template is considered to have a new
+  //   first parameter inserted in its function parameter list.
+  //
+  // Note that we interpret this to mean "if one of the function
+  // templates is a non-static member and the other is a non-member";
+  // otherwise, the ordering rules for static functions against non-static
+  // functions don't make any sense.
+  //
+  // C++98/03 doesn't have this provision but we've extended DR532 to cover
+  // it as wording was broken prior to it.
+  shouldConvert1 =
+  !Method2 && Method1 && Method1->isImplicitObjectMemberFunction();
+  shouldConvert2 =
+  !Method1 && Method2 && Method2->isImplicitObjectMemberFunction();
+}
+if (shouldConvert1) {
+  bool isR2 =
+  getLangOpts().CPlusPlus20 &&
+  (shouldConvert1

HoBoIs wrote:

fixed


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


  1   2   3   4   >