[clang] [C++20][Coroutines] Lambda-coroutine with operator new in promise_type (PR #84193)

2024-04-02 Thread Andreas Fertig via cfe-commits

andreasfertig wrote:

Hello all,

I did more investigation and found another shortcoming. In some cases, my 
initial implementation picked the wrong `this`- type, for example, 
https://github.com/andreasfertig/llvm-project/blob/9c60fec6881cca7e7fed9dca5cf24a0bd1924eaa/clang/test/SemaCXX/coroutine-promise-ctor-lambda.cpp#L45.

I pushed a new branch 
(https://github.com/andreasfertig/llvm-project/tree/fixGH84064take2), which 
also fixes this behavior and requires fewer changes.

Regarding the crash, that was improper testing on my side. All tests let Clang 
crash, even the tests I checked in as part of the PR. The difference is that my 
tests used only `static_assert` to verify that the lambda's size did not 
increase, while the `async_simple::Generator` example _executes_ the code. This 
step leads to code generation, the `static_assert`, I assume, is handled only 
on the constexpr evaluator.

This is where I'm stuck. The call stack for all cases is:

``` 
 #5 0x000105534f38 
clang::CodeGen::CodeGenFunction::EmitCall(clang::CodeGen::CGFunctionInfo 
const&, clang::CodeGen::CGCallee const&, clang::CodeGen::ReturnValueSlot, 
clang::CodeGen::CallArgList const&, llvm::CallBase**, bool, 
clang::SourceLocation) (build/bin/clang-19+0x10262cf38)
 #6 0x0001055e10d8 
clang::CodeGen::CodeGenFunction::EmitCall(clang::QualType, 
clang::CodeGen::CGCallee const&, clang::CallExpr const*, 
clang::CodeGen::ReturnValueSlot, llvm::Value*) (build/bin/clang-19+0x1026d90d8)
 #7 0x0001055e01b4 
clang::CodeGen::CodeGenFunction::EmitCallExpr(clang::CallExpr const*, 
clang::CodeGen::ReturnValueSlot) (build/bin/clang-19+0x1026d81b4)
 #8 0x00010561e5a8 (anonymous 
namespace)::ScalarExprEmitter::VisitCallExpr(clang::CallExpr const*) 
(build/bin/clang-19+0x1027165a8)
 #9 0x00010560edec 
clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) 
(build/bin/clang-19+0x102706dec)
#10 0x00010554e22c 
clang::CodeGen::CodeGenFunction::EmitCoroutineBody(clang::CoroutineBodyStmt 
const&) (build/bin/clang-19+0x10264622c)
```

The crash is within `CodeGenFunction::EmitCall` at 
https://github.com/llvm/llvm-project/blob/8bb944e0117ab61feecce9de339b11b924fc/clang/lib/CodeGen/CGCall.cpp#L5298

`I->getKnownRValue().getScalarVal()` is `nullptr`, which leads to the crash 
later when `V` is deferenced. I don't understand why `getKnownRValue` is empty. 
It looks to me like I had to mark `this` to be not optimized away. However, I 
could not see any coding doing this for the non-lambda case. Any thoughts?

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


[clang] e47a81c - [OpenCL] Fix BIenqueue_kernel fallthrough (#83238)

2024-04-02 Thread via cfe-commits

Author: Sven van Haastregt
Date: 2024-04-02T09:31:38+02:00
New Revision: e47a81c1d2830dda45a561e2c092ebb0c868ed27

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

LOG: [OpenCL] Fix BIenqueue_kernel fallthrough (#83238)

Handling of the `BIenqueue_kernel` builtin must not fallthrough to the
`BIget_kernel_work_group_size` builtin, as these builtins have no common
functionality.

Added: 


Modified: 
clang/lib/CodeGen/CGBuiltin.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index bb007231c0b783..483f9c26859923 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -5835,7 +5835,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 EmitLifetimeEnd(TmpSize, TmpPtr);
   return Call;
 }
-[[fallthrough]];
+llvm_unreachable("Unexpected enqueue_kernel signature");
   }
   // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block
   // parameter.



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


[clang] [OpenCL] Fix BIenqueue_kernel fallthrough (PR #83238)

2024-04-02 Thread Sven van Haastregt via cfe-commits

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -97,21 +97,34 @@ class Environment {
   const Value &Val2, const Environment &Env2,
   Value &JoinedVal, Environment &JoinedEnv) {}
 
+/// The result of the `widen` operation.
+struct WidenResult {
+  /// Non-null pointer to a potentially widened version of the widening
+  /// input.

martinboehme wrote:

```suggestion
  /// Non-null pointer to a potentially widened version of the input
  /// value.
```

("Widening input" is intended to mean "input to widening" but could also be 
misinterpreted as "input that widens". As it's clear that the context is 
widening, maybe just "input value"?)

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits

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

Nice. This is _much_ clearer!

Mostly nits, the only substantive question I have is how we will migrate 
existing overrides.

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -975,6 +994,35 @@ TEST_F(WideningTest, 
DistinctValuesWithSamePropertiesAreEquivalent) {
   });
 }
 
+TEST_F(WideningTest, DistinctValuesWithDifferentPropertiesWidenedToTop) {
+  std::string Code = R"(
+void target(bool Cond) {
+  int *Foo;
+  int i = 0;
+  Foo = nullptr;
+  while (Cond) {
+Foo = &i;
+  }
+  (void)0;
+  /*[[p]]*/
+}
+  )";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));

martinboehme wrote:

We do this in a lot of existing tests, but it's unnecessary: 
`getEnvironmentAtAnnotation()` itself asserts that the annotation exists.

```suggestion
```

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -975,6 +994,35 @@ TEST_F(WideningTest, 
DistinctValuesWithSamePropertiesAreEquivalent) {
   });
 }
 
+TEST_F(WideningTest, DistinctValuesWithDifferentPropertiesWidenedToTop) {
+  std::string Code = R"(
+void target(bool Cond) {
+  int *Foo;
+  int i = 0;
+  Foo = nullptr;
+  while (Cond) {
+Foo = &i;
+  }
+  (void)0;
+  /*[[p]]*/
+}
+  )";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+
+const auto *FooVal = Env.getValue(*FooDecl);
+EXPECT_TRUE(areEquivalentValues(*FooVal->getProperty("is_null"),

martinboehme wrote:

I think we also want to test that `getProperty()` returns non-null?

Easiest way might be `*cast(FooVal->getProperty("is_null"))`. 
(`cast` asserts that its argument is non-null.)

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -122,17 +135,19 @@ class Environment {
 ///
 ///  `Prev` and `Current` must be assigned to the same storage location in
 ///  `PrevEnv` and `CurrentEnv`, respectively.
-virtual Value *widen(QualType Type, Value &Prev, const Environment 
&PrevEnv,
- Value &Current, Environment &CurrentEnv) {
+virtual std::optional widen(QualType Type, Value &Prev,

martinboehme wrote:

How are we going to deal with the fact that this API change breaks existing 
overrides? (There's an existing 
[override](https://github.com/google/crubit/blob/d51d5d004caa1d7c6cf5341d1fab22f5bae02018/nullability/pointer_nullability_analysis.cc#L1752)
 in Crubit's nullability check.)

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -166,17 +166,20 @@ static Value *joinDistinctValues(QualType Type, Value 
&Val1,
   return JoinedVal;
 }
 
-// When widening does not change `Current`, return value will equal `&Prev`.
-static Value &widenDistinctValues(QualType Type, Value &Prev,
-  const Environment &PrevEnv, Value &Current,
-  Environment &CurrentEnv,
-  Environment::ValueModel &Model) {
+namespace {
+using WidenResult = Environment::ValueModel::WidenResult;
+}
+
+static WidenResult widenDistinctValues(QualType Type, Value &Prev,

martinboehme wrote:

```suggestion
static Environment::ValueModel::WidenResult widenDistinctValues(QualType Type, 
Value &Prev,
```

AFAICT, this is used exactly once. Maybe just spell it out?

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -975,6 +994,35 @@ TEST_F(WideningTest, 
DistinctValuesWithSamePropertiesAreEquivalent) {
   });
 }
 
+TEST_F(WideningTest, DistinctValuesWithDifferentPropertiesWidenedToTop) {
+  std::string Code = R"(
+void target(bool Cond) {
+  int *Foo;
+  int i = 0;
+  Foo = nullptr;
+  while (Cond) {
+Foo = &i;
+  }
+  (void)0;
+  /*[[p]]*/
+}
+  )";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+
+const auto *FooVal = Env.getValue(*FooDecl);

martinboehme wrote:

```suggestion
const auto &FooVal = getValueForDecl(ASTCtx, Env, "Foo");
```

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -805,6 +805,25 @@ class NullPointerAnalysis final
 else
   JoinedVal.setProperty("is_null", JoinedEnv.makeTopBoolValue());
   }
+
+  std::optional widen(QualType Type, Value &Prev,
+   const Environment &PrevEnv, Value &Current,
+   Environment &CurrentEnv) override {

martinboehme wrote:

This appears to be more than an API change in that this model didn't have a 
widening operation at all before. Can you explain why this has been added? (Is 
it necessary as part of this patch, or just an additional embellishment?)

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


[clang] Clang: Return new layout path if cannot find CRT (PR #87319)

2024-04-02 Thread YunQiang Su via cfe-commits

https://github.com/wzssyqa created 
https://github.com/llvm/llvm-project/pull/87319

In ToolChain::getCompilerRT:
  If none is found, use a file name from the new layout, which may get
  printed in an error message, aiding users in knowing what Clang is
  looking for.

But in current code, the old layout is printed if no libclang_rt.builtin is 
found with cmd like:
  ./bin/clang --target=aarch64-linux-gnu -rtlib=compiler-rt hello.c

aarch64-linux-gnu/bin/ld: cannot find 
/lib/clang/19/lib/linux/libclang_rt.builtins-aarch64.a: No such file or 
directory

>From 2c8132f08eedfe522ca4dcdcc5bbb11ffb629dd2 Mon Sep 17 00:00:00 2001
From: YunQiang Su 
Date: Tue, 2 Apr 2024 15:50:23 +0800
Subject: [PATCH] Clang: Return new layout path if cannot find CRT

In ToolChain::getCompilerRT:
  // If none is found, use a file name from the new layout, which may get
  // printed in an error message, aiding users in knowing what Clang is
  // looking for.

But in current code, the old layout is printed if no
libclang_rt.builtin is found with cmd like:
  ./bin/clang --target=aarch64-linux-gnu -rtlib=compiler-rt hello.c
---
 clang/lib/Driver/ToolChain.cpp | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 03450fc0f57b93..3b5960992a9dd1 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -692,12 +692,21 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, 
StringRef Component,
   buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/true);
   SmallString<128> OldPath(getCompilerRTPath());
   llvm::sys::path::append(OldPath, CRTBasename);
-  if (Path.empty() || getVFS().exists(OldPath))
+  if (getVFS().exists(OldPath))
 return std::string(OldPath);
 
   // If none is found, use a file name from the new layout, which may get
   // printed in an error message, aiding users in knowing what Clang is
   // looking for.
+  if (Path.empty()) {
+CRTBasename =
+buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false);
+SmallString<128> NewP(D.ResourceDir);
+llvm::sys::path::append(NewP, "lib");
+llvm::sys::path::append(NewP, getTriple().str());
+llvm::sys::path::append(NewP, CRTBasename);
+return std::string(NewP);
+  }
   return std::string(Path);
 }
 

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


[clang] Clang: Return new layout path if cannot find CRT (PR #87319)

2024-04-02 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: YunQiang Su (wzssyqa)


Changes

In ToolChain::getCompilerRT:
  If none is found, use a file name from the new layout, which may get
  printed in an error message, aiding users in knowing what Clang is
  looking for.

But in current code, the old layout is printed if no libclang_rt.builtin is 
found with cmd like:
  ./bin/clang --target=aarch64-linux-gnu -rtlib=compiler-rt hello.c

aarch64-linux-gnu/bin/ld: cannot find 
/lib/clang/19/lib/linux/libclang_rt.builtins-aarch64.a: No such 
file or directory

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


1 Files Affected:

- (modified) clang/lib/Driver/ToolChain.cpp (+10-1) 


``diff
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 03450fc0f57b93..3b5960992a9dd1 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -692,12 +692,21 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, 
StringRef Component,
   buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/true);
   SmallString<128> OldPath(getCompilerRTPath());
   llvm::sys::path::append(OldPath, CRTBasename);
-  if (Path.empty() || getVFS().exists(OldPath))
+  if (getVFS().exists(OldPath))
 return std::string(OldPath);
 
   // If none is found, use a file name from the new layout, which may get
   // printed in an error message, aiding users in knowing what Clang is
   // looking for.
+  if (Path.empty()) {
+CRTBasename =
+buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false);
+SmallString<128> NewP(D.ResourceDir);
+llvm::sys::path::append(NewP, "lib");
+llvm::sys::path::append(NewP, getTriple().str());
+llvm::sys::path::append(NewP, CRTBasename);
+return std::string(NewP);
+  }
   return std::string(Path);
 }
 

``




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


[clang] Clang: Return new layout path if cannot find CRT (PR #87319)

2024-04-02 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-driver

Author: YunQiang Su (wzssyqa)


Changes

In ToolChain::getCompilerRT:
  If none is found, use a file name from the new layout, which may get
  printed in an error message, aiding users in knowing what Clang is
  looking for.

But in current code, the old layout is printed if no libclang_rt.builtin is 
found with cmd like:
  ./bin/clang --target=aarch64-linux-gnu -rtlib=compiler-rt hello.c

aarch64-linux-gnu/bin/ld: cannot find 
/lib/clang/19/lib/linux/libclang_rt.builtins-aarch64.a: No such 
file or directory

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


1 Files Affected:

- (modified) clang/lib/Driver/ToolChain.cpp (+10-1) 


``diff
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 03450fc0f57b93..3b5960992a9dd1 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -692,12 +692,21 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, 
StringRef Component,
   buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/true);
   SmallString<128> OldPath(getCompilerRTPath());
   llvm::sys::path::append(OldPath, CRTBasename);
-  if (Path.empty() || getVFS().exists(OldPath))
+  if (getVFS().exists(OldPath))
 return std::string(OldPath);
 
   // If none is found, use a file name from the new layout, which may get
   // printed in an error message, aiding users in knowing what Clang is
   // looking for.
+  if (Path.empty()) {
+CRTBasename =
+buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false);
+SmallString<128> NewP(D.ResourceDir);
+llvm::sys::path::append(NewP, "lib");
+llvm::sys::path::append(NewP, getTriple().str());
+llvm::sys::path::append(NewP, CRTBasename);
+return std::string(NewP);
+  }
   return std::string(Path);
 }
 

``




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


[clang] Clang: Return new layout path if cannot find CRT (PR #87319)

2024-04-02 Thread YunQiang Su via cfe-commits

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


[clang] [clang][dataflow] Propagate locations from result objects to initializers. (PR #87320)

2024-04-02 Thread via cfe-commits

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

Previously, we were propagating storage locations the other way around, i.e.
from initializers to result objects, using `RecordValue::getLoc()`. This gave
the wrong behavior in some cases -- see the newly added or fixed tests in this
patch.

In addition, this patch now unblocks removing the `RecordValue` class entirely,
as we no longer need `RecordValue::getLoc()`.

With this patch, the test `TransferTest.DifferentReferenceLocInJoin` started to
fail because the framework now always uses the same storge location for a
`MaterializeTemporaryExpr`, meaning that the code under test no longer set up
the desired state where a variable of reference type is mapped to two different
storage locations in environments being joined. Rather than trying to modify
this test to set up the test condition again, I have chosen to replace the test
with an equivalent test in DataflowEnvironmentTest.cpp that sets up the test
condition directly; because this test is more direct, it will also be less
brittle in the face of future changes.


>From 2d2aa88aab3e47e41588397471a90c03bb55d900 Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Tue, 2 Apr 2024 08:00:00 +
Subject: [PATCH] [clang][dataflow] Propagate locations from result objects to
 initializers.

Previously, we were propagating storage locations the other way around, i.e.
from initializers to result objects, using `RecordValue::getLoc()`. This gave
the wrong behavior in some cases -- see the newly added or fixed tests in this
patch.

In addition, this patch now unblocks removing the `RecordValue` class entirely,
as we no longer need `RecordValue::getLoc()`.

With this patch, the test `TransferTest.DifferentReferenceLocInJoin` started to
fail because the framework now always uses the same storge location for a
`MaterializeTemporaryExpr`, meaning that the code under test no longer set up
the desired state where a variable of reference type is mapped to two different
storage locations in environments being joined. Rather than trying to modify
this test to set up the test condition again, I have chosen to replace the test
with an equivalent test in DataflowEnvironmentTest.cpp that sets up the test
condition directly; because this test is more direct, it will also be less
brittle in the face of future changes.
---
 .../FlowSensitive/DataflowEnvironment.h   |  64 ++-
 .../FlowSensitive/DataflowEnvironment.cpp | 402 +-
 clang/lib/Analysis/FlowSensitive/Transfer.cpp | 172 
 .../TypeErasedDataflowAnalysis.cpp|  13 +-
 .../FlowSensitive/DataflowEnvironmentTest.cpp |  43 ++
 .../Analysis/FlowSensitive/TransferTest.cpp   | 172 +---
 6 files changed, 582 insertions(+), 284 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index c30bccd06674a4..dc3a9c239552be 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -30,6 +30,7 @@
 #include "llvm/ADT/MapVector.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
+#include 
 #include 
 #include 
 
@@ -330,17 +331,6 @@ class Environment {
   /// location of the result object to pass in `this`, even though prvalues are
   /// otherwise not associated with storage locations.
   ///
-  /// FIXME: Currently, this simply returns a stable storage location for `E`,
-  /// but this doesn't do the right thing in scenarios like the following:
-  /// ```
-  /// MyClass c = some_condition()? MyClass(foo) : MyClass(bar);
-  /// ```
-  /// Here, `MyClass(foo)` and `MyClass(bar)` will have two different storage
-  /// locations, when in fact their storage locations should be the same.
-  /// Eventually, we want to propagate storage locations from result objects
-  /// down to the prvalues that initialize them, similar to the way that this 
is
-  /// done in Clang's CodeGen.
-  ///
   /// Requirements:
   ///  `E` must be a prvalue of record type.
   RecordStorageLocation &
@@ -448,7 +438,13 @@ class Environment {
   /// Initializes the fields (including synthetic fields) of `Loc` with values,
   /// unless values of the field type are not supported or we hit one of the
   /// limits at which we stop producing values.
-  void initializeFieldsWithValues(RecordStorageLocation &Loc);
+  /// If `Type` is provided, initializes only those fields that are modeled for
+  /// `Type`; this is intended for use in cases where `Loc` is a derived type
+  /// and we only want to initialize the fields of a base type.
+  void initializeFieldsWithValues(RecordStorageLocation &Loc, QualType Type);
+  void initializeFieldsWithValues(RecordStorageLocation &Loc) {
+initializeFieldsWithValues(Loc, Loc.getType());
+  }
 
   /// Assigns `Val` as the value of `Loc` in the environment.
   void setValue(const

[clang] [clang][dataflow] Propagate locations from result objects to initializers. (PR #87320)

2024-04-02 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-analysis

Author: None (martinboehme)


Changes

Previously, we were propagating storage locations the other way around, i.e.
from initializers to result objects, using `RecordValue::getLoc()`. This gave
the wrong behavior in some cases -- see the newly added or fixed tests in this
patch.

In addition, this patch now unblocks removing the `RecordValue` class entirely,
as we no longer need `RecordValue::getLoc()`.

With this patch, the test `TransferTest.DifferentReferenceLocInJoin` started to
fail because the framework now always uses the same storge location for a
`MaterializeTemporaryExpr`, meaning that the code under test no longer set up
the desired state where a variable of reference type is mapped to two different
storage locations in environments being joined. Rather than trying to modify
this test to set up the test condition again, I have chosen to replace the test
with an equivalent test in DataflowEnvironmentTest.cpp that sets up the test
condition directly; because this test is more direct, it will also be less
brittle in the face of future changes.


---

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


6 Files Affected:

- (modified) clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
(+44-20) 
- (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+304-98) 
- (modified) clang/lib/Analysis/FlowSensitive/Transfer.cpp (+73-99) 
- (modified) clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp 
(+3-10) 
- (modified) clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp 
(+43) 
- (modified) clang/unittests/Analysis/FlowSensitive/TransferTest.cpp (+115-57) 


``diff
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index c30bccd06674a4..dc3a9c239552be 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -30,6 +30,7 @@
 #include "llvm/ADT/MapVector.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
+#include 
 #include 
 #include 
 
@@ -330,17 +331,6 @@ class Environment {
   /// location of the result object to pass in `this`, even though prvalues are
   /// otherwise not associated with storage locations.
   ///
-  /// FIXME: Currently, this simply returns a stable storage location for `E`,
-  /// but this doesn't do the right thing in scenarios like the following:
-  /// ```
-  /// MyClass c = some_condition()? MyClass(foo) : MyClass(bar);
-  /// ```
-  /// Here, `MyClass(foo)` and `MyClass(bar)` will have two different storage
-  /// locations, when in fact their storage locations should be the same.
-  /// Eventually, we want to propagate storage locations from result objects
-  /// down to the prvalues that initialize them, similar to the way that this 
is
-  /// done in Clang's CodeGen.
-  ///
   /// Requirements:
   ///  `E` must be a prvalue of record type.
   RecordStorageLocation &
@@ -448,7 +438,13 @@ class Environment {
   /// Initializes the fields (including synthetic fields) of `Loc` with values,
   /// unless values of the field type are not supported or we hit one of the
   /// limits at which we stop producing values.
-  void initializeFieldsWithValues(RecordStorageLocation &Loc);
+  /// If `Type` is provided, initializes only those fields that are modeled for
+  /// `Type`; this is intended for use in cases where `Loc` is a derived type
+  /// and we only want to initialize the fields of a base type.
+  void initializeFieldsWithValues(RecordStorageLocation &Loc, QualType Type);
+  void initializeFieldsWithValues(RecordStorageLocation &Loc) {
+initializeFieldsWithValues(Loc, Loc.getType());
+  }
 
   /// Assigns `Val` as the value of `Loc` in the environment.
   void setValue(const StorageLocation &Loc, Value &Val);
@@ -639,6 +635,9 @@ class Environment {
   LLVM_DUMP_METHOD void dump(raw_ostream &OS) const;
 
 private:
+  using PrValueToResultObject =
+  llvm::DenseMap;
+
   // The copy-constructor is for use in fork() only.
   Environment(const Environment &) = default;
 
@@ -668,8 +667,10 @@ class Environment {
   /// Initializes the fields (including synthetic fields) of `Loc` with values,
   /// unless values of the field type are not supported or we hit one of the
   /// limits at which we stop producing values (controlled by `Visited`,
-  /// `Depth`, and `CreatedValuesCount`).
-  void initializeFieldsWithValues(RecordStorageLocation &Loc,
+  /// `Depth`, and `CreatedValuesCount`). If `Type` is different from
+  /// `Loc.getType()`, initializes only those fields that are modeled for
+  /// `Type`.
+  void initializeFieldsWithValues(RecordStorageLocation &Loc, QualType Type,
   llvm::DenseSet &Visited, int Depth

[clang] [clang] Catch missing format attributes (PR #70024)

2024-04-02 Thread Budimir Aranđelović via cfe-commits

https://github.com/budimirarandjelovicsyrmia updated 
https://github.com/llvm/llvm-project/pull/70024

From 7adedf54a6c4d509046915777600b6e66b90bb8c Mon Sep 17 00:00:00 2001
From: budimirarandjelovicsyrmia 
Date: Fri, 13 Oct 2023 14:45:15 +0200
Subject: [PATCH] [clang] Catch missing format attributes

---
 clang/docs/ReleaseNotes.rst   |   4 +-
 clang/include/clang/Basic/DiagnosticGroups.td |   1 -
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Sema/Sema.h   |   4 +
 clang/lib/Sema/SemaChecking.cpp   |   4 +-
 clang/lib/Sema/SemaDeclAttr.cpp   | 105 +
 clang/test/Sema/attr-format-missing.c | 223 ++
 clang/test/Sema/attr-format-missing.cpp   | 211 +
 8 files changed, 552 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Sema/attr-format-missing.c
 create mode 100644 clang/test/Sema/attr-format-missing.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9cc2a72f4c864d..1ca055f65f2115 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -65,7 +65,9 @@ Improvements to Clang's diagnostics
 ^^^
 - We now generate a diagnostic for signed integer overflow due to unary minus
   in a non-constant expression context. This fixes
-  `Issue 31643 `_
+  `Issue 31643 `_.
+- We now generate a diagnostic for missing format attributes
+  `Issue 60718 `_.
 
 Non-comprehensive list of changes in this release
 -
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 17fdcffa2d4274..114cbbc2e82b85 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -482,7 +482,6 @@ def MainReturnType : DiagGroup<"main-return-type">;
 def MaxUnsignedZero : DiagGroup<"max-unsigned-zero">;
 def MissingBraces : DiagGroup<"missing-braces">;
 def MissingDeclarations: DiagGroup<"missing-declarations">;
-def : DiagGroup<"missing-format-attribute">;
 def : DiagGroup<"missing-include-dirs">;
 def MissingNoreturn : DiagGroup<"missing-noreturn">;
 def MultiChar : DiagGroup<"multichar">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6d6f474f6dcdab..964166b70c2aee 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -936,6 +936,9 @@ def err_opencl_invalid_param : Error<
 def err_opencl_invalid_return : Error<
   "declaring function return value of type %0 is not allowed %select{; did you 
forget * ?|}1">;
 def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
+def warn_missing_format_attribute : Warning<
+  "diagnostic behavior may be improved by adding the %0 format attribute to 
the declaration of %1">,
+  InGroup>, DefaultIgnore;
 def warn_pragma_options_align_reset_failed : Warning<
   "#pragma options align=reset failed: %0">,
   InGroup;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 741c2503127af7..064506e7096033 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10615,6 +10615,10 @@ class Sema final {
 ChangedStateAtExit
   };
 
+  void DiagnoseMissingFormatAttributes(const FunctionDecl *FDecl,
+   ArrayRef Args,
+   SourceLocation Loc);
+
   void DiagnoseNonDefaultPragmaAlignPack(PragmaAlignPackDiagnoseKind Kind,
  SourceLocation IncludeLoc);
   void DiagnoseUnterminatedPragmaAlignPack();
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4602284309491c..d3ac6cb519c56e 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6014,8 +6014,10 @@ void Sema::checkCall(NamedDecl *FDecl, const 
FunctionProtoType *Proto,
 }
   }
 
-  if (FD)
+  if (FD) {
 diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc);
+DiagnoseMissingFormatAttributes(FD, Args, Range.getBegin());
+  }
 }
 
 /// CheckConstructorCall - Check a constructor call for correctness and safety
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1a0bfb3d91bcc8..f2134f2aac70bd 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6849,6 +6849,111 @@ static void handleSwiftAsyncAttr(Sema &S, Decl *D, 
const ParsedAttr &AL) {
 checkSwiftAsyncErrorBlock(S, D, ErrorAttr, AsyncAttr);
 }
 
+// This function is called only if function call is not inside template body.
+// TODO: Add call for function calls inside template body.
+// Check if parent function misses for

[clang] [llvm] [clang][CodeGen] Fix templated constructors in base classes introduce bugs. (PR #87321)

2024-04-02 Thread via cfe-commits

https://github.com/idler66 created 
https://github.com/llvm/llvm-project/pull/87321

For example, struct base { public : base() {} template  base(T x) 
{} }; struct derived : public base { public: derived() {} derived(derived& 
that): base(that) {} }; int main() { derived d1; derived d2 = d1; return 0;}

The copy constructor of base is not chosen because it is not an exact match for 
the argument type derived. The templated constructor base(T x) can accept 
arguments of any type T. In the line derived(const derived& that): base(that), 
the that object should be copied twice — once during the initialization of the 
derived class and again when passing it to the base class constructor. The 
assignment d2 = d1 via base(that) would result in an infinite recursion and 
eventually lead to a stack overflow.

Multiple executions of copy semantics lead to stack overflow. So, for the 
templated constructor base(T x),
if T is a subclass of base, pass-by-reference should be used!

>From 0233bb27a16ce0480a5fcf246e70880dde7a8868 Mon Sep 17 00:00:00 2001
From: wangjufan 
Date: Sun, 31 Mar 2024 23:49:30 +0800
Subject: [PATCH] [clang][CodeGen] Fix templated constructors in base classes
 introduce bugs.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

For example, struct base { public : base() {} template  base(T x) 
{} };
struct derived : public base { public: derived() {} derived(derived& that): 
base(that) {} };
int main() { derived d1; derived d2 = d1; return 0;}

The copy constructor of base is not chosen because it is not an exact match for 
the argument type derived.
The templated constructor base(T x) can accept arguments of any type T.
In the line derived(const derived& that): base(that), the that object should be 
copied twice — once during the initialization of the derived class and again 
when passing it to the base class constructor.
The assignment d2 = d1 via base(that) would result in an infinite recursion and 
eventually lead to a stack overflow.

Multiple executions of copy semantics lead to stack overflow.
So, for the templated constructor base(T x),
if T is a subclass of base, pass-by-reference should be used!
---
 clang/lib/CodeGen/CGCall.cpp   |  24 ++-
 clang/lib/CodeGen/CodeGenFunction.h|   2 +-
 clang/unittests/CodeGen/CMakeLists.txt |   1 +
 llvm/TemplateInstantiationTest.cpp | 214 +
 4 files changed, 238 insertions(+), 3 deletions(-)
 create mode 100644 llvm/TemplateInstantiationTest.cpp

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 4c2577126e48b3..d265e706aa6958 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4520,7 +4520,7 @@ void CodeGenFunction::EmitCallArgs(
 (isa(AC.getDecl()) &&
  isObjCMethodWithTypeParams(cast(AC.getDecl() 
&&
"Argument and parameter types don't match");
-EmitCallArg(Args, *Arg, ArgTypes[Idx]);
+EmitCallArg(Args, *Arg, ArgTypes[Idx], AC);
 // In particular, we depend on it being the last arg in Args, and the
 // objectsize bits depend on there only being one arg if !LeftToRight.
 assert(InitialArgSize + 1 == Args.size() &&
@@ -4611,7 +4611,7 @@ void CallArg::copyInto(CodeGenFunction &CGF, Address 
Addr) const {
 }
 
 void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
-  QualType type) {
+  QualType type, const AbstractCallee& AC) {
   DisableDebugLocationUpdates Dis(*this, E);
   if (const ObjCIndirectCopyRestoreExpr *CRE
 = dyn_cast(E)) {
@@ -4627,6 +4627,26 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return args.add(EmitReferenceBindingToExpr(E), type);
   }
 
+  auto ShouldPassParametersByReferenceToTemplatedConstructors = [&]() {
+if(1 != AC.getNumParams()) return false;
+if (const CXXRecordDecl* SubRecordDecl = type->getAsCXXRecordDecl()) {
+  if (const CXXConstructorDecl* ConstructorDecl = 
dyn_cast(AC.getDecl())) {
+if(const CXXRecordDecl* BaseRecordDecl = 
dyn_cast(ConstructorDecl->getParent())) {
+  if(SubRecordDecl->isDerivedFrom(BaseRecordDecl)) {
+return true;
+  }
+}
+  }
+}
+return false;
+  };
+  if(ShouldPassParametersByReferenceToTemplatedConstructors()) {
+AggValueSlot Slot = args.isUsingInAlloca()
+? createPlaceholderSlot(*this, type) : CreateAggTemp(type, "agg.tmp");
+RValue RV = Slot.asRValue();
+return args.add(RV, type);
+  }
+
   bool HasAggregateEvalKind = hasAggregateEvaluationKind(type);
 
   // In the Microsoft C++ ABI, aggregate arguments are destructed by the 
callee.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 618e78809db408..f2305a9307396f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4746,7 +4746,7 @@ class CodeGenFunction : public

[clang] [llvm] [clang][CodeGen] Fix templated constructors in base classes introduce bugs. (PR #87321)

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


[clang] [llvm] [clang][CodeGen] Fix templated constructors in base classes introduce bugs. (PR #87321)

2024-04-02 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: idle666 (idler66)


Changes

For example, struct base { public : base() {} template  
base(T x) {} }; struct derived : public base { public: derived() {} 
derived(derived& that): base(that) {} }; int main() { derived d1; derived 
d2 = d1; return 0;}

The copy constructor of base is not chosen because it is not an exact match for 
the argument type derived. The templated constructor base(T x) can accept 
arguments of any type T. In the line derived(const derived& that): 
base(that), the that object should be copied twice — once during the 
initialization of the derived class and again when passing it to the base class 
constructor. The assignment d2 = d1 via base(that) would result in an infinite 
recursion and eventually lead to a stack overflow.

Multiple executions of copy semantics lead to stack overflow. So, for the 
templated constructor base(T x),
if T is a subclass of base, pass-by-reference should be used!

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


4 Files Affected:

- (modified) clang/lib/CodeGen/CGCall.cpp (+22-2) 
- (modified) clang/lib/CodeGen/CodeGenFunction.h (+1-1) 
- (modified) clang/unittests/CodeGen/CMakeLists.txt (+1) 
- (added) llvm/TemplateInstantiationTest.cpp (+214) 


``diff
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 4c2577126e48b3..d265e706aa6958 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4520,7 +4520,7 @@ void CodeGenFunction::EmitCallArgs(
 (isa(AC.getDecl()) &&
  isObjCMethodWithTypeParams(cast(AC.getDecl() 
&&
"Argument and parameter types don't match");
-EmitCallArg(Args, *Arg, ArgTypes[Idx]);
+EmitCallArg(Args, *Arg, ArgTypes[Idx], AC);
 // In particular, we depend on it being the last arg in Args, and the
 // objectsize bits depend on there only being one arg if !LeftToRight.
 assert(InitialArgSize + 1 == Args.size() &&
@@ -4611,7 +4611,7 @@ void CallArg::copyInto(CodeGenFunction &CGF, Address 
Addr) const {
 }
 
 void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
-  QualType type) {
+  QualType type, const AbstractCallee& AC) {
   DisableDebugLocationUpdates Dis(*this, E);
   if (const ObjCIndirectCopyRestoreExpr *CRE
 = dyn_cast(E)) {
@@ -4627,6 +4627,26 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return args.add(EmitReferenceBindingToExpr(E), type);
   }
 
+  auto ShouldPassParametersByReferenceToTemplatedConstructors = [&]() {
+if(1 != AC.getNumParams()) return false;
+if (const CXXRecordDecl* SubRecordDecl = type->getAsCXXRecordDecl()) {
+  if (const CXXConstructorDecl* ConstructorDecl = 
dyn_cast(AC.getDecl())) {
+if(const CXXRecordDecl* BaseRecordDecl = 
dyn_cast(ConstructorDecl->getParent())) {
+  if(SubRecordDecl->isDerivedFrom(BaseRecordDecl)) {
+return true;
+  }
+}
+  }
+}
+return false;
+  };
+  if(ShouldPassParametersByReferenceToTemplatedConstructors()) {
+AggValueSlot Slot = args.isUsingInAlloca()
+? createPlaceholderSlot(*this, type) : CreateAggTemp(type, "agg.tmp");
+RValue RV = Slot.asRValue();
+return args.add(RV, type);
+  }
+
   bool HasAggregateEvalKind = hasAggregateEvaluationKind(type);
 
   // In the Microsoft C++ ABI, aggregate arguments are destructed by the 
callee.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 618e78809db408..f2305a9307396f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4746,7 +4746,7 @@ class CodeGenFunction : public CodeGenTypeCache {
AbstractCallee AC, unsigned ParmNum);
 
   /// EmitCallArg - Emit a single call argument.
-  void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
+  void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType, const 
AbstractCallee& AC);
 
   /// EmitDelegateCallArg - We are performing a delegate call; that
   /// is, the current function is delegating to another one.  Produce
diff --git a/clang/unittests/CodeGen/CMakeLists.txt 
b/clang/unittests/CodeGen/CMakeLists.txt
index a437f441568f27..8870237c85539d 100644
--- a/clang/unittests/CodeGen/CMakeLists.txt
+++ b/clang/unittests/CodeGen/CMakeLists.txt
@@ -9,6 +9,7 @@ add_clang_unittest(ClangCodeGenTests
   CodeGenExternalTest.cpp
   TBAAMetadataTest.cpp
   CheckTargetFeaturesTest.cpp
+  TemplateInstantiationTest.cpp
   )
 
 clang_target_link_libraries(ClangCodeGenTests
diff --git a/llvm/TemplateInstantiationTest.cpp 
b/llvm/TemplateInstantiationTest.cpp
new file mode 100644
index 00..08d8f673bb1d43
--- /dev/null
+++ b/llvm/TemplateInstantiationTest.cpp
@@ -0,0 +1,214 @@
+//===- unittests/CodeGen/TemplateInstantiationTest.cpp - template 
insta

[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread Balázs Kéri via cfe-commits

https://github.com/balazske created 
https://github.com/llvm/llvm-project/pull/87322

The checker may create failure branches for all stream write operations only if 
the new option "pedantic" is set to true.
Result of the write operations is often not checked in typical code. If failure 
branches are created the checker will warn for unchecked write operations and 
generate a lot of "false positives" (these are valid warnings but the 
programmer does not care about this problem).

From 79bbe640c0d60744f484db9965865455b0b15246 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= 
Date: Tue, 2 Apr 2024 09:59:48 +0200
Subject: [PATCH] [clang][analyzer] Add "pedantic" mode to StreamChecker.

The checker may create failure branches for all stream write operations
only if the new option "pedantic" is set to true.
Result of the write operations is often not checked in typical code.
If failure branches are created the checker will warn for unchecked
write operations and generate a lot of "false positives" (these are
valid warnings but the programmer does not care about this problem).
---
 .../clang/StaticAnalyzer/Checkers/Checkers.td |  8 +++
 .../StaticAnalyzer/Checkers/StreamChecker.cpp | 32 +++--
 clang/test/Analysis/stream-errno-note.c   |  1 +
 clang/test/Analysis/stream-errno.c|  1 +
 clang/test/Analysis/stream-error.c|  1 +
 clang/test/Analysis/stream-note.c |  2 +
 clang/test/Analysis/stream-pedantic.c | 71 +++
 .../Analysis/stream-stdlibraryfunctionargs.c  |  3 +
 clang/test/Analysis/stream.c  | 12 ++--
 9 files changed, 121 insertions(+), 10 deletions(-)
 create mode 100644 clang/test/Analysis/stream-pedantic.c

diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 5fe5c9286dabb7..570e0849e0124b 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -604,6 +604,14 @@ def PthreadLockChecker : Checker<"PthreadLock">,
 def StreamChecker : Checker<"Stream">,
   HelpText<"Check stream handling functions">,
   WeakDependencies<[NonNullParamChecker]>,
+  CheckerOptions<[
+CmdLineOption
+  ]>,
   Documentation;
 
 def SimpleStreamChecker : Checker<"SimpleStream">,
diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 069e3a633c1214..337420c3b25df3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -297,6 +297,9 @@ class StreamChecker : public Checker FnDescriptions = {
   {{{"fopen"}, 2}, {nullptr, &StreamChecker::evalFopen, ArgNone}},
@@ -945,6 +948,10 @@ void StreamChecker::evalFreadFwrite(const FnDescription 
*Desc,
   }
 
   // Add transition for the failed state.
+  // At write, add failure case only if "pedantic mode" is on.
+  if (!IsFread && !PedanticMode)
+return;
+
   NonLoc RetVal = makeRetVal(C, E.CE).castAs();
   ProgramStateRef StateFailed =
   State->BindExpr(E.CE, C.getLocationContext(), RetVal);
@@ -1059,6 +1066,9 @@ void StreamChecker::evalFputx(const FnDescription *Desc, 
const CallEvent &Call,
 
   // Add transition for the failed state. The resulting value of the file
   // position indicator for the stream is indeterminate.
+  if (!PedanticMode)
+return;
+
   ProgramStateRef StateFailed = E.bindReturnValue(State, C, *EofVal);
   StateFailed = E.setStreamState(
   StateFailed, StreamState::getOpened(Desc, ErrorFError, true));
@@ -1094,6 +1104,9 @@ void StreamChecker::evalFprintf(const FnDescription *Desc,
 
   // Add transition for the failed state. The resulting value of the file
   // position indicator for the stream is indeterminate.
+  if (!PedanticMode)
+return;
+
   StateFailed = E.setStreamState(
   StateFailed, StreamState::getOpened(Desc, ErrorFError, true));
   C.addTransition(StateFailed, E.getFailureNoteTag(this, C));
@@ -1264,16 +1277,18 @@ void StreamChecker::evalFseek(const FnDescription 
*Desc, const CallEvent &Call,
   if (!E.Init(Desc, Call, C, State))
 return;
 
-  // Bifurcate the state into failed and non-failed.
-  // Return zero on success, -1 on error.
+  // Add success state.
   ProgramStateRef StateNotFailed = E.bindReturnValue(State, C, 0);
-  ProgramStateRef StateFailed = E.bindReturnValue(State, C, -1);
-
   // No failure: Reset the state to opened with no error.
   StateNotFailed =
   E.setStreamState(StateNotFailed, StreamState::getOpened(Desc));
   C.addTransition(StateNotFailed);
 
+  // Add failure state.
+  if (!PedanticMode)
+return;
+
+  ProgramStateRef StateFailed = E.bindReturnValue(State, C, -1);
   // At error it is possible that fseek fails but sets none of the error flags.
   // If fseek failed, assume that the file position becomes indeterminate in 
any
   // case.
@@ -1316,6 +1331,10 @@ void StreamChecker

[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Balázs Kéri (balazske)


Changes

The checker may create failure branches for all stream write operations only if 
the new option "pedantic" is set to true.
Result of the write operations is often not checked in typical code. If failure 
branches are created the checker will warn for unchecked write operations and 
generate a lot of "false positives" (these are valid warnings but the 
programmer does not care about this problem).

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


9 Files Affected:

- (modified) clang/include/clang/StaticAnalyzer/Checkers/Checkers.td (+8) 
- (modified) clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp (+26-6) 
- (modified) clang/test/Analysis/stream-errno-note.c (+1) 
- (modified) clang/test/Analysis/stream-errno.c (+1) 
- (modified) clang/test/Analysis/stream-error.c (+1) 
- (modified) clang/test/Analysis/stream-note.c (+2) 
- (added) clang/test/Analysis/stream-pedantic.c (+71) 
- (modified) clang/test/Analysis/stream-stdlibraryfunctionargs.c (+3) 
- (modified) clang/test/Analysis/stream.c (+8-4) 


``diff
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td 
b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 5fe5c9286dabb7..570e0849e0124b 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -604,6 +604,14 @@ def PthreadLockChecker : Checker<"PthreadLock">,
 def StreamChecker : Checker<"Stream">,
   HelpText<"Check stream handling functions">,
   WeakDependencies<[NonNullParamChecker]>,
+  CheckerOptions<[
+CmdLineOption
+  ]>,
   Documentation;
 
 def SimpleStreamChecker : Checker<"SimpleStream">,
diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index 069e3a633c1214..337420c3b25df3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -297,6 +297,9 @@ class StreamChecker : public Checker FnDescriptions = {
   {{{"fopen"}, 2}, {nullptr, &StreamChecker::evalFopen, ArgNone}},
@@ -945,6 +948,10 @@ void StreamChecker::evalFreadFwrite(const FnDescription 
*Desc,
   }
 
   // Add transition for the failed state.
+  // At write, add failure case only if "pedantic mode" is on.
+  if (!IsFread && !PedanticMode)
+return;
+
   NonLoc RetVal = makeRetVal(C, E.CE).castAs();
   ProgramStateRef StateFailed =
   State->BindExpr(E.CE, C.getLocationContext(), RetVal);
@@ -1059,6 +1066,9 @@ void StreamChecker::evalFputx(const FnDescription *Desc, 
const CallEvent &Call,
 
   // Add transition for the failed state. The resulting value of the file
   // position indicator for the stream is indeterminate.
+  if (!PedanticMode)
+return;
+
   ProgramStateRef StateFailed = E.bindReturnValue(State, C, *EofVal);
   StateFailed = E.setStreamState(
   StateFailed, StreamState::getOpened(Desc, ErrorFError, true));
@@ -1094,6 +1104,9 @@ void StreamChecker::evalFprintf(const FnDescription *Desc,
 
   // Add transition for the failed state. The resulting value of the file
   // position indicator for the stream is indeterminate.
+  if (!PedanticMode)
+return;
+
   StateFailed = E.setStreamState(
   StateFailed, StreamState::getOpened(Desc, ErrorFError, true));
   C.addTransition(StateFailed, E.getFailureNoteTag(this, C));
@@ -1264,16 +1277,18 @@ void StreamChecker::evalFseek(const FnDescription 
*Desc, const CallEvent &Call,
   if (!E.Init(Desc, Call, C, State))
 return;
 
-  // Bifurcate the state into failed and non-failed.
-  // Return zero on success, -1 on error.
+  // Add success state.
   ProgramStateRef StateNotFailed = E.bindReturnValue(State, C, 0);
-  ProgramStateRef StateFailed = E.bindReturnValue(State, C, -1);
-
   // No failure: Reset the state to opened with no error.
   StateNotFailed =
   E.setStreamState(StateNotFailed, StreamState::getOpened(Desc));
   C.addTransition(StateNotFailed);
 
+  // Add failure state.
+  if (!PedanticMode)
+return;
+
+  ProgramStateRef StateFailed = E.bindReturnValue(State, C, -1);
   // At error it is possible that fseek fails but sets none of the error flags.
   // If fseek failed, assume that the file position becomes indeterminate in 
any
   // case.
@@ -1316,6 +1331,10 @@ void StreamChecker::evalFsetpos(const FnDescription 
*Desc,
 
   StateNotFailed = E.setStreamState(
   StateNotFailed, StreamState::getOpened(Desc, ErrorNone, false));
+  C.addTransition(StateNotFailed);
+
+  if (!PedanticMode)
+return;
 
   // At failure ferror could be set.
   // The standards do not tell what happens with the file position at failure.
@@ -1324,7 +1343,6 @@ void StreamChecker::evalFsetpos(const FnDescription *Desc,
   StateFailed = E.setStreamState(
   StateFailed, StreamState::getOpened(Desc, ErrorNone | ErrorFError, 
true));
 
-  C.addTransition(StateNotFailed);
   C.addTransiti

[clang] [analyzer] Remove barely used class 'KnownSVal' (NFC) (PR #86953)

2024-04-02 Thread via cfe-commits


@@ -1238,12 +1238,12 @@ class StoreSiteFinder final : public 
TrackingBugReporterVisitor {
   ///changes to its value in a nested stackframe could be pruned, and
   ///this visitor can prevent that without polluting the bugpath too
   ///much.
-  StoreSiteFinder(bugreporter::TrackerRef ParentTracker, KnownSVal V,
+  StoreSiteFinder(bugreporter::TrackerRef ParentTracker, SVal V,
   const MemRegion *R, TrackingOptions Options,
   const StackFrameContext *OriginSFC = nullptr)
   : TrackingBugReporterVisitor(ParentTracker), R(R), V(V), 
Options(Options),
 OriginSFC(OriginSFC) {
-assert(R);
+assert(!V.isUnknown() && R);

NagyDonat wrote:

Actually, I realized that it's better to avoid asserting that `V` is not 
unknown. This is a precondition that _happens to be satisfied_ because this 
class is constructed in one single location and that is preceded by a 
`!V.isUnknown()` check -- but I'm fairly certain that the actual implementation 
of `StoreSiteFinder` can find a site where `UnknownVal` was stored in a region. 

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


[clang] [analyzer] Remove barely used class 'KnownSVal' (NFC) (PR #86953)

2024-04-02 Thread via cfe-commits

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


[clang] [analyzer] Remove barely used class 'KnownSVal' (NFC) (PR #86953)

2024-04-02 Thread via cfe-commits
=?utf-8?q?Donát?= Nagy 
Message-ID:
In-Reply-To: 


https://github.com/NagyDonat updated 
https://github.com/llvm/llvm-project/pull/86953

>From 638497ef227cf6f3e8d558618a186a3c45935dfc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Don=C3=A1t=20Nagy?= 
Date: Thu, 28 Mar 2024 14:49:15 +0100
Subject: [PATCH 1/2] [analyzer] Remove barely used class 'KnownSVal' (NFC)

The class `KnownSVal` was very magical abstract class within the `SVal`
class hierarchy: with a hacky `classof` method it acted as if it was the
common ancestor of the classes `UndefinedSVal` and `DefinedSVal`.

However, it was only used in two `getAs()` calls and the
signatures of two methods, which does not "pay for" its weird behavior,
so I created this commit that removes it and replaces its use with more
straightforward solutions.
---
 .../Core/BugReporter/BugReporterVisitors.h |  3 ++-
 .../StaticAnalyzer/Core/PathSensitive/SVals.h  |  8 
 .../RetainCountChecker/RetainCountDiagnostics.cpp  |  2 +-
 .../StaticAnalyzer/Core/BugReporterVisitors.cpp| 14 +++---
 4 files changed, 10 insertions(+), 17 deletions(-)

diff --git 
a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h 
b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
index d9b3d9352d3224..cc3d93aabafda4 100644
--- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
+++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
@@ -374,6 +374,7 @@ bool trackExpressionValue(const ExplodedNode *N, const Expr 
*E,
 /// from.
 ///
 /// \param V We're searching for the store where \c R received this value.
+///It may be either defined or undefined, but should not be unknown.
 /// \param R The region we're tracking.
 /// \param Opts Tracking options specifying how we want to track the value.
 /// \param Origin Only adds notes when the last store happened in a
@@ -383,7 +384,7 @@ bool trackExpressionValue(const ExplodedNode *N, const Expr 
*E,
 ///changes to its value in a nested stackframe could be pruned, and
 ///this visitor can prevent that without polluting the bugpath too
 ///much.
-void trackStoredValue(KnownSVal V, const MemRegion *R,
+void trackStoredValue(SVal V, const MemRegion *R,
   PathSensitiveBugReport &Report, TrackingOptions Opts = 
{},
   const StackFrameContext *Origin = nullptr);
 
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index c60528b7685fe8..3a4b0872571494 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -232,14 +232,6 @@ class DefinedSVal : public DefinedOrUnknownSVal {
   : DefinedOrUnknownSVal(Kind, Data) {}
 };
 
-/// Represents an SVal that is guaranteed to not be UnknownVal.
-class KnownSVal : public SVal {
-public:
-  /*implicit*/ KnownSVal(DefinedSVal V) : SVal(V) {}
-  /*implicit*/ KnownSVal(UndefinedVal V) : SVal(V) {}
-  static bool classof(SVal V) { return !V.isUnknown(); }
-};
-
 class NonLoc : public DefinedSVal {
 protected:
   NonLoc(SValKind Kind, const void *Data) : DefinedSVal(Kind, Data) {}
diff --git 
a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 
b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index c3acb73ba7175b..086c3e5e49b770 100644
--- 
a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ 
b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -977,7 +977,7 @@ void RefLeakReport::findBindingToReport(CheckerContext &Ctx,
 //   something like derived regions if we want to construct SVal from
 //   Sym. Instead, we take the value that is definitely stored in that
 //   region, thus guaranteeing that trackStoredValue will work.
-bugreporter::trackStoredValue(AllVarBindings[0].second.castAs(),
+bugreporter::trackStoredValue(AllVarBindings[0].second,
   AllocBindingToReport, *this);
   } else {
 AllocBindingToReport = AllocFirstBinding;
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp 
b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index a0822513a6d02e..ce167d979d5761 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -1238,12 +1238,12 @@ class StoreSiteFinder final : public 
TrackingBugReporterVisitor {
   ///changes to its value in a nested stackframe could be pruned, and
   ///this visitor can prevent that without polluting the bugpath too
   ///much.
-  StoreSiteFinder(bugreporter::TrackerRef ParentTracker, KnownSVal V,
+  StoreSiteFinder(bugreporter::TrackerRef ParentTracker, SVal V,
   const MemRegion *R, TrackingOptions 

[clang] [HLSL][clang] Move hlsl_wave_get_lane_index to EmitHLSLBuiltinExpr (PR #87131)

2024-04-02 Thread Nathan Gauër via cfe-commits

Keenuts wrote:

Hi! Thanks @farzonl and @marcauberer for making sure SPIR-V backend didn't 
break, really appreciate it! 😊

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


[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread via cfe-commits

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


[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread via cfe-commits


@@ -1059,6 +1066,9 @@ void StreamChecker::evalFputx(const FnDescription *Desc, 
const CallEvent &Call,
 
   // Add transition for the failed state. The resulting value of the file
   // position indicator for the stream is indeterminate.
+  if (!PedanticMode)
+return;
+

NagyDonat wrote:

```suggestion
  if (!PedanticMode)
return;

  // Add transition for the failed state. The resulting value of the file
  // position indicator for the stream is indeterminate.
```

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


[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread via cfe-commits

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

Good change, I have a few minor suggestions that tweak comment placement.

I felt that it's confusing to have an "Add a transition for" comment directly 
followed by a seemingly unrelated `if (!PedanticMode)` block -- my suggestions 
swap the comment and the `if` block, but you could also e.g. prefix the comment 
with "In pedantic mode, also..." to clarify the logical connection between the 
`if` and the rest of the comment.

As an unrelated note, please explain this checker option to the documentation 
of the checker (in addition to the `Checkers.td` change).

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


[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread via cfe-commits


@@ -1094,6 +1104,9 @@ void StreamChecker::evalFprintf(const FnDescription *Desc,
 
   // Add transition for the failed state. The resulting value of the file
   // position indicator for the stream is indeterminate.
+  if (!PedanticMode)
+return;
+

NagyDonat wrote:

```suggestion
  if (!PedanticMode)
return;

  // Add transition for the failed state. The resulting value of the file
  // position indicator for the stream is indeterminate.
```

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


[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread via cfe-commits


@@ -1264,16 +1277,18 @@ void StreamChecker::evalFseek(const FnDescription 
*Desc, const CallEvent &Call,
   if (!E.Init(Desc, Call, C, State))
 return;
 
-  // Bifurcate the state into failed and non-failed.
-  // Return zero on success, -1 on error.
+  // Add success state.
   ProgramStateRef StateNotFailed = E.bindReturnValue(State, C, 0);
-  ProgramStateRef StateFailed = E.bindReturnValue(State, C, -1);
-
   // No failure: Reset the state to opened with no error.
   StateNotFailed =
   E.setStreamState(StateNotFailed, StreamState::getOpened(Desc));
   C.addTransition(StateNotFailed);
 
+  // Add failure state.

NagyDonat wrote:

```suggestion
  // In pedantic mode, also add a failure state.
```

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


[clang] Reapply "[clang][nullability] allow _Nonnull etc on nullable class types (#82705)" (PR #87325)

2024-04-02 Thread Sam McCall via cfe-commits

https://github.com/sam-mccall created 
https://github.com/llvm/llvm-project/pull/87325

This reverts commit 28760b63bbf9e267713957105a8d17091fb0d20e.

The last commit was missing the new testcase, now fixed.


>From dfcb5dd823e2eb4614be6e34369ac703eb87312e Mon Sep 17 00:00:00 2001
From: Sam McCall 
Date: Tue, 2 Apr 2024 10:45:09 +0200
Subject: [PATCH] Reapply "[clang][nullability] allow _Nonnull etc on nullable
 class types (#82705)"

This reverts commit 28760b63bbf9e267713957105a8d17091fb0d20e.

The last commit was missing the new testcase, now fixed.
---
 clang/docs/ReleaseNotes.rst   | 15 +
 clang/include/clang/Basic/Attr.td |  3 +-
 clang/include/clang/Basic/AttrDocs.td | 25 
 clang/include/clang/Basic/Features.def|  1 +
 clang/include/clang/Parse/Parser.h|  1 +
 clang/include/clang/Sema/Sema.h   |  3 +
 clang/lib/AST/Type.cpp| 29 ++---
 clang/lib/CodeGen/CGCall.cpp  |  3 +-
 clang/lib/CodeGen/CodeGenFunction.cpp |  3 +-
 clang/lib/Parse/ParseDeclCXX.cpp  | 33 +++---
 clang/lib/Sema/SemaAttr.cpp   | 12 
 clang/lib/Sema/SemaChecking.cpp   |  9 +++
 clang/lib/Sema/SemaDecl.cpp   |  4 +-
 clang/lib/Sema/SemaDeclAttr.cpp   | 18 ++
 clang/lib/Sema/SemaInit.cpp   |  5 ++
 clang/lib/Sema/SemaOverload.cpp   |  7 +++
 clang/lib/Sema/SemaTemplate.cpp   |  1 +
 clang/lib/Sema/SemaType.cpp   | 18 --
 clang/test/Sema/nullability.c |  2 +
 clang/test/SemaCXX/nullability.cpp| 62 ++-
 .../Inputs/nullability-consistency-smart.h|  7 +++
 .../SemaObjCXX/nullability-consistency.mm |  1 +
 22 files changed, 233 insertions(+), 29 deletions(-)
 create mode 100644 clang/test/SemaObjCXX/Inputs/nullability-consistency-smart.h

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 76eaf0bf11c303..b2faab1f1525b2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -253,6 +253,21 @@ Attribute Changes in Clang
   added a new extension query ``__has_extension(swiftcc)`` corresponding to the
   ``__attribute__((swiftcc))`` attribute.
 
+- The ``_Nullable`` and ``_Nonnull`` family of type attributes can now apply
+  to certain C++ class types, such as smart pointers:
+  ``void useObject(std::unique_ptr _Nonnull obj);``.
+
+  This works for standard library types including ``unique_ptr``, 
``shared_ptr``,
+  and ``function``. See
+  `the attribute reference documentation 
`_
+  for the full list.
+
+- The ``_Nullable`` attribute can be applied to C++ class declarations:
+  ``template  class _Nullable MySmartPointer {};``.
+
+  This allows the ``_Nullable`` and ``_Nonnull`` family of type attributes to
+  apply to this class.
+
 Improvements to Clang's diagnostics
 ---
 - Clang now applies syntax highlighting to the code snippets it
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 80e607525a0a37..6584460cf5685e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2178,9 +2178,10 @@ def TypeNonNull : TypeAttr {
   let Documentation = [TypeNonNullDocs];
 }
 
-def TypeNullable : TypeAttr {
+def TypeNullable : DeclOrTypeAttr {
   let Spellings = [CustomKeyword<"_Nullable">];
   let Documentation = [TypeNullableDocs];
+//  let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
 }
 
 def TypeNullableResult : TypeAttr {
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 3ea4d676b4f89d..0ca4ea377fc36a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -4151,6 +4151,20 @@ non-underscored keywords. For example:
   @property (assign, nullable) NSView *superview;
   @property (readonly, nonnull) NSArray *subviews;
 @end
+
+As well as built-in pointer types, the nullability attributes can be attached
+to C++ classes marked with the ``_Nullable`` attribute.
+
+The following C++ standard library types are considered nullable:
+``unique_ptr``, ``shared_ptr``, ``auto_ptr``, ``exception_ptr``, ``function``,
+``move_only_function`` and ``coroutine_handle``.
+
+Types should be marked nullable only where the type itself leaves nullability
+ambiguous. For example, ``std::optional`` is not marked ``_Nullable``, because
+``optional _Nullable`` is redundant and ``optional _Nonnull`` is
+not a useful type. ``std::weak_ptr`` is not nullable, because its nullability
+can change with no visible modification, so static annotation is unlikely to be
+unhelpful.
   }];
 }
 
@@ -4185,6 +4199,17 @@ The ``_Nullable`` nullability qualifier indicates that a 
value of the
 int fetch_or_zero(int * _Nullable ptr);
 
 a caller of

[clang] Reapply "[clang][nullability] allow _Nonnull etc on nullable class types (#82705)" (PR #87325)

2024-04-02 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Sam McCall (sam-mccall)


Changes

This reverts commit 28760b63bbf9e267713957105a8d17091fb0d20e.

The last commit was missing the new testcase, now fixed.


---

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


22 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+15) 
- (modified) clang/include/clang/Basic/Attr.td (+2-1) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+25) 
- (modified) clang/include/clang/Basic/Features.def (+1) 
- (modified) clang/include/clang/Parse/Parser.h (+1) 
- (modified) clang/include/clang/Sema/Sema.h (+3) 
- (modified) clang/lib/AST/Type.cpp (+19-10) 
- (modified) clang/lib/CodeGen/CGCall.cpp (+2-1) 
- (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+2-1) 
- (modified) clang/lib/Parse/ParseDeclCXX.cpp (+24-9) 
- (modified) clang/lib/Sema/SemaAttr.cpp (+12) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+9) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+3-1) 
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+18) 
- (modified) clang/lib/Sema/SemaInit.cpp (+5) 
- (modified) clang/lib/Sema/SemaOverload.cpp (+7) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+1) 
- (modified) clang/lib/Sema/SemaType.cpp (+14-4) 
- (modified) clang/test/Sema/nullability.c (+2) 
- (modified) clang/test/SemaCXX/nullability.cpp (+60-2) 
- (added) clang/test/SemaObjCXX/Inputs/nullability-consistency-smart.h (+7) 
- (modified) clang/test/SemaObjCXX/nullability-consistency.mm (+1) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 76eaf0bf11c303..b2faab1f1525b2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -253,6 +253,21 @@ Attribute Changes in Clang
   added a new extension query ``__has_extension(swiftcc)`` corresponding to the
   ``__attribute__((swiftcc))`` attribute.
 
+- The ``_Nullable`` and ``_Nonnull`` family of type attributes can now apply
+  to certain C++ class types, such as smart pointers:
+  ``void useObject(std::unique_ptr _Nonnull obj);``.
+
+  This works for standard library types including ``unique_ptr``, 
``shared_ptr``,
+  and ``function``. See
+  `the attribute reference documentation 
`_
+  for the full list.
+
+- The ``_Nullable`` attribute can be applied to C++ class declarations:
+  ``template  class _Nullable MySmartPointer {};``.
+
+  This allows the ``_Nullable`` and ``_Nonnull`` family of type attributes to
+  apply to this class.
+
 Improvements to Clang's diagnostics
 ---
 - Clang now applies syntax highlighting to the code snippets it
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 80e607525a0a37..6584460cf5685e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2178,9 +2178,10 @@ def TypeNonNull : TypeAttr {
   let Documentation = [TypeNonNullDocs];
 }
 
-def TypeNullable : TypeAttr {
+def TypeNullable : DeclOrTypeAttr {
   let Spellings = [CustomKeyword<"_Nullable">];
   let Documentation = [TypeNullableDocs];
+//  let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
 }
 
 def TypeNullableResult : TypeAttr {
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 3ea4d676b4f89d..0ca4ea377fc36a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -4151,6 +4151,20 @@ non-underscored keywords. For example:
   @property (assign, nullable) NSView *superview;
   @property (readonly, nonnull) NSArray *subviews;
 @end
+
+As well as built-in pointer types, the nullability attributes can be attached
+to C++ classes marked with the ``_Nullable`` attribute.
+
+The following C++ standard library types are considered nullable:
+``unique_ptr``, ``shared_ptr``, ``auto_ptr``, ``exception_ptr``, ``function``,
+``move_only_function`` and ``coroutine_handle``.
+
+Types should be marked nullable only where the type itself leaves nullability
+ambiguous. For example, ``std::optional`` is not marked ``_Nullable``, because
+``optional _Nullable`` is redundant and ``optional _Nonnull`` is
+not a useful type. ``std::weak_ptr`` is not nullable, because its nullability
+can change with no visible modification, so static annotation is unlikely to be
+unhelpful.
   }];
 }
 
@@ -4185,6 +4199,17 @@ The ``_Nullable`` nullability qualifier indicates that a 
value of the
 int fetch_or_zero(int * _Nullable ptr);
 
 a caller of ``fetch_or_zero`` can provide null.
+
+The ``_Nullable`` attribute on classes indicates that the given class can
+represent null values, and so the ``_Nullable``, ``_Nonnull`` etc qualifiers
+make sense for this type. For example:
+
+  .. code-block:: c
+
+class _Nullable ArenaPointer { ... };
+
+ArenaPointer _Nonnull x = ...;
+ArenaPointer _Nullabl

[clang] Revert "Reapply "[clang][nullability] allow _Nonnull etc on nullable class types (#82705)"" (PR #87041)

2024-04-02 Thread Sam McCall via cfe-commits

sam-mccall wrote:

Sorry Douglas, and thanks for the revert.
(I missed including the new test file in the commit - I'll make sure to run 
through CI when relanding this!)

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


[clang] [llvm] [RFC][AMDGPU] Add OpenCL-specific fence address space masks (PR #78572)

2024-04-02 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 59dd10faf8c3bb9dbcecb60d932284b8762cebf8 
36bcf92bf7187b07a3842d3077b9f28c556e -- 
clang/test/CodeGenCXX/builtin-amdgcn-fence-opencl.cpp 
llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h 
llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp 
llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp 
clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CodeGenFunction.h 
clang/lib/Sema/SemaChecking.cpp llvm/include/llvm/Analysis/VectorUtils.h 
llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h 
llvm/include/llvm/CodeGen/MachineFunction.h 
llvm/include/llvm/CodeGen/MachineInstr.h 
llvm/include/llvm/CodeGen/MachineInstrBuilder.h 
llvm/include/llvm/CodeGen/SelectionDAG.h llvm/include/llvm/IR/IRBuilder.h 
llvm/lib/Analysis/VectorUtils.cpp llvm/lib/CodeGen/AtomicExpandPass.cpp 
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp 
llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp 
llvm/lib/CodeGen/MIRPrinter.cpp llvm/lib/CodeGen/MachineFunction.cpp 
llvm/lib/CodeGen/MachineInstr.cpp 
llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp 
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp 
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp 
llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp 
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/lib/IR/IRBuilder.cpp 
llvm/lib/IR/Instruction.cpp llvm/lib/IR/Verifier.cpp 
llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp 
llvm/lib/Transforms/Scalar/MergedLoadStoreMotion.cpp 
llvm/lib/Transforms/Utils/Local.cpp llvm/lib/Transforms/Utils/SimplifyCFG.cpp 
llvm/unittests/CodeGen/MachineInstrTest.cpp
``





View the diff from clang-format here.


``diff
diff --git a/llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h 
b/llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h
index d7e3519179..a9ded6034d 100644
--- a/llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h
+++ b/llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h
@@ -24,8 +24,7 @@
 
 namespace llvm {
 
-template
-class ArrayRef;
+template  class ArrayRef;
 
 class MDNode;
 class MDTuple;
diff --git a/llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp 
b/llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp
index a9e14d81a0..19f438d890 100644
--- a/llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp
+++ b/llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp
@@ -62,15 +62,16 @@ MDTuple *MMRAMetadata::getTagMD(LLVMContext &Ctx, StringRef 
Prefix,
   {MDString::get(Ctx, Prefix), MDString::get(Ctx, 
Suffix)});
 }
 
-MDTuple *MMRAMetadata::getMD(LLVMContext &Ctx, ArrayRef 
Tags) {
+MDTuple *MMRAMetadata::getMD(LLVMContext &Ctx,
+ ArrayRef Tags) {
   if (Tags.empty())
 return nullptr;
 
   if (Tags.size() == 1)
 return getTagMD(Ctx, Tags.front());
 
-  SmallVector MMRAs;
-  for(const auto &Tag: Tags)
+  SmallVector MMRAs;
+  for (const auto &Tag : Tags)
 MMRAs.push_back(getTagMD(Ctx, Tag));
   return MDTuple::get(Ctx, MMRAs);
 }
diff --git a/llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp 
b/llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp
index 13e52909ae..623236436e 100644
--- a/llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp
+++ b/llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp
@@ -57,18 +57,18 @@ TEST(MMRATest, GetMD) {
 
   EXPECT_EQ(MMRAMetadata::getMD(Ctx, {}), nullptr);
 
-  MDTuple* SingleMD = MMRAMetadata::getMD(Ctx, {{"foo", "bar"}});
+  MDTuple *SingleMD = MMRAMetadata::getMD(Ctx, {{"foo", "bar"}});
   EXPECT_EQ(SingleMD->getNumOperands(), 2);
   EXPECT_EQ(cast(SingleMD->getOperand(0))->getString(), "foo");
   EXPECT_EQ(cast(SingleMD->getOperand(1))->getString(), "bar");
 
-  MDTuple* MultiMD = MMRAMetadata::getMD(Ctx, {{"foo", "bar"}, {"bux", 
"qux"}});
+  MDTuple *MultiMD = MMRAMetadata::getMD(Ctx, {{"foo", "bar"}, {"bux", 
"qux"}});
   EXPECT_EQ(MultiMD->getNumOperands(), 2);
 
-  MDTuple* FooBar = cast(MultiMD->getOperand(0));
+  MDTuple *FooBar = cast(MultiMD->getOperand(0));
   EXPECT_EQ(cast(FooBar->getOperand(0))->getString(), "foo");
   EXPECT_EQ(cast(FooBar->getOperand(1))->getString(), "bar");
-  MDTuple* BuxQux = cast(MultiMD->getOperand(1));
+  MDTuple *BuxQux = cast(MultiMD->getOperand(1));
   EXPECT_EQ(cast(BuxQux->getOperand(0))->getString(), "bux");
   EXPECT_EQ(cast(BuxQux->getOperand(1))->getString(), "qux");
 }

``




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


[clang] [llvm] [RFC][AMDGPU] Add vulkan:private/nonprivate MMRAs support (PR #78573)

2024-04-02 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 59dd10faf8c3bb9dbcecb60d932284b8762cebf8 
4e9fd8a4c6f38bca145493e5e7cfe818a090a965 -- 
clang/test/CodeGenCXX/builtin-amdgcn-fence-opencl.cpp 
llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h 
llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp 
llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp 
clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CodeGenFunction.h 
clang/lib/Sema/SemaChecking.cpp llvm/include/llvm/Analysis/VectorUtils.h 
llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h 
llvm/include/llvm/CodeGen/MachineFunction.h 
llvm/include/llvm/CodeGen/MachineInstr.h 
llvm/include/llvm/CodeGen/MachineInstrBuilder.h 
llvm/include/llvm/CodeGen/SelectionDAG.h llvm/include/llvm/IR/IRBuilder.h 
llvm/lib/Analysis/VectorUtils.cpp llvm/lib/CodeGen/AtomicExpandPass.cpp 
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp 
llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp 
llvm/lib/CodeGen/MIRPrinter.cpp llvm/lib/CodeGen/MachineFunction.cpp 
llvm/lib/CodeGen/MachineInstr.cpp 
llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp 
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp 
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp 
llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp 
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/lib/IR/IRBuilder.cpp 
llvm/lib/IR/Instruction.cpp llvm/lib/IR/Verifier.cpp 
llvm/lib/Target/AMDGPU/SIMemoryLegalizer.cpp 
llvm/lib/Transforms/Scalar/MergedLoadStoreMotion.cpp 
llvm/lib/Transforms/Utils/Local.cpp llvm/lib/Transforms/Utils/SimplifyCFG.cpp 
llvm/unittests/CodeGen/MachineInstrTest.cpp
``





View the diff from clang-format here.


``diff
diff --git a/llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h 
b/llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h
index d7e3519179..a9ded6034d 100644
--- a/llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h
+++ b/llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h
@@ -24,8 +24,7 @@
 
 namespace llvm {
 
-template
-class ArrayRef;
+template  class ArrayRef;
 
 class MDNode;
 class MDTuple;
diff --git a/llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp 
b/llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp
index a9e14d81a0..19f438d890 100644
--- a/llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp
+++ b/llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp
@@ -62,15 +62,16 @@ MDTuple *MMRAMetadata::getTagMD(LLVMContext &Ctx, StringRef 
Prefix,
   {MDString::get(Ctx, Prefix), MDString::get(Ctx, 
Suffix)});
 }
 
-MDTuple *MMRAMetadata::getMD(LLVMContext &Ctx, ArrayRef 
Tags) {
+MDTuple *MMRAMetadata::getMD(LLVMContext &Ctx,
+ ArrayRef Tags) {
   if (Tags.empty())
 return nullptr;
 
   if (Tags.size() == 1)
 return getTagMD(Ctx, Tags.front());
 
-  SmallVector MMRAs;
-  for(const auto &Tag: Tags)
+  SmallVector MMRAs;
+  for (const auto &Tag : Tags)
 MMRAs.push_back(getTagMD(Ctx, Tag));
   return MDTuple::get(Ctx, MMRAs);
 }
diff --git a/llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp 
b/llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp
index 13e52909ae..623236436e 100644
--- a/llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp
+++ b/llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp
@@ -57,18 +57,18 @@ TEST(MMRATest, GetMD) {
 
   EXPECT_EQ(MMRAMetadata::getMD(Ctx, {}), nullptr);
 
-  MDTuple* SingleMD = MMRAMetadata::getMD(Ctx, {{"foo", "bar"}});
+  MDTuple *SingleMD = MMRAMetadata::getMD(Ctx, {{"foo", "bar"}});
   EXPECT_EQ(SingleMD->getNumOperands(), 2);
   EXPECT_EQ(cast(SingleMD->getOperand(0))->getString(), "foo");
   EXPECT_EQ(cast(SingleMD->getOperand(1))->getString(), "bar");
 
-  MDTuple* MultiMD = MMRAMetadata::getMD(Ctx, {{"foo", "bar"}, {"bux", 
"qux"}});
+  MDTuple *MultiMD = MMRAMetadata::getMD(Ctx, {{"foo", "bar"}, {"bux", 
"qux"}});
   EXPECT_EQ(MultiMD->getNumOperands(), 2);
 
-  MDTuple* FooBar = cast(MultiMD->getOperand(0));
+  MDTuple *FooBar = cast(MultiMD->getOperand(0));
   EXPECT_EQ(cast(FooBar->getOperand(0))->getString(), "foo");
   EXPECT_EQ(cast(FooBar->getOperand(1))->getString(), "bar");
-  MDTuple* BuxQux = cast(MultiMD->getOperand(1));
+  MDTuple *BuxQux = cast(MultiMD->getOperand(1));
   EXPECT_EQ(cast(BuxQux->getOperand(0))->getString(), "bux");
   EXPECT_EQ(cast(BuxQux->getOperand(1))->getString(), "qux");
 }

``




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


[clang] [C++20][Coroutines] Lambda-coroutine with operator new in promise_type (PR #84193)

2024-04-02 Thread Chuanqi Xu via cfe-commits

ChuanqiXu9 wrote:

Hi Andreas, thanks for looking into this. I am still confused about whether or 
not your new branch can fix the crash or not.

For the question about the crash itself, I don't have any insight though, I 
feel like this is a defect in the code generator. I didn't understand why mark 
a variable as referenced or not by the frontend may affect the code generation.

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


[clang] [llvm] [clang][CodeGen] Fix templated constructors in base classes introduce bugs. (PR #87321)

2024-04-02 Thread via cfe-commits

https://github.com/idler66 updated 
https://github.com/llvm/llvm-project/pull/87321

>From 0233bb27a16ce0480a5fcf246e70880dde7a8868 Mon Sep 17 00:00:00 2001
From: wangjufan 
Date: Sun, 31 Mar 2024 23:49:30 +0800
Subject: [PATCH] [clang][CodeGen] Fix templated constructors in base classes
 introduce bugs.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

For example, struct base { public : base() {} template  base(T x) 
{} };
struct derived : public base { public: derived() {} derived(derived& that): 
base(that) {} };
int main() { derived d1; derived d2 = d1; return 0;}

The copy constructor of base is not chosen because it is not an exact match for 
the argument type derived.
The templated constructor base(T x) can accept arguments of any type T.
In the line derived(const derived& that): base(that), the that object should be 
copied twice — once during the initialization of the derived class and again 
when passing it to the base class constructor.
The assignment d2 = d1 via base(that) would result in an infinite recursion and 
eventually lead to a stack overflow.

Multiple executions of copy semantics lead to stack overflow.
So, for the templated constructor base(T x),
if T is a subclass of base, pass-by-reference should be used!
---
 clang/lib/CodeGen/CGCall.cpp   |  24 ++-
 clang/lib/CodeGen/CodeGenFunction.h|   2 +-
 clang/unittests/CodeGen/CMakeLists.txt |   1 +
 llvm/TemplateInstantiationTest.cpp | 214 +
 4 files changed, 238 insertions(+), 3 deletions(-)
 create mode 100644 llvm/TemplateInstantiationTest.cpp

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 4c2577126e48b3..d265e706aa6958 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4520,7 +4520,7 @@ void CodeGenFunction::EmitCallArgs(
 (isa(AC.getDecl()) &&
  isObjCMethodWithTypeParams(cast(AC.getDecl() 
&&
"Argument and parameter types don't match");
-EmitCallArg(Args, *Arg, ArgTypes[Idx]);
+EmitCallArg(Args, *Arg, ArgTypes[Idx], AC);
 // In particular, we depend on it being the last arg in Args, and the
 // objectsize bits depend on there only being one arg if !LeftToRight.
 assert(InitialArgSize + 1 == Args.size() &&
@@ -4611,7 +4611,7 @@ void CallArg::copyInto(CodeGenFunction &CGF, Address 
Addr) const {
 }
 
 void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
-  QualType type) {
+  QualType type, const AbstractCallee& AC) {
   DisableDebugLocationUpdates Dis(*this, E);
   if (const ObjCIndirectCopyRestoreExpr *CRE
 = dyn_cast(E)) {
@@ -4627,6 +4627,26 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return args.add(EmitReferenceBindingToExpr(E), type);
   }
 
+  auto ShouldPassParametersByReferenceToTemplatedConstructors = [&]() {
+if(1 != AC.getNumParams()) return false;
+if (const CXXRecordDecl* SubRecordDecl = type->getAsCXXRecordDecl()) {
+  if (const CXXConstructorDecl* ConstructorDecl = 
dyn_cast(AC.getDecl())) {
+if(const CXXRecordDecl* BaseRecordDecl = 
dyn_cast(ConstructorDecl->getParent())) {
+  if(SubRecordDecl->isDerivedFrom(BaseRecordDecl)) {
+return true;
+  }
+}
+  }
+}
+return false;
+  };
+  if(ShouldPassParametersByReferenceToTemplatedConstructors()) {
+AggValueSlot Slot = args.isUsingInAlloca()
+? createPlaceholderSlot(*this, type) : CreateAggTemp(type, "agg.tmp");
+RValue RV = Slot.asRValue();
+return args.add(RV, type);
+  }
+
   bool HasAggregateEvalKind = hasAggregateEvaluationKind(type);
 
   // In the Microsoft C++ ABI, aggregate arguments are destructed by the 
callee.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index 618e78809db408..f2305a9307396f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4746,7 +4746,7 @@ class CodeGenFunction : public CodeGenTypeCache {
AbstractCallee AC, unsigned ParmNum);
 
   /// EmitCallArg - Emit a single call argument.
-  void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
+  void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType, const 
AbstractCallee& AC);
 
   /// EmitDelegateCallArg - We are performing a delegate call; that
   /// is, the current function is delegating to another one.  Produce
diff --git a/clang/unittests/CodeGen/CMakeLists.txt 
b/clang/unittests/CodeGen/CMakeLists.txt
index a437f441568f27..8870237c85539d 100644
--- a/clang/unittests/CodeGen/CMakeLists.txt
+++ b/clang/unittests/CodeGen/CMakeLists.txt
@@ -9,6 +9,7 @@ add_clang_unittest(ClangCodeGenTests
   CodeGenExternalTest.cpp
   TBAAMetadataTest.cpp
   CheckTargetFeaturesTest.cpp
+  TemplateInstantiationTest.cpp
   )
 
 clang_target_link_libraries(ClangCodeGenTe

[clang] [llvm] [clang][CodeGen] Fix templated constructors in base classes introduce bugs. (PR #87321)

2024-04-02 Thread via cfe-commits

https://github.com/idler66 updated 
https://github.com/llvm/llvm-project/pull/87321

>From 20dc290ea0d01d3b9979b189652e6eedec8c6923 Mon Sep 17 00:00:00 2001
From: wangjufan 
Date: Sun, 31 Mar 2024 23:49:30 +0800
Subject: [PATCH] [clang][CodeGen] Fix templated constructors in base classes
 introduce bugs.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

For example, struct base { public : base() {} template  base(T x) 
{} };
struct derived : public base { public: derived() {} derived(derived& that): 
base(that) {} };
int main() { derived d1; derived d2 = d1; return 0;}

The copy constructor of base is not chosen because it is not an exact match for 
the argument type derived.
The templated constructor base(T x) can accept arguments of any type T.
In the line derived(const derived& that): base(that), the that object should be 
copied twice — once during the initialization of the derived class and again 
when passing it to the base class constructor.
The assignment d2 = d1 via base(that) would result in an infinite recursion and 
eventually lead to a stack overflow.

Multiple executions of copy semantics lead to stack overflow.
So, for the templated constructor base(T x),
if T is a subclass of base, pass-by-reference should be used!
---
 clang/lib/CodeGen/CGCall.cpp   |  24 ++-
 clang/lib/CodeGen/CodeGenFunction.h|   2 +-
 clang/unittests/CodeGen/CMakeLists.txt |   1 +
 llvm/TemplateInstantiationTest.cpp | 214 +
 4 files changed, 238 insertions(+), 3 deletions(-)
 create mode 100644 llvm/TemplateInstantiationTest.cpp

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 9308528ac93823..76f70bf6b8a8e2 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4573,7 +4573,7 @@ void CodeGenFunction::EmitCallArgs(
 (isa(AC.getDecl()) &&
  isObjCMethodWithTypeParams(cast(AC.getDecl() 
&&
"Argument and parameter types don't match");
-EmitCallArg(Args, *Arg, ArgTypes[Idx]);
+EmitCallArg(Args, *Arg, ArgTypes[Idx], AC);
 // In particular, we depend on it being the last arg in Args, and the
 // objectsize bits depend on there only being one arg if !LeftToRight.
 assert(InitialArgSize + 1 == Args.size() &&
@@ -4664,7 +4664,7 @@ void CallArg::copyInto(CodeGenFunction &CGF, Address 
Addr) const {
 }
 
 void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
-  QualType type) {
+  QualType type, const AbstractCallee& AC) {
   DisableDebugLocationUpdates Dis(*this, E);
   if (const ObjCIndirectCopyRestoreExpr *CRE
 = dyn_cast(E)) {
@@ -4680,6 +4680,26 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return args.add(EmitReferenceBindingToExpr(E), type);
   }
 
+  auto ShouldPassParametersByReferenceToTemplatedConstructors = [&]() {
+if(1 != AC.getNumParams()) return false;
+if (const CXXRecordDecl* SubRecordDecl = type->getAsCXXRecordDecl()) {
+  if (const CXXConstructorDecl* ConstructorDecl = 
dyn_cast(AC.getDecl())) {
+if(const CXXRecordDecl* BaseRecordDecl = 
dyn_cast(ConstructorDecl->getParent())) {
+  if(SubRecordDecl->isDerivedFrom(BaseRecordDecl)) {
+return true;
+  }
+}
+  }
+}
+return false;
+  };
+  if(ShouldPassParametersByReferenceToTemplatedConstructors()) {
+AggValueSlot Slot = args.isUsingInAlloca()
+? createPlaceholderSlot(*this, type) : CreateAggTemp(type, "agg.tmp");
+RValue RV = Slot.asRValue();
+return args.add(RV, type);
+  }
+
   bool HasAggregateEvalKind = hasAggregateEvaluationKind(type);
 
   // In the Microsoft C++ ABI, aggregate arguments are destructed by the 
callee.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index e2a7e28c8211ea..cf713d6fc07dd0 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4958,7 +4958,7 @@ class CodeGenFunction : public CodeGenTypeCache {
unsigned ParmNum);
 
   /// EmitCallArg - Emit a single call argument.
-  void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
+  void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType, const 
AbstractCallee& AC);
 
   /// EmitDelegateCallArg - We are performing a delegate call; that
   /// is, the current function is delegating to another one.  Produce
diff --git a/clang/unittests/CodeGen/CMakeLists.txt 
b/clang/unittests/CodeGen/CMakeLists.txt
index a437f441568f27..8870237c85539d 100644
--- a/clang/unittests/CodeGen/CMakeLists.txt
+++ b/clang/unittests/CodeGen/CMakeLists.txt
@@ -9,6 +9,7 @@ add_clang_unittest(ClangCodeGenTests
   CodeGenExternalTest.cpp
   TBAAMetadataTest.cpp
   CheckTargetFeaturesTest.cpp
+  TemplateInstantiationTest.cpp
   )
 
 clang_target_link_libraries(ClangCodeGenTests
diff --git a/ll

[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread Balazs Benics via cfe-commits

https://github.com/steakhal commented:

Unless you plan to add more heuristics, I'd prefer a more concrete option name, 
like AssumeSuccessfulWrites=true.
This would better describe it imo.

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


[clang] [llvm] [clang][CodeGen] Fix templated constructors in base classes introduce bugs. (PR #87321)

2024-04-02 Thread via cfe-commits

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


[clang] [clang-format] Lambda parameter should be passed by const reference (PR #87306)

2024-04-02 Thread Simon Pilgrim via cfe-commits


@@ -3578,7 +3578,7 @@ cleanupAroundReplacements(StringRef Code, const 
tooling::Replacements &Replaces,
   // We need to use lambda function here since there are two versions of
   // `cleanup`.
   auto Cleanup = [](const FormatStyle &Style, StringRef Code,
-std::vector Ranges,
+const std::vector &Ranges,

RKSimon wrote:

Since cleanup() takes an `ArrayRef` should this also?

https://github.com/llvm/llvm-project/pull/87306
___
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-04-02 Thread Jay Foad via cfe-commits


@@ -2594,12 +2594,10 @@ bool SIMemoryLegalizer::expandAtomicCmpxchgOrRmw(const 
SIMemOpInfo &MOI,
 MOI.getOrdering() == AtomicOrdering::SequentiallyConsistent ||
 MOI.getFailureOrdering() == AtomicOrdering::Acquire ||
 MOI.getFailureOrdering() == AtomicOrdering::SequentiallyConsistent) {
-  Changed |= CC->insertWait(MI, MOI.getScope(),
-MOI.getInstrAddrSpace(),
-isAtomicRet(*MI) ? SIMemOp::LOAD :
-   SIMemOp::STORE,
-MOI.getIsCrossAddressSpaceOrdering(),
-Position::AFTER);
+  Changed |=

jayfoad wrote:

Remove this.

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] [llvm] [AMDGPU] Emit a waitcnt instruction after each memory instruction (PR #79236)

2024-04-02 Thread Jay Foad via cfe-commits


@@ -0,0 +1,1406 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 4
+; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -mattr=+precise-memory < %s | 
FileCheck %s -check-prefixes=GFX9
+; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -mattr=+precise-memory < %s | 
FileCheck %s -check-prefixes=GFX90A
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1010 -mattr=+precise-memory < %s | 
FileCheck %s -check-prefixes=GFX10
+; RUN: llc -mtriple=amdgcn -mcpu=gfx900 
-mattr=+enable-flat-scratch,+precise-memory < %s | FileCheck 
--check-prefixes=GFX9-FLATSCR %s
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+precise-memory < %s | 
FileCheck %s -check-prefixes=GFX11
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1200 -mattr=+precise-memory < %s | 
FileCheck %s -check-prefixes=GFX12
+
+; from atomicrmw-expand.ll
+; covers flat_load, flat_atomic (atomic with return)
+;
+define void @syncscope_workgroup_nortn(ptr %addr, float %val) {
+; GFX9-LABEL: syncscope_workgroup_nortn:
+; GFX9:   ; %bb.0:
+; GFX9-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:flat_load_dword v4, v[0:1]
+; GFX9-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-NEXT:s_mov_b64 s[4:5], 0
+; GFX9-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX9-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX9-NEXT:v_add_f32_e32 v3, v4, v2
+; GFX9-NEXT:flat_atomic_cmpswap v3, v[0:1], v[3:4] glc
+; GFX9-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-NEXT:v_cmp_eq_u32_e32 vcc, v3, v4
+; GFX9-NEXT:s_or_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT:v_mov_b32_e32 v4, v3
+; GFX9-NEXT:s_andn2_b64 exec, exec, s[4:5]
+; GFX9-NEXT:s_cbranch_execnz .LBB0_1
+; GFX9-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX9-NEXT:s_or_b64 exec, exec, s[4:5]
+; GFX9-NEXT:s_setpc_b64 s[30:31]
+;
+; GFX90A-LABEL: syncscope_workgroup_nortn:
+; GFX90A:   ; %bb.0:
+; GFX90A-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX90A-NEXT:flat_load_dword v5, v[0:1]
+; GFX90A-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX90A-NEXT:s_mov_b64 s[4:5], 0
+; GFX90A-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX90A-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX90A-NEXT:v_add_f32_e32 v4, v5, v2
+; GFX90A-NEXT:flat_atomic_cmpswap v3, v[0:1], v[4:5] glc
+; GFX90A-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX90A-NEXT:v_cmp_eq_u32_e32 vcc, v3, v5
+; GFX90A-NEXT:s_or_b64 s[4:5], vcc, s[4:5]
+; GFX90A-NEXT:v_mov_b32_e32 v5, v3
+; GFX90A-NEXT:s_andn2_b64 exec, exec, s[4:5]
+; GFX90A-NEXT:s_cbranch_execnz .LBB0_1
+; GFX90A-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX90A-NEXT:s_or_b64 exec, exec, s[4:5]
+; GFX90A-NEXT:s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: syncscope_workgroup_nortn:
+; GFX10:   ; %bb.0:
+; GFX10-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:flat_load_dword v4, v[0:1]
+; GFX10-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX10-NEXT:s_mov_b32 s4, 0
+; GFX10-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX10-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX10-NEXT:v_add_f32_e32 v3, v4, v2
+; GFX10-NEXT:s_waitcnt_vscnt null, 0x0
+; GFX10-NEXT:flat_atomic_cmpswap v3, v[0:1], v[3:4] glc
+; GFX10-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX10-NEXT:buffer_gl0_inv
+; GFX10-NEXT:v_cmp_eq_u32_e32 vcc_lo, v3, v4
+; GFX10-NEXT:v_mov_b32_e32 v4, v3
+; GFX10-NEXT:s_or_b32 s4, vcc_lo, s4
+; GFX10-NEXT:s_andn2_b32 exec_lo, exec_lo, s4
+; GFX10-NEXT:s_cbranch_execnz .LBB0_1
+; GFX10-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX10-NEXT:s_or_b32 exec_lo, exec_lo, s4
+; GFX10-NEXT:s_setpc_b64 s[30:31]
+;
+; GFX9-FLATSCR-LABEL: syncscope_workgroup_nortn:
+; GFX9-FLATSCR:   ; %bb.0:
+; GFX9-FLATSCR-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-FLATSCR-NEXT:flat_load_dword v4, v[0:1]
+; GFX9-FLATSCR-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-FLATSCR-NEXT:s_mov_b64 s[0:1], 0
+; GFX9-FLATSCR-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX9-FLATSCR-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX9-FLATSCR-NEXT:v_add_f32_e32 v3, v4, v2
+; GFX9-FLATSCR-NEXT:flat_atomic_cmpswap v3, v[0:1], v[3:4] glc
+; GFX9-FLATSCR-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-FLATSCR-NEXT:v_cmp_eq_u32_e32 vcc, v3, v4
+; GFX9-FLATSCR-NEXT:s_or_b64 s[0:1], vcc, s[0:1]
+; GFX9-FLATSCR-NEXT:v_mov_b32_e32 v4, v3
+; GFX9-FLATSCR-NEXT:s_andn2_b64 exec, exec, s[0:1]
+; GFX9-FLATSCR-NEXT:s_cbranch_execnz .LBB0_1
+; GFX9-FLATSCR-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX9-FLATSCR-NEXT:s_or_b64 exec, exec, s[0:1]
+; GFX9-FLATSCR-NEXT:s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: syncscope_workgroup_nortn:
+; GFX11:   ; %bb.0:
+; GFX11-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:flat_load_b32 v4, v[0:1]
+; GFX11-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX11-NEXT:s_mov_b32 s0, 0
+; GFX11-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX11-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX11-NEXT:s_delay_al

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

2024-04-02 Thread Jay Foad via cfe-commits


@@ -0,0 +1,1406 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 4
+; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -mattr=+precise-memory < %s | 
FileCheck %s -check-prefixes=GFX9
+; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -mattr=+precise-memory < %s | 
FileCheck %s -check-prefixes=GFX90A
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1010 -mattr=+precise-memory < %s | 
FileCheck %s -check-prefixes=GFX10
+; RUN: llc -mtriple=amdgcn -mcpu=gfx900 
-mattr=+enable-flat-scratch,+precise-memory < %s | FileCheck 
--check-prefixes=GFX9-FLATSCR %s
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+precise-memory < %s | 
FileCheck %s -check-prefixes=GFX11
+; RUN: llc -mtriple=amdgcn -mcpu=gfx1200 -mattr=+precise-memory < %s | 
FileCheck %s -check-prefixes=GFX12
+
+; from atomicrmw-expand.ll
+; covers flat_load, flat_atomic (atomic with return)
+;
+define void @syncscope_workgroup_nortn(ptr %addr, float %val) {
+; GFX9-LABEL: syncscope_workgroup_nortn:
+; GFX9:   ; %bb.0:
+; GFX9-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-NEXT:flat_load_dword v4, v[0:1]
+; GFX9-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-NEXT:s_mov_b64 s[4:5], 0
+; GFX9-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX9-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX9-NEXT:v_add_f32_e32 v3, v4, v2
+; GFX9-NEXT:flat_atomic_cmpswap v3, v[0:1], v[3:4] glc
+; GFX9-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-NEXT:v_cmp_eq_u32_e32 vcc, v3, v4
+; GFX9-NEXT:s_or_b64 s[4:5], vcc, s[4:5]
+; GFX9-NEXT:v_mov_b32_e32 v4, v3
+; GFX9-NEXT:s_andn2_b64 exec, exec, s[4:5]
+; GFX9-NEXT:s_cbranch_execnz .LBB0_1
+; GFX9-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX9-NEXT:s_or_b64 exec, exec, s[4:5]
+; GFX9-NEXT:s_setpc_b64 s[30:31]
+;
+; GFX90A-LABEL: syncscope_workgroup_nortn:
+; GFX90A:   ; %bb.0:
+; GFX90A-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX90A-NEXT:flat_load_dword v5, v[0:1]
+; GFX90A-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX90A-NEXT:s_mov_b64 s[4:5], 0
+; GFX90A-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX90A-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX90A-NEXT:v_add_f32_e32 v4, v5, v2
+; GFX90A-NEXT:flat_atomic_cmpswap v3, v[0:1], v[4:5] glc
+; GFX90A-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX90A-NEXT:v_cmp_eq_u32_e32 vcc, v3, v5
+; GFX90A-NEXT:s_or_b64 s[4:5], vcc, s[4:5]
+; GFX90A-NEXT:v_mov_b32_e32 v5, v3
+; GFX90A-NEXT:s_andn2_b64 exec, exec, s[4:5]
+; GFX90A-NEXT:s_cbranch_execnz .LBB0_1
+; GFX90A-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX90A-NEXT:s_or_b64 exec, exec, s[4:5]
+; GFX90A-NEXT:s_setpc_b64 s[30:31]
+;
+; GFX10-LABEL: syncscope_workgroup_nortn:
+; GFX10:   ; %bb.0:
+; GFX10-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX10-NEXT:flat_load_dword v4, v[0:1]
+; GFX10-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX10-NEXT:s_mov_b32 s4, 0
+; GFX10-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX10-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX10-NEXT:v_add_f32_e32 v3, v4, v2
+; GFX10-NEXT:s_waitcnt_vscnt null, 0x0
+; GFX10-NEXT:flat_atomic_cmpswap v3, v[0:1], v[3:4] glc
+; GFX10-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX10-NEXT:buffer_gl0_inv
+; GFX10-NEXT:v_cmp_eq_u32_e32 vcc_lo, v3, v4
+; GFX10-NEXT:v_mov_b32_e32 v4, v3
+; GFX10-NEXT:s_or_b32 s4, vcc_lo, s4
+; GFX10-NEXT:s_andn2_b32 exec_lo, exec_lo, s4
+; GFX10-NEXT:s_cbranch_execnz .LBB0_1
+; GFX10-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX10-NEXT:s_or_b32 exec_lo, exec_lo, s4
+; GFX10-NEXT:s_setpc_b64 s[30:31]
+;
+; GFX9-FLATSCR-LABEL: syncscope_workgroup_nortn:
+; GFX9-FLATSCR:   ; %bb.0:
+; GFX9-FLATSCR-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX9-FLATSCR-NEXT:flat_load_dword v4, v[0:1]
+; GFX9-FLATSCR-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-FLATSCR-NEXT:s_mov_b64 s[0:1], 0
+; GFX9-FLATSCR-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX9-FLATSCR-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX9-FLATSCR-NEXT:v_add_f32_e32 v3, v4, v2
+; GFX9-FLATSCR-NEXT:flat_atomic_cmpswap v3, v[0:1], v[3:4] glc
+; GFX9-FLATSCR-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-FLATSCR-NEXT:v_cmp_eq_u32_e32 vcc, v3, v4
+; GFX9-FLATSCR-NEXT:s_or_b64 s[0:1], vcc, s[0:1]
+; GFX9-FLATSCR-NEXT:v_mov_b32_e32 v4, v3
+; GFX9-FLATSCR-NEXT:s_andn2_b64 exec, exec, s[0:1]
+; GFX9-FLATSCR-NEXT:s_cbranch_execnz .LBB0_1
+; GFX9-FLATSCR-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX9-FLATSCR-NEXT:s_or_b64 exec, exec, s[0:1]
+; GFX9-FLATSCR-NEXT:s_setpc_b64 s[30:31]
+;
+; GFX11-LABEL: syncscope_workgroup_nortn:
+; GFX11:   ; %bb.0:
+; GFX11-NEXT:s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
+; GFX11-NEXT:flat_load_b32 v4, v[0:1]
+; GFX11-NEXT:s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX11-NEXT:s_mov_b32 s0, 0
+; GFX11-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX11-NEXT:; =>This Inner Loop Header: Depth=1
+; GFX11-NEXT:s_delay_al

[clang] [X86_32] Teach X86_32 va_arg to ignore empty structs. (PR #86075)

2024-04-02 Thread Longsheng Mou via cfe-commits

https://github.com/CoTinker updated 
https://github.com/llvm/llvm-project/pull/86075

>From 95a11789d89a57cc96512bd180949164f89695d0 Mon Sep 17 00:00:00 2001
From: Longsheng Mou 
Date: Thu, 21 Mar 2024 11:23:56 +0800
Subject: [PATCH] [X86_32] Teach X86_32 va_arg to ignore empty structs.

Empty structs are ignored for parameter passing purposes, but va_arg was
incrementing the pointer anyway for that the size of empty struct in c++
is 1 byte, which could lead to va_list getting out of sync.
---
 clang/lib/CodeGen/Targets/X86.cpp  |  6 ++
 clang/test/CodeGenCXX/x86_32-vaarg.cpp | 20 
 2 files changed, 26 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/x86_32-vaarg.cpp

diff --git a/clang/lib/CodeGen/Targets/X86.cpp 
b/clang/lib/CodeGen/Targets/X86.cpp
index 1146a851a7715d..c831777699f627 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -1069,6 +1069,12 @@ Address X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF,
 
   auto TypeInfo = getContext().getTypeInfoInChars(Ty);
 
+  CCState State(*const_cast(CGF.CurFnInfo));
+  ABIArgInfo AI = classifyArgumentType(Ty, State, /*ArgIndex*/ 0);
+  // Empty records are ignored for parameter passing purposes.
+  if (AI.isIgnore())
+return CGF.CreateMemTemp(Ty);
+
   // x86-32 changes the alignment of certain arguments on the stack.
   //
   // Just messing with TypeInfo like this works because we never pass
diff --git a/clang/test/CodeGenCXX/x86_32-vaarg.cpp 
b/clang/test/CodeGenCXX/x86_32-vaarg.cpp
new file mode 100644
index 00..23eac1164118c6
--- /dev/null
+++ b/clang/test/CodeGenCXX/x86_32-vaarg.cpp
@@ -0,0 +1,20 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple i386-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-linux-gnu -emit-llvm -x c -o - %s | FileCheck 
%s
+
+typedef struct {} empty;
+
+// CHECK-LABEL: @{{.*}}empty_record_test
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[RESULT_PTR:%.*]] = alloca ptr, align 4
+// CHECK-NEXT:[[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:[[LIST:%.*]] = alloca ptr, align 4
+// CHECK-NEXT:[[TMP:%.*]] = alloca [[STRUCT_EMPTY:%.*]], align 1
+// CHECK-NEXT:store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4
+// CHECK-NEXT:store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:call void @llvm.va_start(ptr [[LIST]])
+empty empty_record_test(int z, ...) {
+  __builtin_va_list list;
+  __builtin_va_start(list, z);
+  return __builtin_va_arg(list, empty);
+}

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


[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)

2024-04-02 Thread Haojian Wu via cfe-commits

https://github.com/hokein updated 
https://github.com/llvm/llvm-project/pull/82776

>From 7fcd58b750872221aa754e81e17ab9068e144a44 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 23 Feb 2024 10:03:16 +0100
Subject: [PATCH 1/2] [clang] Add __builtin_start_object_lifetime builtin.

This patch implements a clang built `__builtin_start_object_lifetime`,
it has the same semantics as C++23's `std::start_lifetime_as`, but
without the implicit-lifetime type restriction, it can be used for
implementing `std::start_lifetime_as` in the future.

Due to the current clang lowering, the builtin reuses the existing 
`__builtin_launder` implementation:
- it is a no-op for the most part;
- with `-fstrict-vtable-pointers` flag, we update the vtpr assumption correctly
  (mark the load/store vptr with appropriate invariant group intrinsics)
  to prevent incorrect vptr load folding;
- for now, the builtin is non-constant, cannot be executed in constant 
evaluation;

CAVEAT:
- this builtin may cause TBAA miscomplies without the `-fno-strict-alias`
  flag. These TBAA miscompiles are known issues and may need more LLVM
  IR support for the fix, fixing them is orthogonal to the implementaton of the
  builtin.

Context: 
https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy/76961
---
 clang/include/clang/Basic/Builtins.td |  6 +++
 clang/lib/CodeGen/CGBuiltin.cpp   |  1 +
 clang/lib/Sema/SemaChecking.cpp   |  2 +
 clang/test/CodeGen/builtins.c | 10 
 .../builtin-start-object-life-time.cpp| 49 +++
 clang/test/SemaCXX/builtins.cpp   | 33 -
 6 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenCXX/builtin-start-object-life-time.cpp

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index f421223ff087de..2c2e0eb58b15a1 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -926,6 +926,12 @@ def Launder : Builtin {
   let Prototype = "void*(void*)";
 }
 
+def StartObjectLifeTime : Builtin {
+  let Spellings = ["__builtin_start_object_lifetime"];
+  let Attributes = [NoThrow, CustomTypeChecking];
+  let Prototype = "void*(void*)";
+}
+
 def IsConstantEvaluated : LangBuiltin<"CXX_LANG"> {
   let Spellings = ["__builtin_is_constant_evaluated"];
   let Attributes = [NoThrow, Constexpr];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 483f9c26859923..6cdb602f8bb07d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4509,6 +4509,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 
 return RValue::get(nullptr);
   }
+  case Builtin::BI__builtin_start_object_lifetime:
   case Builtin::BI__builtin_launder: {
 const Expr *Arg = E->getArg(0);
 QualType ArgTy = Arg->getType()->getPointeeType();
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 11401b6f56c0ea..356765609f694b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -37,6 +37,7 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/UnresolvedSet.h"
 #include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/IdentifierTable.h"
@@ -2642,6 +2643,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 TheCall->setType(Context.IntTy);
 break;
   }
+  case Builtin::BI__builtin_start_object_lifetime:
   case Builtin::BI__builtin_launder:
 return SemaBuiltinLaunder(*this, TheCall);
   case Builtin::BI__sync_fetch_and_add:
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 407e0857d22311..00c81c23d0ed02 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -143,6 +143,7 @@ int main(void) {
   P(signbit, (1.0));
 
   R(launder, (&N));
+  R(start_object_lifetime, (&N));
 
   return 0;
 }
@@ -511,6 +512,15 @@ void test_builtin_launder(int *p) {
   int *d = __builtin_launder(p);
 }
 
+/// It should be a NOP in C since there are no vtables.
+// CHECK-LABEL: define{{.*}} void @test_builtin_start_object_lifetime
+void test_builtin_start_object_lifetime(int *p) {
+  // CHECK: [[TMP:%.*]] = load ptr,
+  // CHECK-NOT: @llvm.launder
+  // CHECK: store ptr [[TMP]],
+  int *d = __builtin_start_object_lifetime(p);
+}
+
 // __warn_memset_zero_len should be NOP, see 
https://sourceware.org/bugzilla/show_bug.cgi?id=25399
 // CHECK-LABEL: define{{.*}} void @test___warn_memset_zero_len
 void test___warn_memset_zero_len(void) {
diff --git a/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp 
b/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp
new file mode 100644
index 00..58012f52cc0ef5
--- /dev/null
+++ b/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp
@@ -0

[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)

2024-04-02 Thread Haojian Wu via cfe-commits


@@ -4386,6 +4386,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 
 return RValue::get(nullptr);
   }
+  case Builtin::BI__builtin_start_object_lifetime:
   case Builtin::BI__builtin_launder: {

hokein wrote:

I think the name is fine, we're in the CodeGen, and the BuiltinLaunder in 
`TypeRequiresBuiltinLaunder` means the LLVM IR `llvm.launder` 
[intrinsics](https://llvm.org/docs/LangRef.html#llvm-launder-invariant-group-intrinsic).

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


[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)

2024-04-02 Thread Haojian Wu via cfe-commits


@@ -896,6 +896,12 @@ def Launder : Builtin {
   let Prototype = "void*(void*)";
 }
 
+def StartObjectLifeTime : Builtin {

hokein wrote:

Done.

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


[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)

2024-04-02 Thread Haojian Wu via cfe-commits


@@ -4386,6 +4386,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 
 return RValue::get(nullptr);
   }
+  case Builtin::BI__builtin_start_object_lifetime:

hokein wrote:

Added a comment for it, please take a look.

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


[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)

2024-04-02 Thread Haojian Wu via cfe-commits


@@ -896,6 +896,12 @@ def Launder : Builtin {
   let Prototype = "void*(void*)";
 }
 
+def StartObjectLifeTime : Builtin {
+  let Spellings = ["__builtin_start_object_lifetime"];

hokein wrote:

I don't have strong opinion on the name. Since this builtin doesn't strictly 
align with std::start_lifetime_as, I think it's better to have some divergence 
in the name.

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


[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)

2024-04-02 Thread Haojian Wu via cfe-commits


@@ -156,6 +156,37 @@ void test_noexcept(int *i) {
 #undef TEST_TYPE
 } // end namespace test_launder
 
+namespace test_start_object_lifetime {
+// The builtin is non-constant.
+constexpr int test_non_constexpr(int i) { // expected-error {{constexpr 
function never produces a constant expression}}
+  __builtin_start_object_lifetime(&i); // expected-note {{subexpression not 
valid in a constant expression}}
+#ifdef CXX11
+  // expected-warning@-2 {{use of this statement in a constexpr function is a 
C++14 extension}}
+#endif
+  return 0;
+}
+
+struct Incomplete; // expected-note {{forward declaration}}
+void test_incomplete(Incomplete *i) {
+   // Requires a complete type
+   __builtin_start_object_lifetime(i); // expected-error {{incomplete type 
'Incomplete' where a complete type is required}}
+}
+
+// The builtin is type-generic.
+#define TEST_TYPE(Ptr, Type) \
+  static_assert(__is_same(decltype(__builtin_launder(Ptr)), Type), "expected 
same type")

hokein wrote:

oops, yeah, it should be `__builtin_start_object_lifetime `.

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


[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread via cfe-commits

NagyDonat wrote:

Personally I like the habit that these options are consistently named 
"Pedantic" because it highlights that they all provide "true, but not helpful" 
results. When the users see that an option is named "Pedantic", many of them 
will be able to immediately conclude that they are not interested; while if the 
option was named "AssumeSuccessfulWrites", they would need to understand its 
exact meaning (so they would probably read the full doc, not just the name) and 
its relevance in their project to make a decision.

I agree that "AssumeSuccessfulWrites" is more informative in a certain sense, 
but it still doesn't convey enough information for a full understanding; and 
"Pedantic" provides a different kind of information that (IMO) is more 
practical overall.

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread Yitzhak Mandelbaum via cfe-commits


@@ -122,17 +135,19 @@ class Environment {
 ///
 ///  `Prev` and `Current` must be assigned to the same storage location in
 ///  `PrevEnv` and `CurrentEnv`, respectively.
-virtual Value *widen(QualType Type, Value &Prev, const Environment 
&PrevEnv,
- Value &Current, Environment &CurrentEnv) {
+virtual std::optional widen(QualType Type, Value &Prev,

ymand wrote:

That's the *only* override I could find. So, I think we'll just prepare a patch 
to crubit to coincide with pushing this.

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


[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread Balázs Kéri via cfe-commits

balazske wrote:

> Unless you plan to add more heuristics, I'd prefer a more concrete option 
> name, like AssumeSuccessfulWrites=true. This would better describe it imo.

I do not like totally the name "Pedantic", it could be 
"AssumeOftenUncheckedOperationsMayFail". I am not sure if this behavior is 
needed only on write operations, the intent was to remove failure branches from 
all operations that are often unchecked.

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread Yitzhak Mandelbaum via cfe-commits


@@ -805,6 +805,25 @@ class NullPointerAnalysis final
 else
   JoinedVal.setProperty("is_null", JoinedEnv.makeTopBoolValue());
   }
+
+  std::optional widen(QualType Type, Value &Prev,
+   const Environment &PrevEnv, Value &Current,
+   Environment &CurrentEnv) override {

ymand wrote:

I added this so that we can test the widening functionality. Turns out we had 
no tests for framework calls to `widen`.

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread Yitzhak Mandelbaum via cfe-commits


@@ -975,6 +994,35 @@ TEST_F(WideningTest, 
DistinctValuesWithSamePropertiesAreEquivalent) {
   });
 }
 
+TEST_F(WideningTest, DistinctValuesWithDifferentPropertiesWidenedToTop) {
+  std::string Code = R"(
+void target(bool Cond) {
+  int *Foo;
+  int i = 0;
+  Foo = nullptr;
+  while (Cond) {
+Foo = &i;
+  }
+  (void)0;
+  /*[[p]]*/
+}
+  )";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));

ymand wrote:

Great. I've removed it here and in all other cases of WideningTest.

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


[clang] [clang][analyzer] Add "pedantic" mode to StreamChecker. (PR #87322)

2024-04-02 Thread via cfe-commits

NagyDonat wrote:

I feel that "AssumeOftenUncheckedOperationsMayFail" does not provide more 
information than "Pedantic" (≈ report issues that are often left unchecked), 
while it is significantly longer, so my preferences are _Pedantic > 
AssumeSuccessfulWrites > AssumeOftenUncheckedOperationsMayFail_.

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread Yitzhak Mandelbaum via cfe-commits


@@ -975,6 +994,35 @@ TEST_F(WideningTest, 
DistinctValuesWithSamePropertiesAreEquivalent) {
   });
 }
 
+TEST_F(WideningTest, DistinctValuesWithDifferentPropertiesWidenedToTop) {
+  std::string Code = R"(
+void target(bool Cond) {
+  int *Foo;
+  int i = 0;
+  Foo = nullptr;
+  while (Cond) {
+Foo = &i;
+  }
+  (void)0;
+  /*[[p]]*/
+}
+  )";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+
+const auto *FooVal = Env.getValue(*FooDecl);
+EXPECT_TRUE(areEquivalentValues(*FooVal->getProperty("is_null"),

ymand wrote:

I prefer direct assertion, because it results in a cleaner error message on 
failure (crashing the test process vs exiting the test with a test-assertion 
failure).

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


[clang] [clang][CodeGen] Fix templated constructors in base classes introduce bugs. (PR #87332)

2024-04-02 Thread via cfe-commits

https://github.com/idler66 created 
https://github.com/llvm/llvm-project/pull/87332

For example, struct base { public : base() {} template  base(T x) 
{} }; struct derived : public base { public: derived() {} derived(derived& 
that): base(that) {} }; int main() { derived d1; derived d2 = d1; return 0;}

The copy constructor of base is not chosen because it is not an exact match for 
the argument type derived. The templated constructor base(T x) can accept 
arguments of any type T. In the line derived(const derived& that): base(that), 
the that object should be copied twice — once during the initialization of the 
derived class and again when passing it to the base class constructor. The 
assignment d2 = d1 via base(that) would result in an infinite recursion and 
eventually lead to a stack overflow.

Multiple executions of copy semantics lead to stack overflow. So, for the 
templated constructor base(T x),
if T is a subclass of base, pass-by-reference should be used!

>From e36764032dd624f26ab44a7bc3f1126eb98617ae Mon Sep 17 00:00:00 2001
From: wangjufan 
Date: Sun, 31 Mar 2024 23:49:30 +0800
Subject: [PATCH] [clang][CodeGen] Fix templated constructors in base classes
 introduce bugs.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

For example, struct base { public : base() {} template  base(T x) 
{} };
struct derived : public base { public: derived() {} derived(derived& that): 
base(that) {} };
int main() { derived d1; derived d2 = d1; return 0;}

The copy constructor of base is not chosen because it is not an exact match for 
the argument type derived.
The templated constructor base(T x) can accept arguments of any type T.
In the line derived(const derived& that): base(that), the that object should be 
copied twice — once during the initialization of the derived class and again 
when passing it to the base class constructor.
The assignment d2 = d1 via base(that) would result in an infinite recursion and 
eventually lead to a stack overflow.

Multiple executions of copy semantics lead to stack overflow.
So, for the templated constructor base(T x),
if T is a subclass of base, pass-by-reference should be used!
---
 clang/lib/CodeGen/CGCall.cpp  |  24 +-
 clang/lib/CodeGen/CodeGenFunction.h   |   2 +-
 clang/unittests/CodeGen/CMakeLists.txt|   1 +
 .../CodeGen/TemplateInstantiationTest.cpp | 214 ++
 4 files changed, 238 insertions(+), 3 deletions(-)
 create mode 100644 clang/unittests/CodeGen/TemplateInstantiationTest.cpp

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 9308528ac93823..76f70bf6b8a8e2 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4573,7 +4573,7 @@ void CodeGenFunction::EmitCallArgs(
 (isa(AC.getDecl()) &&
  isObjCMethodWithTypeParams(cast(AC.getDecl() 
&&
"Argument and parameter types don't match");
-EmitCallArg(Args, *Arg, ArgTypes[Idx]);
+EmitCallArg(Args, *Arg, ArgTypes[Idx], AC);
 // In particular, we depend on it being the last arg in Args, and the
 // objectsize bits depend on there only being one arg if !LeftToRight.
 assert(InitialArgSize + 1 == Args.size() &&
@@ -4664,7 +4664,7 @@ void CallArg::copyInto(CodeGenFunction &CGF, Address 
Addr) const {
 }
 
 void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
-  QualType type) {
+  QualType type, const AbstractCallee& AC) {
   DisableDebugLocationUpdates Dis(*this, E);
   if (const ObjCIndirectCopyRestoreExpr *CRE
 = dyn_cast(E)) {
@@ -4680,6 +4680,26 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return args.add(EmitReferenceBindingToExpr(E), type);
   }
 
+  auto ShouldPassParametersByReferenceToTemplatedConstructors = [&]() {
+if(1 != AC.getNumParams()) return false;
+if (const CXXRecordDecl* SubRecordDecl = type->getAsCXXRecordDecl()) {
+  if (const CXXConstructorDecl* ConstructorDecl = 
dyn_cast(AC.getDecl())) {
+if(const CXXRecordDecl* BaseRecordDecl = 
dyn_cast(ConstructorDecl->getParent())) {
+  if(SubRecordDecl->isDerivedFrom(BaseRecordDecl)) {
+return true;
+  }
+}
+  }
+}
+return false;
+  };
+  if(ShouldPassParametersByReferenceToTemplatedConstructors()) {
+AggValueSlot Slot = args.isUsingInAlloca()
+? createPlaceholderSlot(*this, type) : CreateAggTemp(type, "agg.tmp");
+RValue RV = Slot.asRValue();
+return args.add(RV, type);
+  }
+
   bool HasAggregateEvalKind = hasAggregateEvaluationKind(type);
 
   // In the Microsoft C++ ABI, aggregate arguments are destructed by the 
callee.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index e2a7e28c8211ea..cf713d6fc07dd0 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4958,7 +4

[clang] [clang][CodeGen] Fix templated constructors in base classes introduce bugs. (PR #87332)

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


[clang] [clang][CodeGen] Fix templated constructors in base classes introduce bugs. (PR #87332)

2024-04-02 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: idle666 (idler66)


Changes

For example, struct base { public : base() {} template  
base(T x) {} }; struct derived : public base { public: derived() {} 
derived(derived& that): base(that) {} }; int main() { derived d1; derived 
d2 = d1; return 0;}

The copy constructor of base is not chosen because it is not an exact match for 
the argument type derived. The templated constructor base(T x) can accept 
arguments of any type T. In the line derived(const derived& that): 
base(that), the that object should be copied twice — once during the 
initialization of the derived class and again when passing it to the base class 
constructor. The assignment d2 = d1 via base(that) would result in an infinite 
recursion and eventually lead to a stack overflow.

Multiple executions of copy semantics lead to stack overflow. So, for the 
templated constructor base(T x),
if T is a subclass of base, pass-by-reference should be used!

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


4 Files Affected:

- (modified) clang/lib/CodeGen/CGCall.cpp (+22-2) 
- (modified) clang/lib/CodeGen/CodeGenFunction.h (+1-1) 
- (modified) clang/unittests/CodeGen/CMakeLists.txt (+1) 
- (added) clang/unittests/CodeGen/TemplateInstantiationTest.cpp (+214) 


``diff
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 9308528ac93823..76f70bf6b8a8e2 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4573,7 +4573,7 @@ void CodeGenFunction::EmitCallArgs(
 (isa(AC.getDecl()) &&
  isObjCMethodWithTypeParams(cast(AC.getDecl() 
&&
"Argument and parameter types don't match");
-EmitCallArg(Args, *Arg, ArgTypes[Idx]);
+EmitCallArg(Args, *Arg, ArgTypes[Idx], AC);
 // In particular, we depend on it being the last arg in Args, and the
 // objectsize bits depend on there only being one arg if !LeftToRight.
 assert(InitialArgSize + 1 == Args.size() &&
@@ -4664,7 +4664,7 @@ void CallArg::copyInto(CodeGenFunction &CGF, Address 
Addr) const {
 }
 
 void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
-  QualType type) {
+  QualType type, const AbstractCallee& AC) {
   DisableDebugLocationUpdates Dis(*this, E);
   if (const ObjCIndirectCopyRestoreExpr *CRE
 = dyn_cast(E)) {
@@ -4680,6 +4680,26 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, 
const Expr *E,
 return args.add(EmitReferenceBindingToExpr(E), type);
   }
 
+  auto ShouldPassParametersByReferenceToTemplatedConstructors = [&]() {
+if(1 != AC.getNumParams()) return false;
+if (const CXXRecordDecl* SubRecordDecl = type->getAsCXXRecordDecl()) {
+  if (const CXXConstructorDecl* ConstructorDecl = 
dyn_cast(AC.getDecl())) {
+if(const CXXRecordDecl* BaseRecordDecl = 
dyn_cast(ConstructorDecl->getParent())) {
+  if(SubRecordDecl->isDerivedFrom(BaseRecordDecl)) {
+return true;
+  }
+}
+  }
+}
+return false;
+  };
+  if(ShouldPassParametersByReferenceToTemplatedConstructors()) {
+AggValueSlot Slot = args.isUsingInAlloca()
+? createPlaceholderSlot(*this, type) : CreateAggTemp(type, "agg.tmp");
+RValue RV = Slot.asRValue();
+return args.add(RV, type);
+  }
+
   bool HasAggregateEvalKind = hasAggregateEvaluationKind(type);
 
   // In the Microsoft C++ ABI, aggregate arguments are destructed by the 
callee.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h 
b/clang/lib/CodeGen/CodeGenFunction.h
index e2a7e28c8211ea..cf713d6fc07dd0 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4958,7 +4958,7 @@ class CodeGenFunction : public CodeGenTypeCache {
unsigned ParmNum);
 
   /// EmitCallArg - Emit a single call argument.
-  void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
+  void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType, const 
AbstractCallee& AC);
 
   /// EmitDelegateCallArg - We are performing a delegate call; that
   /// is, the current function is delegating to another one.  Produce
diff --git a/clang/unittests/CodeGen/CMakeLists.txt 
b/clang/unittests/CodeGen/CMakeLists.txt
index a437f441568f27..8870237c85539d 100644
--- a/clang/unittests/CodeGen/CMakeLists.txt
+++ b/clang/unittests/CodeGen/CMakeLists.txt
@@ -9,6 +9,7 @@ add_clang_unittest(ClangCodeGenTests
   CodeGenExternalTest.cpp
   TBAAMetadataTest.cpp
   CheckTargetFeaturesTest.cpp
+  TemplateInstantiationTest.cpp
   )
 
 clang_target_link_libraries(ClangCodeGenTests
diff --git a/clang/unittests/CodeGen/TemplateInstantiationTest.cpp 
b/clang/unittests/CodeGen/TemplateInstantiationTest.cpp
new file mode 100644
index 00..08d8f673bb1d43
--- /dev/null
+++ b/clang/unittests/CodeGen/TemplateInstantiationTest.cpp
@@ -0,0 +1,214 @@
+//===- unittest

[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread Yitzhak Mandelbaum via cfe-commits

https://github.com/ymand updated https://github.com/llvm/llvm-project/pull/87233

>From d8d875271bd47b71701143afb06ea654546e2b7c Mon Sep 17 00:00:00 2001
From: Yitzhak Mandelbaum 
Date: Mon, 1 Apr 2024 12:13:39 +
Subject: [PATCH 1/2] [clang][dataflow] Refactor `widen` API to be explicit
 about change effect.

The previous API relied on pointer equality of inputs and outputs to signal
whether a change occured. This was too subtle and led to bugs in practice. It
was also very limiting: the override could not return an equivalent (but not
identical) value.
---
 .../FlowSensitive/DataflowEnvironment.h   | 47 +++---
 .../FlowSensitive/DataflowEnvironment.cpp | 43 ++---
 .../TypeErasedDataflowAnalysisTest.cpp| 48 +++
 3 files changed, 104 insertions(+), 34 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index c30bccd06674a4..0a37d9d68e2898 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -97,6 +97,16 @@ class Environment {
   const Value &Val2, const Environment &Env2,
   Value &JoinedVal, Environment &JoinedEnv) {}
 
+/// The result of the `widen` operation.
+struct WidenResult {
+  /// Non-null pointer to a potentially widened version of the widening
+  /// input.
+  Value *V;
+  /// Whether `V` represents a "change" (that is, a different value) with
+  /// respect to the previous value in the sequence.
+  LatticeJoinEffect Effect;
+};
+
 /// This function may widen the current value -- replace it with an
 /// approximation that can reach a fixed point more quickly than iterated
 /// application of the transfer function alone. The previous value is
@@ -104,14 +114,17 @@ class Environment {
 /// serve as a comparison operation, by indicating whether the widened 
value
 /// is equivalent to the previous value.
 ///
-/// Returns either:
-///
-///   `nullptr`, if this value is not of interest to the model, or
-///
-///   `&Prev`, if the widened value is equivalent to `Prev`, or
-///
-///   A non-null value that approximates `Current`. `Prev` is available to
-///   inform the chosen approximation.
+/// Returns one of the folowing:
+/// *  `std::nullopt`, if this value is not of interest to the
+/// model.
+/// *  A `WidenResult` with:
+///*  A non-null `Value *` that points either to `Current` or a widened
+///   version of `Current`. This value must be consistent with
+///   the flow condition of `CurrentEnv`. We particularly caution
+///   against using `Prev`, which is rarely consistent.
+///*  A `LatticeJoinEffect` indicating whether the value should be
+///   considered a new value (`Changed`) or one *equivalent* (if not
+///   necessarily equal) to `Prev` (`Unchanged`).
 ///
 /// `PrevEnv` and `CurrentEnv` can be used to query child values and path
 /// condition implications of `Prev` and `Current`, respectively.
@@ -122,17 +135,19 @@ class Environment {
 ///
 ///  `Prev` and `Current` must be assigned to the same storage location in
 ///  `PrevEnv` and `CurrentEnv`, respectively.
-virtual Value *widen(QualType Type, Value &Prev, const Environment 
&PrevEnv,
- Value &Current, Environment &CurrentEnv) {
+virtual std::optional widen(QualType Type, Value &Prev,
+ const Environment &PrevEnv,
+ Value &Current,
+ Environment &CurrentEnv) {
   // The default implementation reduces to just comparison, since 
comparison
   // is required by the API, even if no widening is performed.
   switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
-case ComparisonResult::Same:
-  return &Prev;
-case ComparisonResult::Different:
-  return &Current;
-case ComparisonResult::Unknown:
-  return nullptr;
+  case ComparisonResult::Unknown:
+return std::nullopt;
+  case ComparisonResult::Same:
+return WidenResult{&Current, LatticeJoinEffect::Unchanged};
+  case ComparisonResult::Different:
+return WidenResult{&Current, LatticeJoinEffect::Changed};
   }
   llvm_unreachable("all cases in switch covered");
 }
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index f729d676dd0de8..8ae51b7cdb444d 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -166,17 +166,20 @@ static Value *joinDistinctValues(QualTyp

[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread Yitzhak Mandelbaum via cfe-commits

https://github.com/ymand updated https://github.com/llvm/llvm-project/pull/87233

>From d8d875271bd47b71701143afb06ea654546e2b7c Mon Sep 17 00:00:00 2001
From: Yitzhak Mandelbaum 
Date: Mon, 1 Apr 2024 12:13:39 +
Subject: [PATCH 1/3] [clang][dataflow] Refactor `widen` API to be explicit
 about change effect.

The previous API relied on pointer equality of inputs and outputs to signal
whether a change occured. This was too subtle and led to bugs in practice. It
was also very limiting: the override could not return an equivalent (but not
identical) value.
---
 .../FlowSensitive/DataflowEnvironment.h   | 47 +++---
 .../FlowSensitive/DataflowEnvironment.cpp | 43 ++---
 .../TypeErasedDataflowAnalysisTest.cpp| 48 +++
 3 files changed, 104 insertions(+), 34 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index c30bccd06674a4..0a37d9d68e2898 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -97,6 +97,16 @@ class Environment {
   const Value &Val2, const Environment &Env2,
   Value &JoinedVal, Environment &JoinedEnv) {}
 
+/// The result of the `widen` operation.
+struct WidenResult {
+  /// Non-null pointer to a potentially widened version of the widening
+  /// input.
+  Value *V;
+  /// Whether `V` represents a "change" (that is, a different value) with
+  /// respect to the previous value in the sequence.
+  LatticeJoinEffect Effect;
+};
+
 /// This function may widen the current value -- replace it with an
 /// approximation that can reach a fixed point more quickly than iterated
 /// application of the transfer function alone. The previous value is
@@ -104,14 +114,17 @@ class Environment {
 /// serve as a comparison operation, by indicating whether the widened 
value
 /// is equivalent to the previous value.
 ///
-/// Returns either:
-///
-///   `nullptr`, if this value is not of interest to the model, or
-///
-///   `&Prev`, if the widened value is equivalent to `Prev`, or
-///
-///   A non-null value that approximates `Current`. `Prev` is available to
-///   inform the chosen approximation.
+/// Returns one of the folowing:
+/// *  `std::nullopt`, if this value is not of interest to the
+/// model.
+/// *  A `WidenResult` with:
+///*  A non-null `Value *` that points either to `Current` or a widened
+///   version of `Current`. This value must be consistent with
+///   the flow condition of `CurrentEnv`. We particularly caution
+///   against using `Prev`, which is rarely consistent.
+///*  A `LatticeJoinEffect` indicating whether the value should be
+///   considered a new value (`Changed`) or one *equivalent* (if not
+///   necessarily equal) to `Prev` (`Unchanged`).
 ///
 /// `PrevEnv` and `CurrentEnv` can be used to query child values and path
 /// condition implications of `Prev` and `Current`, respectively.
@@ -122,17 +135,19 @@ class Environment {
 ///
 ///  `Prev` and `Current` must be assigned to the same storage location in
 ///  `PrevEnv` and `CurrentEnv`, respectively.
-virtual Value *widen(QualType Type, Value &Prev, const Environment 
&PrevEnv,
- Value &Current, Environment &CurrentEnv) {
+virtual std::optional widen(QualType Type, Value &Prev,
+ const Environment &PrevEnv,
+ Value &Current,
+ Environment &CurrentEnv) {
   // The default implementation reduces to just comparison, since 
comparison
   // is required by the API, even if no widening is performed.
   switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
-case ComparisonResult::Same:
-  return &Prev;
-case ComparisonResult::Different:
-  return &Current;
-case ComparisonResult::Unknown:
-  return nullptr;
+  case ComparisonResult::Unknown:
+return std::nullopt;
+  case ComparisonResult::Same:
+return WidenResult{&Current, LatticeJoinEffect::Unchanged};
+  case ComparisonResult::Different:
+return WidenResult{&Current, LatticeJoinEffect::Changed};
   }
   llvm_unreachable("all cases in switch covered");
 }
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index f729d676dd0de8..8ae51b7cdb444d 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -166,17 +166,20 @@ static Value *joinDistinctValues(QualTyp

[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread Yitzhak Mandelbaum via cfe-commits


@@ -975,6 +994,35 @@ TEST_F(WideningTest, 
DistinctValuesWithSamePropertiesAreEquivalent) {
   });
 }
 
+TEST_F(WideningTest, DistinctValuesWithDifferentPropertiesWidenedToTop) {
+  std::string Code = R"(
+void target(bool Cond) {
+  int *Foo;
+  int i = 0;
+  Foo = nullptr;
+  while (Cond) {
+Foo = &i;
+  }
+  (void)0;
+  /*[[p]]*/
+}
+  )";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+
+const auto *FooVal = Env.getValue(*FooDecl);

ymand wrote:

Done

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread Yitzhak Mandelbaum via cfe-commits

ymand wrote:

Martin, I've addressed all of your comments. PTAL.

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


[clang] [clang] Catch missing format attributes (PR #70024)

2024-04-02 Thread Budimir Aranđelović via cfe-commits

https://github.com/budimirarandjelovicsyrmia updated 
https://github.com/llvm/llvm-project/pull/70024

From 1c027637176d9100d3cc0a4f92b4ee227d4afddf Mon Sep 17 00:00:00 2001
From: budimirarandjelovicsyrmia 
Date: Fri, 13 Oct 2023 14:45:15 +0200
Subject: [PATCH] [clang] Catch missing format attributes

---
 clang/docs/ReleaseNotes.rst   |   4 +-
 clang/include/clang/Basic/DiagnosticGroups.td |   1 -
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Sema/Sema.h   |   4 +
 clang/lib/Sema/SemaChecking.cpp   |   4 +-
 clang/lib/Sema/SemaDeclAttr.cpp   | 105 +
 clang/test/Sema/attr-format-missing.c | 223 ++
 clang/test/Sema/attr-format-missing.cpp   | 211 +
 8 files changed, 552 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Sema/attr-format-missing.c
 create mode 100644 clang/test/Sema/attr-format-missing.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9cc2a72f4c864d..1ca055f65f2115 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -65,7 +65,9 @@ Improvements to Clang's diagnostics
 ^^^
 - We now generate a diagnostic for signed integer overflow due to unary minus
   in a non-constant expression context. This fixes
-  `Issue 31643 `_
+  `Issue 31643 `_.
+- We now generate a diagnostic for missing format attributes
+  `Issue 60718 `_.
 
 Non-comprehensive list of changes in this release
 -
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 17fdcffa2d4274..114cbbc2e82b85 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -482,7 +482,6 @@ def MainReturnType : DiagGroup<"main-return-type">;
 def MaxUnsignedZero : DiagGroup<"max-unsigned-zero">;
 def MissingBraces : DiagGroup<"missing-braces">;
 def MissingDeclarations: DiagGroup<"missing-declarations">;
-def : DiagGroup<"missing-format-attribute">;
 def : DiagGroup<"missing-include-dirs">;
 def MissingNoreturn : DiagGroup<"missing-noreturn">;
 def MultiChar : DiagGroup<"multichar">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6d6f474f6dcdab..964166b70c2aee 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -936,6 +936,9 @@ def err_opencl_invalid_param : Error<
 def err_opencl_invalid_return : Error<
   "declaring function return value of type %0 is not allowed %select{; did you 
forget * ?|}1">;
 def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
+def warn_missing_format_attribute : Warning<
+  "diagnostic behavior may be improved by adding the %0 format attribute to 
the declaration of %1">,
+  InGroup>, DefaultIgnore;
 def warn_pragma_options_align_reset_failed : Warning<
   "#pragma options align=reset failed: %0">,
   InGroup;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 741c2503127af7..064506e7096033 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10615,6 +10615,10 @@ class Sema final {
 ChangedStateAtExit
   };
 
+  void DiagnoseMissingFormatAttributes(const FunctionDecl *FDecl,
+   ArrayRef Args,
+   SourceLocation Loc);
+
   void DiagnoseNonDefaultPragmaAlignPack(PragmaAlignPackDiagnoseKind Kind,
  SourceLocation IncludeLoc);
   void DiagnoseUnterminatedPragmaAlignPack();
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4602284309491c..d3ac6cb519c56e 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6014,8 +6014,10 @@ void Sema::checkCall(NamedDecl *FDecl, const 
FunctionProtoType *Proto,
 }
   }
 
-  if (FD)
+  if (FD) {
 diagnoseArgDependentDiagnoseIfAttrs(FD, ThisArg, Args, Loc);
+DiagnoseMissingFormatAttributes(FD, Args, Range.getBegin());
+  }
 }
 
 /// CheckConstructorCall - Check a constructor call for correctness and safety
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1a0bfb3d91bcc8..b30d752a36cd49 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6849,6 +6849,111 @@ static void handleSwiftAsyncAttr(Sema &S, Decl *D, 
const ParsedAttr &AL) {
 checkSwiftAsyncErrorBlock(S, D, ErrorAttr, AsyncAttr);
 }
 
+// This function is called only if function call is not inside template body.
+// TODO: Add call for function calls inside template body.
+// Check if parent function misses for

[clang] [clang] Add __builtin_start_object_lifetime builtin. (PR #82776)

2024-04-02 Thread Haojian Wu via cfe-commits

https://github.com/hokein updated 
https://github.com/llvm/llvm-project/pull/82776

>From 7fcd58b750872221aa754e81e17ab9068e144a44 Mon Sep 17 00:00:00 2001
From: Haojian Wu 
Date: Fri, 23 Feb 2024 10:03:16 +0100
Subject: [PATCH 1/2] [clang] Add __builtin_start_object_lifetime builtin.

This patch implements a clang built `__builtin_start_object_lifetime`,
it has the same semantics as C++23's `std::start_lifetime_as`, but
without the implicit-lifetime type restriction, it can be used for
implementing `std::start_lifetime_as` in the future.

Due to the current clang lowering, the builtin reuses the existing 
`__builtin_launder` implementation:
- it is a no-op for the most part;
- with `-fstrict-vtable-pointers` flag, we update the vtpr assumption correctly
  (mark the load/store vptr with appropriate invariant group intrinsics)
  to prevent incorrect vptr load folding;
- for now, the builtin is non-constant, cannot be executed in constant 
evaluation;

CAVEAT:
- this builtin may cause TBAA miscomplies without the `-fno-strict-alias`
  flag. These TBAA miscompiles are known issues and may need more LLVM
  IR support for the fix, fixing them is orthogonal to the implementaton of the
  builtin.

Context: 
https://discourse.llvm.org/t/extension-for-creating-objects-via-memcpy/76961
---
 clang/include/clang/Basic/Builtins.td |  6 +++
 clang/lib/CodeGen/CGBuiltin.cpp   |  1 +
 clang/lib/Sema/SemaChecking.cpp   |  2 +
 clang/test/CodeGen/builtins.c | 10 
 .../builtin-start-object-life-time.cpp| 49 +++
 clang/test/SemaCXX/builtins.cpp   | 33 -
 6 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenCXX/builtin-start-object-life-time.cpp

diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index f421223ff087de..2c2e0eb58b15a1 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -926,6 +926,12 @@ def Launder : Builtin {
   let Prototype = "void*(void*)";
 }
 
+def StartObjectLifeTime : Builtin {
+  let Spellings = ["__builtin_start_object_lifetime"];
+  let Attributes = [NoThrow, CustomTypeChecking];
+  let Prototype = "void*(void*)";
+}
+
 def IsConstantEvaluated : LangBuiltin<"CXX_LANG"> {
   let Spellings = ["__builtin_is_constant_evaluated"];
   let Attributes = [NoThrow, Constexpr];
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 483f9c26859923..6cdb602f8bb07d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4509,6 +4509,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl 
GD, unsigned BuiltinID,
 
 return RValue::get(nullptr);
   }
+  case Builtin::BI__builtin_start_object_lifetime:
   case Builtin::BI__builtin_launder: {
 const Expr *Arg = E->getArg(0);
 QualType ArgTy = Arg->getType()->getPointeeType();
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 11401b6f56c0ea..356765609f694b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -37,6 +37,7 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/UnresolvedSet.h"
 #include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/IdentifierTable.h"
@@ -2642,6 +2643,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 TheCall->setType(Context.IntTy);
 break;
   }
+  case Builtin::BI__builtin_start_object_lifetime:
   case Builtin::BI__builtin_launder:
 return SemaBuiltinLaunder(*this, TheCall);
   case Builtin::BI__sync_fetch_and_add:
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c
index 407e0857d22311..00c81c23d0ed02 100644
--- a/clang/test/CodeGen/builtins.c
+++ b/clang/test/CodeGen/builtins.c
@@ -143,6 +143,7 @@ int main(void) {
   P(signbit, (1.0));
 
   R(launder, (&N));
+  R(start_object_lifetime, (&N));
 
   return 0;
 }
@@ -511,6 +512,15 @@ void test_builtin_launder(int *p) {
   int *d = __builtin_launder(p);
 }
 
+/// It should be a NOP in C since there are no vtables.
+// CHECK-LABEL: define{{.*}} void @test_builtin_start_object_lifetime
+void test_builtin_start_object_lifetime(int *p) {
+  // CHECK: [[TMP:%.*]] = load ptr,
+  // CHECK-NOT: @llvm.launder
+  // CHECK: store ptr [[TMP]],
+  int *d = __builtin_start_object_lifetime(p);
+}
+
 // __warn_memset_zero_len should be NOP, see 
https://sourceware.org/bugzilla/show_bug.cgi?id=25399
 // CHECK-LABEL: define{{.*}} void @test___warn_memset_zero_len
 void test___warn_memset_zero_len(void) {
diff --git a/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp 
b/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp
new file mode 100644
index 00..58012f52cc0ef5
--- /dev/null
+++ b/clang/test/CodeGenCXX/builtin-start-object-life-time.cpp
@@ -0

[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -805,6 +805,25 @@ class NullPointerAnalysis final
 else
   JoinedVal.setProperty("is_null", JoinedEnv.makeTopBoolValue());
   }
+
+  std::optional widen(QualType Type, Value &Prev,
+   const Environment &PrevEnv, Value &Current,
+   Environment &CurrentEnv) override {

martinboehme wrote:

Wow -- makes sense to add this then!

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -122,17 +135,19 @@ class Environment {
 ///
 ///  `Prev` and `Current` must be assigned to the same storage location in
 ///  `PrevEnv` and `CurrentEnv`, respectively.
-virtual Value *widen(QualType Type, Value &Prev, const Environment 
&PrevEnv,
- Value &Current, Environment &CurrentEnv) {
+virtual std::optional widen(QualType Type, Value &Prev,

martinboehme wrote:

Makes sense, thanks for the explanation.

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -975,6 +989,35 @@ TEST_F(WideningTest, 
DistinctValuesWithSamePropertiesAreEquivalent) {
   });
 }
 
+TEST_F(WideningTest, DistinctValuesWithDifferentPropertiesWidenedToTop) {
+  std::string Code = R"(
+void target(bool Cond) {
+  int *Foo;
+  int i = 0;
+  Foo = nullptr;
+  while (Cond) {
+Foo = &i;
+  }
+  (void)0;
+  /*[[p]]*/
+}
+  )";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+

martinboehme wrote:

```suggestion
```

`getValueForDecl()` asserts that the declaration exists.

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits

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


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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread via cfe-commits


@@ -975,6 +994,35 @@ TEST_F(WideningTest, 
DistinctValuesWithSamePropertiesAreEquivalent) {
   });
 }
 
+TEST_F(WideningTest, DistinctValuesWithDifferentPropertiesWidenedToTop) {
+  std::string Code = R"(
+void target(bool Cond) {
+  int *Foo;
+  int i = 0;
+  Foo = nullptr;
+  while (Cond) {
+Foo = &i;
+  }
+  (void)0;
+  /*[[p]]*/
+}
+  )";
+  runDataflow(
+  Code,
+  [](const llvm::StringMap> &Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
+const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
+
+const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+ASSERT_THAT(FooDecl, NotNull());
+
+const auto *FooVal = Env.getValue(*FooDecl);
+EXPECT_TRUE(areEquivalentValues(*FooVal->getProperty("is_null"),

martinboehme wrote:

Looks good!

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


[clang] [clang]Treat arguments to builtin type traits as template type arguments (PR #87132)

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

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

LGTM, thank you! No need for a release note because the changes are correcting 
an issue introduced in 19.x.

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


[clang] [clang-repl] Add call to 'InitializeAllAsmParsers' (PR #86727)

2024-04-02 Thread Andrew V. Teylu via cfe-commits

https://github.com/aytey updated https://github.com/llvm/llvm-project/pull/86727

>From 480d77eb88df2abc589c4be90ceab200cb3fac98 Mon Sep 17 00:00:00 2001
From: "Andrew V. Teylu" 
Date: Tue, 26 Mar 2024 20:10:24 +
Subject: [PATCH 1/2] [clang-repl] Add call to 'InitializeAllAsmParsers'

Signed-off-by: Andrew V. Teylu 
---
 clang/tools/clang-repl/ClangRepl.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/tools/clang-repl/ClangRepl.cpp 
b/clang/tools/clang-repl/ClangRepl.cpp
index 5bad8145324d06..aecf61b97fc719 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -152,6 +152,7 @@ int main(int argc, const char **argv) {
   llvm::InitializeAllTargets();
   llvm::InitializeAllTargetMCs();
   llvm::InitializeAllAsmPrinters();
+  llvm::InitializeAllAsmParsers();
 
   if (OptHostSupportsJit) {
 auto J = llvm::orc::LLJITBuilder().create();

>From d1e104977e22c4d641459714c4e45acdb87576b1 Mon Sep 17 00:00:00 2001
From: "Andrew V. Teylu" 
Date: Tue, 26 Mar 2024 20:49:53 +
Subject: [PATCH 2/2] [clang-repl] add test for inline asm

Signed-off-by: Andrew V. Teylu 
---
 clang/test/Interpreter/inline-asm.cpp | 17 +
 1 file changed, 17 insertions(+)
 create mode 100644 clang/test/Interpreter/inline-asm.cpp

diff --git a/clang/test/Interpreter/inline-asm.cpp 
b/clang/test/Interpreter/inline-asm.cpp
new file mode 100644
index 00..f94f14df72f80e
--- /dev/null
+++ b/clang/test/Interpreter/inline-asm.cpp
@@ -0,0 +1,17 @@
+// REQUIRES: host-supports-jit, x86_64-linux
+// UNSUPPORTED: system-aix
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: cat %t/inline-asm.txt | clang-repl -Xcc="-I%t"
+
+//--- inline-asm.cpp
+__asm(".globl _ZSt21ios_base_library_initv");
+int x;
+
+//--- inline-asm.txt
+#include "inline-asm.cpp"
+x = 10;
+%quit

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


[clang] [clang-repl] Add call to 'InitializeAllAsmParsers' (PR #86727)

2024-04-02 Thread Andrew V. Teylu via cfe-commits

aytey wrote:

@weliveindetail @vgvassilev @junaire: sorry for pinging you directly, but could 
you take a look at this PR? I see you're all active on other `clang-repl` PRs, 
so thought you might be the best place to start to take a look at this one 🤞 

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


[clang] 7ef602b - Reapply "[clang][nullability] allow _Nonnull etc on nullable class types (#82705)" (#87325)

2024-04-02 Thread via cfe-commits

Author: Sam McCall
Date: 2024-04-02T13:48:45+02:00
New Revision: 7ef602b58c1ccacab20d9d01e24b281458c3facc

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

LOG: Reapply "[clang][nullability] allow _Nonnull etc on nullable class types 
(#82705)" (#87325)

This reverts commit 28760b63bbf9e267713957105a8d17091fb0d20e.

The last commit was missing the new testcase, now fixed.

Added: 
clang/test/SemaObjCXX/Inputs/nullability-consistency-smart.h

Modified: 
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/Features.def
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/Type.cpp
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Sema/SemaAttr.cpp
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaInit.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/SemaType.cpp
clang/test/Sema/nullability.c
clang/test/SemaCXX/nullability.cpp
clang/test/SemaObjCXX/nullability-consistency.mm

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 76eaf0bf11c303..b2faab1f1525b2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -253,6 +253,21 @@ Attribute Changes in Clang
   added a new extension query ``__has_extension(swiftcc)`` corresponding to the
   ``__attribute__((swiftcc))`` attribute.
 
+- The ``_Nullable`` and ``_Nonnull`` family of type attributes can now apply
+  to certain C++ class types, such as smart pointers:
+  ``void useObject(std::unique_ptr _Nonnull obj);``.
+
+  This works for standard library types including ``unique_ptr``, 
``shared_ptr``,
+  and ``function``. See
+  `the attribute reference documentation 
`_
+  for the full list.
+
+- The ``_Nullable`` attribute can be applied to C++ class declarations:
+  ``template  class _Nullable MySmartPointer {};``.
+
+  This allows the ``_Nullable`` and ``_Nonnull`` family of type attributes to
+  apply to this class.
+
 Improvements to Clang's diagnostics
 ---
 - Clang now applies syntax highlighting to the code snippets it

diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 80e607525a0a37..6584460cf5685e 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2178,9 +2178,10 @@ def TypeNonNull : TypeAttr {
   let Documentation = [TypeNonNullDocs];
 }
 
-def TypeNullable : TypeAttr {
+def TypeNullable : DeclOrTypeAttr {
   let Spellings = [CustomKeyword<"_Nullable">];
   let Documentation = [TypeNullableDocs];
+//  let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
 }
 
 def TypeNullableResult : TypeAttr {

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 3ea4d676b4f89d..0ca4ea377fc36a 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -4151,6 +4151,20 @@ non-underscored keywords. For example:
   @property (assign, nullable) NSView *superview;
   @property (readonly, nonnull) NSArray *subviews;
 @end
+
+As well as built-in pointer types, the nullability attributes can be attached
+to C++ classes marked with the ``_Nullable`` attribute.
+
+The following C++ standard library types are considered nullable:
+``unique_ptr``, ``shared_ptr``, ``auto_ptr``, ``exception_ptr``, ``function``,
+``move_only_function`` and ``coroutine_handle``.
+
+Types should be marked nullable only where the type itself leaves nullability
+ambiguous. For example, ``std::optional`` is not marked ``_Nullable``, because
+``optional _Nullable`` is redundant and ``optional _Nonnull`` is
+not a useful type. ``std::weak_ptr`` is not nullable, because its nullability
+can change with no visible modification, so static annotation is unlikely to be
+unhelpful.
   }];
 }
 
@@ -4185,6 +4199,17 @@ The ``_Nullable`` nullability qualifier indicates that a 
value of the
 int fetch_or_zero(int * _Nullable ptr);
 
 a caller of ``fetch_or_zero`` can provide null.
+
+The ``_Nullable`` attribute on classes indicates that the given class can
+represent null values, and so the ``_Nullable``, ``_Nonnull`` etc qualifiers
+make sense for this type. For example:
+
+  .. code-block:: c
+
+class _Nullable ArenaPointer { ... };
+
+ArenaPointer _Nonnull x = ...;
+ArenaPointer _Nullable y = nullptr;
   }];
 }
 

diff  --git a/clang/include/clang/Basic/Features.def 
b/clang/include/clang/Basic/Features.de

[clang] Reapply "[clang][nullability] allow _Nonnull etc on nullable class types (#82705)" (PR #87325)

2024-04-02 Thread Sam McCall via cfe-commits

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


[clang] [clang] Fix crash when inheriting from a cv-qualified type (PR #70594)

2024-04-02 Thread Vlad Serebrennikov via cfe-commits

Endilll wrote:

You might want to include a test from 
https://github.com/llvm/llvm-project/issues/85256#issuecomment-2031815104

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


[clang] [C++20][Coroutines] Lambda-coroutine with operator new in promise_type (PR #84193)

2024-04-02 Thread Andreas Fertig via cfe-commits

andreasfertig wrote:

Hello @ChuanqiXu9,

> Hi Andreas, thanks for looking into this. I am still confused about whether 
> or not your new branch can fix the crash or not.

It's my pleasure! The new branch doesn't fix the crash. If I understand why it 
is crashing, this branch is a better change compared to the previous merged 
code.


> For the question about the crash itself, I don't have any insight though, I 
> feel like this is a defect in the code generator. I didn't understand why 
> mark a variable as referenced or not by the frontend may affect the code 
> generation.

I'm also struggling with that. As far as I could see, the coroutine part does 
nothing special for classes. I suspect that some other coroutine-unrelated part 
does something with the lambda. I also checked whether `I` holds a 
`getKnownLValue`, but that's not the case either.

Do you know who I could ping to get assistance with the CodeGen part? 



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


[clang] [clang] Add test for CWG1606 (PR #87274)

2024-04-02 Thread Yuri Istomin via cfe-commits

https://github.com/NekoCdr updated 
https://github.com/llvm/llvm-project/pull/87274

>From 1dfb9414a28f99024a8abe36b0b10a4d91eae573 Mon Sep 17 00:00:00 2001
From: Yuri Istomin 
Date: Mon, 1 Apr 2024 22:02:42 +0300
Subject: [PATCH 1/3] [clang] Add test for CWG1606

---
 clang/test/CXX/drs/dr16xx.cpp | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/clang/test/CXX/drs/dr16xx.cpp b/clang/test/CXX/drs/dr16xx.cpp
index 766c90d3bc7bda..cf05cc2291e6ff 100644
--- a/clang/test/CXX/drs/dr16xx.cpp
+++ b/clang/test/CXX/drs/dr16xx.cpp
@@ -35,6 +35,17 @@ void g() {
 }
 } // namespace dr1601
 
+namespace dr1606 { // dr1606: 3.1
+#if __cplusplus >= 201103L
+  std::size_t test() {
+int i = 1;
+int j = 1;
+auto f = [=]{ return i + j;};
+return sizeof(f);
+  }
+#endif
+} // namespace dr1606
+
 namespace dr1611 { // dr1611: dup 1658
   struct A { A(int); };
   struct B : virtual A { virtual void f() = 0; };

>From fdffb31e1f960d51b840398950e3758f7c5a284f Mon Sep 17 00:00:00 2001
From: Yuri Istomin 
Date: Mon, 1 Apr 2024 22:03:12 +0300
Subject: [PATCH 2/3] Update DR status page

---
 clang/www/cxx_dr_status.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index c20a5d021e9d95..5e1e03dec1d484 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -9444,7 +9444,7 @@ C++ defect report implementation 
status
 https://cplusplus.github.io/CWG/issues/1606.html";>1606
 NAD
 sizeof closure class
-Unknown
+Clang 3.1
   
   
 https://cplusplus.github.io/CWG/issues/1607.html";>1607

>From 48a042bf084f92e8da935326f8cf22b5c6e72a1c Mon Sep 17 00:00:00 2001
From: Yuri Istomin 
Date: Tue, 2 Apr 2024 14:58:57 +0300
Subject: [PATCH 3/3] Fix codestyle

---
 clang/test/CXX/drs/dr16xx.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CXX/drs/dr16xx.cpp b/clang/test/CXX/drs/dr16xx.cpp
index cf05cc2291e6ff..f4d6c04fb8e073 100644
--- a/clang/test/CXX/drs/dr16xx.cpp
+++ b/clang/test/CXX/drs/dr16xx.cpp
@@ -40,7 +40,7 @@ namespace dr1606 { // dr1606: 3.1
   std::size_t test() {
 int i = 1;
 int j = 1;
-auto f = [=]{ return i + j;};
+auto f = [=]{ return i + j; };
 return sizeof(f);
   }
 #endif

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


[clang] [llvm] [HLSL][DXIL][SPIRV] Implementation of an abstraction for intrinsic selection of HLSL backends (PR #87171)

2024-04-02 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,44 @@
+
+//===- CGHLSLUtils.h - Utility functions for HLSL CodeGen ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This File Provides utility function for HLSL code generation.
+// It is used to abstract away implementation details of backends.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_CGHLSLUTILS_H
+#define LLVM_CLANG_LIB_CODEGEN_CGHLSLUTILS_H
+
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+
+// Define the function generator macro
+#define GENERATE_HLSL_INTRINSIC_FUNCTION(name) 
\
+  static llvm::Intrinsic::ID get_hlsl_##name##_intrinsic(  
\
+  const llvm::Triple::ArchType Arch) { 
\
+switch (Arch) {
\
+case llvm::Triple::dxil:   
\
+  return llvm::Intrinsic::dx_##name;   
\
+case llvm::Triple::spirv:  
\
+  return llvm::Intrinsic::spv_##name;  
\
+default:   
\
+  llvm_unreachable("Input semantic not supported by target");  
\

Keenuts wrote:

Shall the error be `"Intrinsic " #name " not supported by target architecture"`?

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


[clang] [llvm] [HLSL][DXIL][SPIRV] Implementation of an abstraction for intrinsic selection of HLSL backends (PR #87171)

2024-04-02 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,95 @@
+; RUN: llc -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+; Note: The validator is wrong it wants the return to be a bool vector when it 
is bool scalar return

Keenuts wrote:

AFAIK the validator is not wrong, it complains for 2 reasons:

`OpAll` cannot be used with a single boolean as input: It **must** be a vector 
of boolean.
And SPIR-V doesn't allow vector of 1 value.
Hence, `all(my_bool)` shall be translated to `return my_bool`.

Then, for int/long intrinsics:
HLSL only checks if the value (any type) is non-zero for all vector items.
for SPIR-V, `OpAll` only works for boolean vectors. This means the translation 
is not that straightforward.

What is being done in DXC is the following:

```
%const = OpConstantComposite %v2int %int_0 %int_0
%tmp = OpINotEqual %v2bool %variable %const
%res = OpAll %bool %tmp
```

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


[clang] [llvm] [HLSL][DXIL][SPIRV] Implementation of an abstraction for intrinsic selection of HLSL backends (PR #87171)

2024-04-02 Thread Nathan Gauër via cfe-commits


@@ -100,6 +100,118 @@ double3 abs(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
 double4 abs(double4);
 
+//===--===//
+// all builtins
+//===--===//
+
+/// \fn bool all(T x)
+/// \brief Returns True if all components of the \a x parameter are non-zero;
+/// otherwise, false. \param x The input value.
+
+#ifdef __HLSL_ENABLE_16_BIT
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int16_t);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int16_t2);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int16_t3);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int16_t4);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint16_t);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint16_t2);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint16_t3);
+_HLSL_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint16_t4);
+#endif
+
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(half);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(half2);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(half3);
+_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(half4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(bool);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(bool2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(bool3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(bool4);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(uint4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(float);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(float2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(float3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(float4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int64_t);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int64_t2);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int64_t3);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all)
+bool all(int64_t4);

Keenuts wrote:

Not sure if that's considered cleaner, but could those repetition be avoid with 
something like:


```cpp
#define _HLSL_ALIAS_BUILTIN_FOR_VECTOR(BuiltIn, BaseType) \
BuiltIn(BaseType);  \
BuiltIn(BaseType ## 2); \
BuiltIn(BaseType ## 3); \
BuiltIn(BaseType ## 4)
```

Which would be used like so:

```cpp
#define _DEFINE_BUILTIN_HLSL_ELEMENTWISE_ALL(Type)  \
_HLSL_AVAILABILITY(shadermodel, 6.2)\
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_all) \
bool all(Type)
_HLSL_ALIAS_BUILTIN_FOR_VECTOR(_DEFINE_BUILTIN_HLSL_ELEMENTWISE_ALL, int);
_HLSL_ALIAS_BUILTIN_FOR_VECTOR(_DEFINE_BUILTIN_HLSL_ELEMENTWISE_ALL, uint);
_HLSL_ALIAS_BUILTIN_FOR_VECTOR(_DEFINE_BUILTIN_HLSL_ELEMENTWISE_ALL, float);
_HLSL_ALIAS_BUILTIN_FOR_VECTOR(_DEFINE_BUILTIN_HLSL_ELEMENTWISE_ALL, double);


#define _DEFINE_BUILTIN_HLSL_ELEMENTWISE_ANY(Type)  \
_HLSL_AVAILABILITY(shadermodel, 6.2)\
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_any) \
bool all(Type)
_HLSL_ALIAS_BUILTIN_FOR_VECTOR(_DEFINE_BUILTIN_HLSL_ELEMENTWISE_ANY, int);
_HLSL_ALIAS_BUILTIN_FOR_VECTOR(_DEFINE_BUILTIN_HLSL_ELEMENTWISE_ANY, uint);
_HLSL_ALIAS_BUILTIN_FOR_VECTOR(_DEFINE_BUILTIN_HLSL_ELEMENTWISE_ANY, float);
_HLSL_ALIAS_BUILTIN_FOR_VECTOR(_DEFINE_BUILTIN_HLSL_ELEMENTWISE_ANY, double);
```

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


[clang] [llvm] [HLSL][DXIL][SPIRV] Implementation of an abstraction for intrinsic selection of HLSL backends (PR #87171)

2024-04-02 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,44 @@
+
+//===- CGHLSLUtils.h - Utility functions for HLSL CodeGen ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This File Provides utility function for HLSL code generation.

Keenuts wrote:

nit:
```suggestion
// This file provides utility functions for HLSL code generation.
```

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


[clang] [llvm] [HLSL][DXIL][SPIRV] Implementation of an abstraction for intrinsic selection of HLSL backends (PR #87171)

2024-04-02 Thread Nathan Gauër via cfe-commits


@@ -0,0 +1,44 @@
+
+//===- CGHLSLUtils.h - Utility functions for HLSL CodeGen ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This File Provides utility function for HLSL code generation.
+// It is used to abstract away implementation details of backends.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_CGHLSLUTILS_H
+#define LLVM_CLANG_LIB_CODEGEN_CGHLSLUTILS_H
+
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicsDirectX.h"
+#include "llvm/IR/IntrinsicsSPIRV.h"
+
+// Define the function generator macro
+#define GENERATE_HLSL_INTRINSIC_FUNCTION(name) 
\
+  static llvm::Intrinsic::ID get_hlsl_##name##_intrinsic(  
\
+  const llvm::Triple::ArchType Arch) { 
\
+switch (Arch) {
\
+case llvm::Triple::dxil:   
\
+  return llvm::Intrinsic::dx_##name;   
\
+case llvm::Triple::spirv:  
\
+  return llvm::Intrinsic::spv_##name;  
\
+default:   
\
+  llvm_unreachable("Input semantic not supported by target");  
\
+}  
\
+  }
+
+class CGHLSLUtils {
+public:
+  GENERATE_HLSL_INTRINSIC_FUNCTION(all)

Keenuts wrote:

Why are those functions in a class and not a namespace? Does the class provides 
something a namespace wouldn't?

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


[clang] [clang][ASTImporter] fix variable inline of CXX17 (PR #87314)

2024-04-02 Thread via cfe-commits

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


[clang] [clang][ASTImporter] fix variable inline of CXX17 (PR #87314)

2024-04-02 Thread via cfe-commits


@@ -5317,6 +5317,34 @@ TEST_P(ASTImporterOptionSpecificTestBase,
   EXPECT_FALSE(ToX);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, VarTemplateDeclInlineWithCXX17) {
+  Decl *FromTU = getTuDecl(
+  R"(
+  struct S {
+template  static constexpr bool X = true;
+  };
+  )",
+  Lang_CXX17, "input1.cc");
+  Decl *FromTU2 = getTuDecl(
+  R"(
+  struct S {
+template  static constexpr bool X = true;
+template  void get() { X; }
+  };
+  template  T qvariant_cast(const S &v) { return v.get; }

NagyDonat wrote:

```suggestion
  template  U qvariant_cast(const S &v) { return v.get; }
```
At first I thought that the template argument `typename T` of this definition 
is intended to correspond to the same type as the `typename T` in the 
definition of `get`, while it seems to be a different type, and if this is 
true, then it'd be better to use a different name. (By the way, is it 
intentional that you return `v.get` without calling it?)

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


[clang] [clang][ASTImporter] fix variable inline of CXX17 (PR #87314)

2024-04-02 Thread via cfe-commits

https://github.com/NagyDonat commented:

Looks good, but I'm not familiar enough with these details of the standard to 
provide a definite review. 

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


[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread Yitzhak Mandelbaum via cfe-commits

https://github.com/ymand updated https://github.com/llvm/llvm-project/pull/87233

>From d8d875271bd47b71701143afb06ea654546e2b7c Mon Sep 17 00:00:00 2001
From: Yitzhak Mandelbaum 
Date: Mon, 1 Apr 2024 12:13:39 +
Subject: [PATCH 1/4] [clang][dataflow] Refactor `widen` API to be explicit
 about change effect.

The previous API relied on pointer equality of inputs and outputs to signal
whether a change occured. This was too subtle and led to bugs in practice. It
was also very limiting: the override could not return an equivalent (but not
identical) value.
---
 .../FlowSensitive/DataflowEnvironment.h   | 47 +++---
 .../FlowSensitive/DataflowEnvironment.cpp | 43 ++---
 .../TypeErasedDataflowAnalysisTest.cpp| 48 +++
 3 files changed, 104 insertions(+), 34 deletions(-)

diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index c30bccd06674a4..0a37d9d68e2898 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -97,6 +97,16 @@ class Environment {
   const Value &Val2, const Environment &Env2,
   Value &JoinedVal, Environment &JoinedEnv) {}
 
+/// The result of the `widen` operation.
+struct WidenResult {
+  /// Non-null pointer to a potentially widened version of the widening
+  /// input.
+  Value *V;
+  /// Whether `V` represents a "change" (that is, a different value) with
+  /// respect to the previous value in the sequence.
+  LatticeJoinEffect Effect;
+};
+
 /// This function may widen the current value -- replace it with an
 /// approximation that can reach a fixed point more quickly than iterated
 /// application of the transfer function alone. The previous value is
@@ -104,14 +114,17 @@ class Environment {
 /// serve as a comparison operation, by indicating whether the widened 
value
 /// is equivalent to the previous value.
 ///
-/// Returns either:
-///
-///   `nullptr`, if this value is not of interest to the model, or
-///
-///   `&Prev`, if the widened value is equivalent to `Prev`, or
-///
-///   A non-null value that approximates `Current`. `Prev` is available to
-///   inform the chosen approximation.
+/// Returns one of the folowing:
+/// *  `std::nullopt`, if this value is not of interest to the
+/// model.
+/// *  A `WidenResult` with:
+///*  A non-null `Value *` that points either to `Current` or a widened
+///   version of `Current`. This value must be consistent with
+///   the flow condition of `CurrentEnv`. We particularly caution
+///   against using `Prev`, which is rarely consistent.
+///*  A `LatticeJoinEffect` indicating whether the value should be
+///   considered a new value (`Changed`) or one *equivalent* (if not
+///   necessarily equal) to `Prev` (`Unchanged`).
 ///
 /// `PrevEnv` and `CurrentEnv` can be used to query child values and path
 /// condition implications of `Prev` and `Current`, respectively.
@@ -122,17 +135,19 @@ class Environment {
 ///
 ///  `Prev` and `Current` must be assigned to the same storage location in
 ///  `PrevEnv` and `CurrentEnv`, respectively.
-virtual Value *widen(QualType Type, Value &Prev, const Environment 
&PrevEnv,
- Value &Current, Environment &CurrentEnv) {
+virtual std::optional widen(QualType Type, Value &Prev,
+ const Environment &PrevEnv,
+ Value &Current,
+ Environment &CurrentEnv) {
   // The default implementation reduces to just comparison, since 
comparison
   // is required by the API, even if no widening is performed.
   switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
-case ComparisonResult::Same:
-  return &Prev;
-case ComparisonResult::Different:
-  return &Current;
-case ComparisonResult::Unknown:
-  return nullptr;
+  case ComparisonResult::Unknown:
+return std::nullopt;
+  case ComparisonResult::Same:
+return WidenResult{&Current, LatticeJoinEffect::Unchanged};
+  case ComparisonResult::Different:
+return WidenResult{&Current, LatticeJoinEffect::Changed};
   }
   llvm_unreachable("all cases in switch covered");
 }
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index f729d676dd0de8..8ae51b7cdb444d 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -166,17 +166,20 @@ static Value *joinDistinctValues(QualTyp

[clang] [clang][dataflow] Refactor `widen` API to be explicit about change effect. (PR #87233)

2024-04-02 Thread Yitzhak Mandelbaum via cfe-commits

ymand wrote:

I also fixed up the other tests to use `getValue/LocForDecl` to be consistent.

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


[clang] [Headers] Don't declare unreachable() from stddef.h in C++ (PR #86748)

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

AaronBallman wrote:

> > FWIW, I did verify that it's very unlikely the changes in this PR will 
> > break existing code: 
> > https://sourcegraph.com/search?q=context:global+__need_unreachable+-file:.*clang.*&patternType=keyword&sm=0,
> >  so that's a good thing.
> > > I do wonder if we could have the broader builtin headers discussion 
> > > independent of this patch? Is everyone happy with this patch? We can keep 
> > > talking about the builtin headers in here independent of merging right?
> > 
> > 
> > I guess I don't see these as independent topics; if we decide that C++ mode 
> > should not have observable differences in C headers, then the changes here 
> > are incorrect. I think we should have this discussion in a broader context 
> > (like Discourse) before moving forward with these changes.
> > Also, I'd still like an explanation for [this 
> > question](https://github.com/llvm/llvm-project/pull/86748#issuecomment-2023145043):
> > > I don't understand why this is making into C++ builds at all:
> > 
> > 
> > because it may turn out we don't need these changes in the first place 
> > because the issue is elsewhere.
> 
> Right now I just noticed that in a C++ test I was writing that stddef.h alone 
> doesn't give me unreachable, but __needs_unreachable does. And that's 
> probably wrong because unreachable belongs to  in C++ and _not_ 
> stddef.h. The C++ standard has some frustrating divergence with the C 
> standard as to what the c stdlib headers declare...

I don't yet agree that it's wrong -- you define the macro saying you want 
`unreachable` from `stddef.h`, so you get `unreachable` from `stddef.h`. 
Morally, it's very similar to:
```
#define unreachable "I am doing something which causes myself pain"
#include 
```

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


[clang] [X86_32] Teach X86_32 va_arg to ignore empty structs. (PR #86075)

2024-04-02 Thread Longsheng Mou via cfe-commits

https://github.com/CoTinker updated 
https://github.com/llvm/llvm-project/pull/86075

>From 85d829dcef3484892d6db8f6a0329cb9bc34c349 Mon Sep 17 00:00:00 2001
From: Longsheng Mou 
Date: Thu, 21 Mar 2024 11:23:56 +0800
Subject: [PATCH] [X86_32] Teach X86_32 va_arg to ignore empty structs.

Empty structs are ignored for parameter passing purposes, but va_arg was
incrementing the pointer anyway for that the size of empty struct in c++
is 1 byte, which could lead to va_list getting out of sync.
---
 clang/lib/CodeGen/Targets/X86.cpp  |  6 ++
 clang/test/CodeGenCXX/x86_32-vaarg.cpp | 21 +
 2 files changed, 27 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/x86_32-vaarg.cpp

diff --git a/clang/lib/CodeGen/Targets/X86.cpp 
b/clang/lib/CodeGen/Targets/X86.cpp
index 1146a851a7715d..c831777699f627 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -1069,6 +1069,12 @@ Address X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF,
 
   auto TypeInfo = getContext().getTypeInfoInChars(Ty);
 
+  CCState State(*const_cast(CGF.CurFnInfo));
+  ABIArgInfo AI = classifyArgumentType(Ty, State, /*ArgIndex*/ 0);
+  // Empty records are ignored for parameter passing purposes.
+  if (AI.isIgnore())
+return CGF.CreateMemTemp(Ty);
+
   // x86-32 changes the alignment of certain arguments on the stack.
   //
   // Just messing with TypeInfo like this works because we never pass
diff --git a/clang/test/CodeGenCXX/x86_32-vaarg.cpp 
b/clang/test/CodeGenCXX/x86_32-vaarg.cpp
new file mode 100644
index 00..dcc2f7f96a40f1
--- /dev/null
+++ b/clang/test/CodeGenCXX/x86_32-vaarg.cpp
@@ -0,0 +1,21 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple i386-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+typedef struct {} empty;
+
+// CHECK-LABEL: @_Z17empty_record_testiz(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:[[RESULT_PTR:%.*]] = alloca ptr, align 4
+// CHECK-NEXT:[[Z_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:[[LIST:%.*]] = alloca ptr, align 4
+// CHECK-NEXT:[[TMP:%.*]] = alloca [[STRUCT_EMPTY:%.*]], align 1
+// CHECK-NEXT:store ptr [[AGG_RESULT:%.*]], ptr [[RESULT_PTR]], align 4
+// CHECK-NEXT:store i32 [[Z:%.*]], ptr [[Z_ADDR]], align 4
+// CHECK-NEXT:call void @llvm.va_start.p0(ptr [[LIST]])
+// CHECK-NEXT:ret void
+//
+empty empty_record_test(int z, ...) {
+  __builtin_va_list list;
+  __builtin_va_start(list, z);
+  return __builtin_va_arg(list, empty);
+}

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


[clang] [clang-tools-extra] [Clang][Sema] Fix explicit specializations of member function templates with a deduced return type (PR #86817)

2024-04-02 Thread Krystian Stasiowski via cfe-commits

https://github.com/sdkrystian updated 
https://github.com/llvm/llvm-project/pull/86817

>From e84e4b6fedb5a643082cd38d0e10d910b299f73f Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski 
Date: Wed, 27 Mar 2024 11:23:19 -0400
Subject: [PATCH] [Clang][Sema] Fix explicit specializations of member function
 templates with a deduced return type

---
 .../clang-tidy/infrastructure/diagnostic.cpp  |  4 +-
 clang/docs/ReleaseNotes.rst   |  2 +
 clang/lib/Sema/SemaDecl.cpp   | 46 ---
 .../SemaCXX/deduced-return-type-cxx14.cpp | 18 
 4 files changed, 50 insertions(+), 20 deletions(-)

diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp 
b/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp
index d0efc5ca763753..57d930b26e64c0 100644
--- a/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp
+++ b/clang-tools-extra/test/clang-tidy/infrastructure/diagnostic.cpp
@@ -25,7 +25,7 @@
 // RUN: not clang-tidy -checks='-*,modernize-use-override' 
%T/diagnostics/input.cpp -- -DCOMPILATION_ERROR 2>&1 | FileCheck 
-check-prefix=CHECK6 -implicit-check-not='{{warning:|error:}}' %s
 // RUN: clang-tidy 
-checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- 
-DMACRO_FROM_COMMAND_LINE -std=c++20 | FileCheck -check-prefix=CHECK4 
-implicit-check-not='{{warning:|error:}}' %s
 // RUN: clang-tidy 
-checks='-*,modernize-use-override,clang-diagnostic-macro-redefined,clang-diagnostic-literal-conversion'
 %s -- -DMACRO_FROM_COMMAND_LINE -std=c++20 -Wno-macro-redefined | FileCheck 
--check-prefix=CHECK7 -implicit-check-not='{{warning:|error:}}' %s
-// RUN: not clang-tidy -checks='-*,modernize-use-override' %s -- -std=c++20 
-DPR64602 | FileCheck -check-prefix=CHECK8 
-implicit-check-not='{{warning:|error:}}' %s
+// RUN: clang-tidy -checks='-*,modernize-use-override' %s -- -std=c++20 
-DPR64602
 
 // CHECK1: error: no input files [clang-diagnostic-error]
 // CHECK1: error: no such file or directory: '{{.*}}nonexistent.cpp' 
[clang-diagnostic-error]
@@ -68,6 +68,4 @@ auto S<>::foo(auto)
 {
 return 1;
 }
-// CHECK8: error: conflicting types for 'foo' [clang-diagnostic-error]
-// CHECK8: note: previous declaration is here
 #endif
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b2faab1f1525b2..3a84ff16a1e4d4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -483,6 +483,8 @@ Bug Fixes to C++ Support
   following the first `::` were ignored).
 - Fix an out-of-bounds crash when checking the validity of template partial 
specializations. (part of #GH86757).
 - Fix an issue caused by not handling invalid cases when substituting into the 
parameter mapping of a constraint. Fixes (#GH86757).
+- Fixed a bug that prevented member function templates of class templates 
declared with a deduced return type
+  from being explicitly specialized for a given implicit instantiation of the 
class template.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 6ff85c0c5c29da..5c1152896559b5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10124,23 +10124,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, 
DeclContext *DC,
 Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual);
 }
 
-if (getLangOpts().CPlusPlus14 &&
-(NewFD->isDependentContext() ||
- (isFriend && CurContext->isDependentContext())) &&
-NewFD->getReturnType()->isUndeducedType()) {
-  // If the function template is referenced directly (for instance, as a
-  // member of the current instantiation), pretend it has a dependent type.
-  // This is not really justified by the standard, but is the only sane
-  // thing to do.
-  // FIXME: For a friend function, we have not marked the function as being
-  // a friend yet, so 'isDependentContext' on the FD doesn't work.
-  const FunctionProtoType *FPT =
-  NewFD->getType()->castAs();
-  QualType Result = SubstAutoTypeDependent(FPT->getReturnType());
-  NewFD->setType(Context.getFunctionType(Result, FPT->getParamTypes(),
- FPT->getExtProtoInfo()));
-}
-
 // C++ [dcl.fct.spec]p3:
 //  The inline specifier shall not appear on a block scope function
 //  declaration.
@@ -12112,6 +12095,35 @@ bool Sema::CheckFunctionDeclaration(Scope *S, 
FunctionDecl *NewFD,
 
   CheckConstPureAttributesUsage(*this, NewFD);
 
+  // C++ [dcl.spec.auto.general]p12:
+  //   Return type deduction for a templated function with a placeholder in its
+  //   declared type occurs when the definition is instantiated even if the
+  //   function body contains a return statement with a non-type-dependent
+  //   operand.
+  //
+  // C++ [temp.dep.expr]p3:
+  //   An id-expression is type-dependent if it is a template-id that is not a
+

[clang-tools-extra] Support renaming designated initializers (PR #86976)

2024-04-02 Thread Edwin Vane via cfe-commits

https://github.com/revane updated 
https://github.com/llvm/llvm-project/pull/86976

>From f8604d450fa3852d5c684bc8ada228a07ce6ccf5 Mon Sep 17 00:00:00 2001
From: Edwin Vane 
Date: Thu, 28 Mar 2024 09:24:34 -0400
Subject: [PATCH] Support renaming designated initializers

Until now, they were just ignored by RenamerClangTidyCheck.
---
 .../clang-tidy/utils/RenamerClangTidyCheck.cpp | 18 ++
 clang-tools-extra/docs/ReleaseNotes.rst|  3 ++-
 .../checkers/readability/identifier-naming.cpp | 10 ++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp 
b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index da1433aa2d05d4..1edab9504b0ec0 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -367,6 +367,24 @@ class RenamerClangTidyVisitor
 return true;
   }
 
+  bool VisitDesignatedInitExpr(DesignatedInitExpr *Expr) {
+for (const auto &Designator : Expr->designators()) {
+  if (!Designator.isFieldDesignator())
+continue;
+  FieldDecl *FD = Designator.getFieldDecl();
+  if (!FD)
+continue;
+  IdentifierInfo *II = FD->getIdentifier();
+  if (!II)
+continue;
+  SourceRange FixLocation{Designator.getFieldLoc(),
+  Designator.getFieldLoc()};
+  Check->addUsage(FD, FixLocation, SM);
+}
+
+return true;
+  }
+
 private:
   RenamerClangTidyCheck *Check;
   const SourceManager *SM;
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 309b844615a121..e076281bd5fafe 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -254,7 +254,8 @@ Changes in existing checks
 - Improved :doc:`readability-identifier-naming
   ` check in 
`GetConfigPerFile`
   mode by resolving symbolic links to header files. Fixed handling of Hungarian
-  Prefix when configured to `LowerCase`.
+  Prefix when configured to `LowerCase`. Added support for renaming designated
+  initializers.
 
 - Improved :doc:`readability-implicit-bool-conversion
   ` check to provide
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp
index d2e89a7c9855c9..57ef4aae5ddb78 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/identifier-naming.cpp
@@ -766,3 +766,13 @@ STATIC_MACRO void someFunc(MyFunPtr, const MyFunPtr) {}
 // CHECK-FIXES: {{^}}STATIC_MACRO void someFunc(my_fun_ptr_t, const 
my_fun_ptr_t) {}
 #undef STATIC_MACRO
 }
+
+struct Some_struct {
+  int SomeMember;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: invalid case style for public 
member 'SomeMember' [readability-identifier-naming]
+// CHECK-FIXES: {{^}}  int some_member;
+};
+Some_struct g_s1{ .SomeMember = 1 };
+// CHECK-FIXES: {{^}}Some_struct g_s1{ .some_member = 1 };
+Some_struct g_s2{.SomeMember=1};
+// CHECK-FIXES: {{^}}Some_struct g_s2{.some_member=1};

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


[clang-tools-extra] Support renaming designated initializers (PR #86976)

2024-04-02 Thread Edwin Vane via cfe-commits


@@ -367,6 +367,25 @@ class RenamerClangTidyVisitor
 return true;
   }
 
+  bool VisitDesignatedInitExpr(DesignatedInitExpr *Expr) {
+for (const auto &Designator : Expr->designators()) {
+  if (!Designator.isFieldDesignator())
+continue;
+  auto *FieldDecl = Designator.getFieldDecl();
+  if (!FieldDecl)
+continue;
+  auto *II = FieldDecl->getIdentifier();
+  if (!II)
+continue;
+  SourceRange FixLocation{
+  Designator.getFieldLoc(),
+  Designator.getFieldLoc().getLocWithOffset(II->getLength())};

revane wrote:

You're right. Good to know!

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


[clang] [clang] Fix crash when inheriting from a cv-qualified type (PR #70594)

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

https://github.com/Rajveer100 updated 
https://github.com/llvm/llvm-project/pull/70594

>From f2a9a4137d39dd9f3896c64f41d5700774ec9204 Mon Sep 17 00:00:00 2001
From: Rajveer 
Date: Sun, 29 Oct 2023 18:37:17 +0530
Subject: [PATCH] [clang] Fix a crash in debug mode

Resolves Issue #35603

This bug was caused due to the assertions being too strict,
loosened by stripping qualifiers from the base class but not
from the type of the initializer.

Added Release Notes for the same.
---
 clang/docs/ReleaseNotes.rst|  3 +++
 clang/lib/AST/ExprConstant.cpp |  2 +-
 clang/test/Sema/GH70594.cpp| 28 
 3 files changed, 32 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Sema/GH70594.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 93cc5291e2391fb..07aad91e3e2b322 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -390,6 +390,9 @@ Bug Fixes to C++ Support
 - 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. (#GH64808)
 
+- Fix crash when inheriting from a cv-qualified type. Fixes:
+  (`#35603 `_)
+
 Bug Fixes to AST Handling
 ^
 - Clang now properly preserves ``FoundDecls`` within a ``ConceptReference``. 
(#GH82628)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 7137efb7876de2b..753bbcc94db4f44 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6453,7 +6453,7 @@ static bool HandleConstructorCall(const Expr *E, const 
LValue &This,
   // Non-virtual base classes are initialized in the order in the class
   // definition. We have already checked for virtual base classes.
   assert(!BaseIt->isVirtual() && "virtual base for literal type");
-  assert(Info.Ctx.hasSameType(BaseIt->getType(), BaseType) &&
+  assert(Info.Ctx.hasSameUnqualifiedType(BaseIt->getType(), BaseType) &&
  "base class initializers not in expected order");
   ++BaseIt;
 #endif
diff --git a/clang/test/Sema/GH70594.cpp b/clang/test/Sema/GH70594.cpp
new file mode 100644
index 000..ce98e9b12b5cba3
--- /dev/null
+++ b/clang/test/Sema/GH70594.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++23 %s -verify
+
+// expected-no-diagnostics
+
+struct A {};
+using CA = const A;
+
+struct S1 : CA {
+  constexpr S1() : CA() {}
+};
+
+struct S2 : A {
+  constexpr S2() : CA() {}
+};
+
+struct S3 : CA {
+  constexpr S3() : A() {}
+};
+
+struct Int {};
+
+template 
+struct __tuple_leaf : _Hp {
+  constexpr __tuple_leaf() : _Hp() {}
+};
+
+constexpr __tuple_leaf t;

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


  1   2   3   >