[PATCH] D122110: [Clang] Set -mlinker-version explicitly in the lto test

2022-03-20 Thread Petr Hosek via Phabricator via cfe-commits
phosek added a comment.

In D122110#3395336 , @int3 wrote:

> Would it make sense to have clang pass `-object_path_lto` whenever it's 
> invoking LLD?

It already does, see 
https://github.com/llvm/llvm-project/blob/afc2f024462951d6e74c5e733f4b4666e21d3309/clang/lib/Driver/ToolChains/Darwin.cpp#L232,
 but in this particular case the test is explicitly requesting the platform 
linker by passing `-fuse-ld=`.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122110

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


[PATCH] D107141: [Inline-asm] Add diagnosts for unsupported inline assembly arguments

2022-03-20 Thread Phoebe Wang via Phabricator via cfe-commits
pengfei added a comment.

Ping @jyu2


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107141

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


[PATCH] D102669: [analyzer][ctu] Fix wrong 'multiple definitions' errors caused by space characters in lookup names when parsing the ctu index file

2022-03-20 Thread Ella Ma via Phabricator via cfe-commits
OikawaKirie added a comment.
Herald added a project: All.

Thanks, @keith.

I agree with @keith to commit this patch without using on-demand-parsing 
through cc1.
As this patch has nothing to do with the target triple issue we found.

In the current version, I use the PCH file to load the external TU.
And it seems to work fine on my system and on the Windows CI.

IMO, maybe we can just leave a FIXME or something else in the test case and 
commit this patch to fix the original problem we want to fix.
(of course, re-submit to rerun the test case on Linux)
What do you think? @steakhal


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

https://reviews.llvm.org/D102669

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


[PATCH] D121271: [C++20] [Modules] Don't generate strong function of a partition in importing modules

2022-03-20 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu added a comment.

In D121271#3394108 , @iains wrote:

> it looks like the test case is failing everywhere - perhaps as a result of 
> changes in the mangling scheme?

Oh, yeah... let me try to continue the work in mangling scheme. I feel it is 
important otherwise it is not so good to demangle.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121271

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


[PATCH] D121097: [C++20][Modules][HU 3/5] Emit module macros for header units.

2022-03-20 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu accepted this revision.
ChuanqiXu added a comment.
This revision is now accepted and ready to land.

In D121097#3391698 , @iains wrote:

> In D121097#3391236 , @ChuanqiXu 
> wrote:
>
>> I feel good if we could add  the test from: 
>> http://eel.is/c++draft/cpp.import#8.
>
> I agree we should have tests based on all the relevant examples in the 
> standard.
>
> However, that specific example is not connected with **building** header 
> units, but instead is connected with consuming various preprocessor 
> directives etc. when building a regular module.  We actually already have 
> some of the tests in diagnosing bad imports.
>
> So I think that (after this series is in) we should be in a position to add 
> some more of the examples in the standard - as a follow-on patch, does that 
> make sense?

Yeah, it makes sense. This one LGTM.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121097

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


[PATCH] D119792: [Clang] [P2025] Analyze only potential scopes for NRVO

2022-03-20 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu added inline comments.



Comment at: clang/include/clang/Sema/Scope.h:518
 
   void addNRVOCandidate(VarDecl *VD) {
+// every candidate except VD is "spoiled" now, remove them from the set

Izaron wrote:
> ChuanqiXu wrote:
> > Firstly I am wondering why here doesn't check `NRVO.getInt()` to shortcut 
> > directly. But later I found it would change the logic in 
> > `::mergeNRVOIntoParent`:
> > ```
> > void Scope::mergeNRVOIntoParent() {
> >   if (VarDecl *Candidate = NRVO.getPointer()) {
> > if (isDeclScope(Candidate))
> >   Candidate->setNRVOVariable(true);
> >   }
> >   ...
> > ```
> > 
> > It would set NRVO for the candidate in NRVO if it is in current scope. With 
> > the context of `addNRVOCandidate` here, I could judge that the change would 
> > be:
> > ```
> > X test(bool B) {
> >   X x; // before: no nrvo, after: no nrvo (same)
> >   if (B)
> > return x;
> >   X y; // before: no nrvo, after: nrvo (better)
> >   return y; // Now NRVO.getInt()==true and NRVO.getPointer() == y;
> > }
> > ```
> > 
> > Yeah, the behavior is still 'right'. `y` should be NRVO in this case. But 
> > the implementation smell bad, if `NRVO.getInt()` is true, we shouldn't do 
> > any thing. I am not sure if I state my points well. I mean the 
> > implementation might be correct, but it is hard to understand, read and 
> > maintain. It'd better to make the reader avoid doing mathmatics when 
> > reading the codes.
> > I am not sure if I state my points well. I mean the implementation might be 
> > correct, but it is hard to understand, read and maintain. It'd better to 
> > make the reader avoid doing mathmatics when reading the codes.
> I agree that it is really hard to understand and needs to be polished. It 
> took long time for me to construct the code that won't break.
> 
> I think that one of the sources of the complexity is the `NRVO` variable 
> itself.
> If we could change
> ```
> llvm::PointerIntPair NRVO;
> ```
> to something like
> ```
> VarDecl *NRVOCandidate;
> bool InvalidatesParentNRVOCandidates;
> ```
> And maybe rename `setNoNRVO()` to smth like `invalidateNRVOCandidates` and so 
> on.
> 
> What do you think?
From my understanding, 
```
llvm::PointerIntPair NRVO;
```
is structurally equal to
```
VarDecl *NRVOCandidate;
bool InvalidatesParentNRVOCandidates;
```

so it doesn't change anything. My idea is that if it is possible to remove 
`NRVOCandidatesInScope`? Since there would be at most one NRVO candidate in one 
scope. So it should be possible to represent the NRVO candidate by one variable 
if we don't support nested scopes. If it makes sense? Then let me consider the 
case about nested scopes. For the nested scopes, the child scope is responsible 
to inform the parent scope that:
 If any variable in the parent scope is an available NRVO candidate.

So the child should offer a set for unavailable NRVO candidates for the parent 
scope. So we could get the data structure:
```
llvm::SmallMap NRVOCandidatesLattices;
```

`NRVOCandidatesLattices[V] == true` indicates that V is known available in 
current scope and all the child scopes. And `NRVOCandidatesLattices[V] == 
false` indicates that V is known unavailable in current scope and all the child 
scopes.

So we could get the implementation for `addNRVOCandidate(VarDecl *VD)`:
```
if (VD not in NRVOCandidatesLattices) {
NRVOCandidatesLattices[VD] = true; // We met the VD firstly, it should be 
available NRVO candidate.
Update NRVOCandidatesLattices for other variables; // There should be only 
one available variables in NRVOCandidatesLattices.
}
else if (NRVOCandidatesLattices[VD])
nothing;  // We met the available NRVO again, we shouldn't do anything;
else // NRVOCandidatesLattices[VD] == false;
nothing;  // We've already know what happened.
```


And in `mergeNRVOIntoParent `, we could do:
```
VarDecl *VD = try to get the only one available NRVO candidate from 
UnavilableNRVOCandidates;
if (VD && isDeclScope(Candidate))
 set VD as NRVO candidate;

ParentScope->mergeUnavilableNRVOCandidates(UnavilableNRVOCandidates); // We 
could do lattice merges here. The implementation should be trivial.
```

The implementation looks good to me and easy to understand. Maybe we could add 
extra data structure to erase the iterations in `mergeNRVOIntoParent ` and the 
first branch of `addNRVOCandidate `. But they are helpers and wouldn't make the 
framework hard to understand.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D119792

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


[PATCH] D121992: [Clang] [Driver] Add option to set alternative toolchain path

2022-03-20 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: clang/include/clang/Driver/Driver.h:152
 
+  /// Alternative toolchain path in prior to sysroot.
+  std::string OverlayToolChainPath;

I don't understand the use of "in" in the comment. Perhaps "used" was meant?



Comment at: clang/lib/Driver/ToolChains/Linux.cpp:270-271
+addPathIfExists(D, ExtraPath + "/usr/lib/../" + OSLibDir, Paths);
+addPathIfExists(D, ExtraPath + "/lib", Paths);
+addPathIfExists(D, ExtraPath + "/usr/lib", Paths);
+  }

The `/lib` and `/usr/lib` cases should occur after the multiarch and `OSLibDir` 
cases taken from the sysroot.



Comment at: clang/test/Driver/gcc-toolchain.cpp:42
+/// Test option to add 'overlay platform toolchain'
+// RUN: %clangxx %s -### --target=powerpc64le-linux-gnu \
+// RUN:   
--overlay-platform-toolchain=%S/Inputs/powerpc64le-linux-gnu-tree/gcc-11.2.0 \

Should specify a sysroot and test relative ordering between resource paths 
taken from the "overlay platform toochain" and the sysroot.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121992

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


[PATCH] D70401: [RISCV] Complete RV32E/ilp32e implementation

2022-03-20 Thread Kito Cheng via Phabricator via cfe-commits
kito-cheng added a comment.

Last LLVM sync-up call @asb has raise the discussion about the ILP32E issue, so 
here is note from my site:

RISC-V psABI doc still say "we don't  guarantee the stability of `ILP32E`", the 
reason is RV32E still not a ratified extension, but as psABI chair, what I can 
say is we intend to do NOT change as possible.

As I know rv32e*/ilp32e are already used by many vendors (include SiFive), so I 
support ilp32e should be supported on LLVM upstream.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70401

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


[PATCH] D122110: [Clang] Set -mlinker-version explicitly in the lto test

2022-03-20 Thread Jez Ng via Phabricator via cfe-commits
int3 added a comment.

Would it make sense to have clang pass `-object_path_lto` whenever it's 
invoking LLD?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122110

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


[PATCH] D122109: [CMake][Clang] Skip host link version detection for lld on Darwin

2022-03-20 Thread Jez Ng via Phabricator via cfe-commits
int3 accepted this revision.
int3 added a comment.
This revision is now accepted and ready to land.

Thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122109

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


[PATCH] D122104: [X86][regcall] Support passing / returning structures

2022-03-20 Thread LuoYuanke via Phabricator via cfe-commits
LuoYuanke added inline comments.



Comment at: clang/include/clang/CodeGen/CGFunctionInfo.h:744
+  void setMaxVectorWidth(unsigned Width) {
+ MaxVectorWidth = Width ? llvm::countTrailingZeros(Width) + 1 : 0;
+  }

Use "Log2_32()"?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122104

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


[PATCH] D121627: [IROutliner][NFC] Fix typo in doc of findOrCreatePHIInBlock

2022-03-20 Thread Andrew Litteken via Phabricator via cfe-commits
AndrewLitteken accepted this revision.
AndrewLitteken added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121627

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


[PATCH] D122111: [clang-tidy] Fix false positives in `misc-redundant-expression` check

2022-03-20 Thread Fabian Wolff via Phabricator via cfe-commits
fwolff created this revision.
fwolff added reviewers: alexfh, aaron.ballman, pavelkryukov.
fwolff added a project: clang-tools-extra.
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a project: All.
fwolff requested review of this revision.
Herald added a subscriber: cfe-commits.

It turns out that the right-hand sides of overloaded comparison operators are 
currently not checked at all in `misc-redundant-expression`, leading to such 
false positives as given in #54011 
 or here 
. This patch fixes this.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122111

Files:
  clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
@@ -453,6 +453,11 @@
   if (s1 >= 1 || s1 <= 1) return true;
   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always 
true
 
+  // Test for absence of false positives (issue #54011).
+  if (s1 == 1 || s1 == 2) return true;
+  if (s1 > 1 && s1 < 3) return true;
+  if (s1 >= 2 || s1 <= 0) return true;
+
   // Test for overloaded operators that may modify their params.
   S2 s2;
   if (s2 == 1 || s2 != 1) return true;
Index: clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
===
--- clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -569,6 +569,7 @@
   std::string SwapId = (Id + "-swap").str();
   std::string NegateId = (Id + "-negate").str();
   std::string OverloadId = (Id + "-overload").str();
+  std::string ConstId = (Id + "-const").str();
 
   const auto RelationalExpr = ignoringParenImpCasts(binaryOperator(
   isComparisonOperator(), expr().bind(Id),
@@ -600,7 +601,8 @@
   cxxOperatorCallExpr(
   hasAnyOverloadedOperatorName("==", "!=", "<", "<=", ">", ">="),
   // Filter noisy false positives.
-  unless(isMacro()), unless(isInTemplateInstantiation()))
+  unless(isMacro()), unless(isInTemplateInstantiation()),
+  hasRHS(ignoringParenImpCasts(integerLiteral().bind(ConstId
   .bind(OverloadId);
 
   return anyOf(RelationalExpr, CastExpr, NegateRelationalExpr,
@@ -683,6 +685,9 @@
 OperandExpr = OverloadedOperatorExpr;
 Opcode = 
BinaryOperator::getOverloadedOpcode(OverloadedOperatorExpr->getOperator());
 
+if (!retrieveIntegerConstantExpr(Result, Id, Value, ConstExpr))
+  return false;
+
 return BinaryOperator::isComparisonOp(Opcode);
   } else {
 return false;


Index: clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
@@ -453,6 +453,11 @@
   if (s1 >= 1 || s1 <= 1) return true;
   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
 
+  // Test for absence of false positives (issue #54011).
+  if (s1 == 1 || s1 == 2) return true;
+  if (s1 > 1 && s1 < 3) return true;
+  if (s1 >= 2 || s1 <= 0) return true;
+
   // Test for overloaded operators that may modify their params.
   S2 s2;
   if (s2 == 1 || s2 != 1) return true;
Index: clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
===
--- clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -569,6 +569,7 @@
   std::string SwapId = (Id + "-swap").str();
   std::string NegateId = (Id + "-negate").str();
   std::string OverloadId = (Id + "-overload").str();
+  std::string ConstId = (Id + "-const").str();
 
   const auto RelationalExpr = ignoringParenImpCasts(binaryOperator(
   isComparisonOperator(), expr().bind(Id),
@@ -600,7 +601,8 @@
   cxxOperatorCallExpr(
   hasAnyOverloadedOperatorName("==", "!=", "<", "<=", ">", ">="),
   // Filter noisy false positives.
-  unless(isMacro()), unless(isInTemplateInstantiation()))
+  unless(isMacro()), unless(isInTemplateInstantiation()),
+  hasRHS(ignoringParenImpCasts(integerLiteral().bind(ConstId
   .bind(OverloadId);
 
   return anyOf(RelationalExpr, CastExpr, NegateRelationalExpr,
@@ -683,6 +685,9 @@
 OperandExpr = OverloadedOperatorExpr;
 Opcode = BinaryOperator::getOverloadedOpcode(OverloadedOperatorExpr->getOperator());
 
+if 

[PATCH] D122110: [Clang] Set -mlinker-version explicitly in the lto test

2022-03-20 Thread Petr Hosek via Phabricator via cfe-commits
phosek created this revision.
phosek added reviewers: smeenai, int3, oontvoo, thakis.
Herald added subscribers: ormris, steven_wu, hiraditya, inglorion.
Herald added a project: All.
phosek requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This test assumes that the driver will set -object_path_lto linker
flag and it requests the platform linker with -fuse-ld=. When lld is
used as the host linker, the host linker version is unset and so
Clang won't set -object_path_lto since that flag is set conditionally
only when linker version is at least 116. We set the linker version
explicitly to make sure that -object_path_lto is set. That approach
is already used elsewhere in the test.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122110

Files:
  clang/test/Driver/darwin-ld-lto.c


Index: clang/test/Driver/darwin-ld-lto.c
===
--- clang/test/Driver/darwin-ld-lto.c
+++ clang/test/Driver/darwin-ld-lto.c
@@ -20,12 +20,14 @@
 
 
 // Check that -object_lto_path is passed correctly to ld64
-// RUN: %clang -fuse-ld= -target x86_64-apple-darwin10 %s -flto=full -### 2>&1 
\
+// RUN: %clang -fuse-ld= -target x86_64-apple-darwin10 %s -flto=full \
+// RUN: -mlinker-version=116 -### 2>&1 \
 // RUN: | FileCheck -check-prefix=FULL_LTO_OBJECT_PATH %s
 // FULL_LTO_OBJECT_PATH: {{ld(.exe)?"}}
 // FULL_LTO_OBJECT_PATH-SAME: "-object_path_lto"
 // FULL_LTO_OBJECT_PATH-SAME: {{cc\-[a-zA-Z0-9_]+.o}}"
-// RUN: %clang -fuse-ld= -target x86_64-apple-darwin10 %s -flto=thin -### 2>&1 
\
+// RUN: %clang -fuse-ld= -target x86_64-apple-darwin10 %s -flto=thin \
+// RUN: -mlinker-version=116 -### 2>&1 \
 // RUN: | FileCheck -check-prefix=THIN_LTO_OBJECT_PATH %s
 // THIN_LTO_OBJECT_PATH: {{ld(.exe)?"}}
 // THIN_LTO_OBJECT_PATH-SAME: "-object_path_lto"


Index: clang/test/Driver/darwin-ld-lto.c
===
--- clang/test/Driver/darwin-ld-lto.c
+++ clang/test/Driver/darwin-ld-lto.c
@@ -20,12 +20,14 @@
 
 
 // Check that -object_lto_path is passed correctly to ld64
-// RUN: %clang -fuse-ld= -target x86_64-apple-darwin10 %s -flto=full -### 2>&1 \
+// RUN: %clang -fuse-ld= -target x86_64-apple-darwin10 %s -flto=full \
+// RUN: -mlinker-version=116 -### 2>&1 \
 // RUN: | FileCheck -check-prefix=FULL_LTO_OBJECT_PATH %s
 // FULL_LTO_OBJECT_PATH: {{ld(.exe)?"}}
 // FULL_LTO_OBJECT_PATH-SAME: "-object_path_lto"
 // FULL_LTO_OBJECT_PATH-SAME: {{cc\-[a-zA-Z0-9_]+.o}}"
-// RUN: %clang -fuse-ld= -target x86_64-apple-darwin10 %s -flto=thin -### 2>&1 \
+// RUN: %clang -fuse-ld= -target x86_64-apple-darwin10 %s -flto=thin \
+// RUN: -mlinker-version=116 -### 2>&1 \
 // RUN: | FileCheck -check-prefix=THIN_LTO_OBJECT_PATH %s
 // THIN_LTO_OBJECT_PATH: {{ld(.exe)?"}}
 // THIN_LTO_OBJECT_PATH-SAME: "-object_path_lto"
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122109: [CMake][Clang] Skip host link version detection for lld on Darwin

2022-03-20 Thread Petr Hosek via Phabricator via cfe-commits
phosek created this revision.
phosek added reviewers: smeenai, int3, oontvoo, thakis.
Herald added a subscriber: mgorny.
Herald added a project: All.
phosek requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

When lld is being used as host linker, skip version detection since
lld version cannot be used interchangeably with ld64 version and lld
is already handled specially in Clang driver.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122109

Files:
  clang/CMakeLists.txt


Index: clang/CMakeLists.txt
===
--- clang/CMakeLists.txt
+++ clang/CMakeLists.txt
@@ -403,7 +403,7 @@
 
 # Determine HOST_LINK_VERSION on Darwin.
 set(HOST_LINK_VERSION)
-if (APPLE)
+if (APPLE AND NOT CMAKE_LINKER MATCHES ".*lld.*")
   set(LD_V_OUTPUT)
   execute_process(
 COMMAND sh -c "${CMAKE_LINKER} -v 2>&1 | head -1"


Index: clang/CMakeLists.txt
===
--- clang/CMakeLists.txt
+++ clang/CMakeLists.txt
@@ -403,7 +403,7 @@
 
 # Determine HOST_LINK_VERSION on Darwin.
 set(HOST_LINK_VERSION)
-if (APPLE)
+if (APPLE AND NOT CMAKE_LINKER MATCHES ".*lld.*")
   set(LD_V_OUTPUT)
   execute_process(
 COMMAND sh -c "${CMAKE_LINKER} -v 2>&1 | head -1"
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D111400: [Clang][C++2b] P2242R3: Non-literal variables [...] in constexpr

2022-03-20 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:163
+
+// Test whether lambda are correctly treated as implicitely constexpr under 
the relaxed c++23 rules.
+int test_lambdas_implicitly_constexpr() {

Fix typo and expand comment.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:165-169
+  auto a = [] {
+static const int m = 32;
+return m;
+  };
+

Remove this lambda. It is not callable in any constant expression even under 
C++2b mode.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:194-195
+  c(0);
+  constexpr auto c_ok = c(0); // cxx2a-error {{must be initialized by a 
constant expression}} \
+   // cxx2a-note {{non-constexpr function}}
+

Minor nit: Align comments.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:207-209
+  constexpr auto non_literal_ko = non_literal(true); // expected-error 
{{constexpr variable 'non_literal_ko' must be initialized by a constant 
expression}} \
+  // cxx2a-note 
{{non-constexpr function}} \
+  // cxx2b-note {{in call}}

Minor nit: Align comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111400

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


[PATCH] D111400: [Clang][C++2b] P2242R3: Non-literal variables [...] in constexpr

2022-03-20 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp:26
   };
-  struct Nonlit { Nonlit(); }; // expected-note {{not literal}}
+  struct Nonlit { // cxx2a-note {{'Nonlit' is not literal becaus}}
+Nonlit();

Typo still present.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:1-2
+// RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2a %s 
-fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++2b-compat
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2b %s 
-fcxx-exceptions -triple=x86_64-linux-gnu
+

Flip `cxx2a` and `cxx2b` prefixes to match mode used. Add 
`-Wno-c++2b-extensions` since tests for those warnings are covered in 
`p3-2b.cpp`.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:8
+
+#if __cplusplus > 202002
+

It's customary to have the `L` suffix in the context of checking `__cplusplus`.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:90
+
+int non_literal_1 = non_literal(false);
+

Evaluate as `constexpr`.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:116
+
+int d = label();
+

Evaluate as `constexpr`.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:118
+
+} // namespace eval_goto
+

Move `#endif` to here (from below) so the explicitly-`constexpr` lambda cases 
are also tried in C++20 mode.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:120-121
+
+// Test that explicitely constexpr lambdas behave correctly,
+// This is to be constracted with the test for implicitely constexpr lambda 
below.
+int test_in_lambdas() {

Fix typos.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:125
+static const int m = 32; // expected-note {{control flows through the 
declaration of a static variable}} \
+ // expected-warning {{incompatible with C++ 
standards before C++2b}}
+return m;

Adjust for suggested changes: do not expect C++2b mode warning in C++20 mode.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:132
+  return 0;
+static const int m = n; // expected-warning {{incompatible with C++ 
standards before C++2b}}
+return m;

Adjust for suggested changes: do not expect C++2b mode warning in C++20 mode.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:141
+else
+  goto test; // expected-warning {{incompatible with C++ standards before 
C++2b}} \
+ // expected-note {{subexpression not valid in a constant 
expression}}

Adjust for suggested changes: do not expect C++2b mode warning in C++20 mode.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:147-148
+  c(0);
+  constexpr auto c_error = c(1); // expected-error {{constexpr variable 
'c_error' must be initialized by a constant expression}} \
+   // expected-note {{in call to}}
+

Minor: Adjust alignment of comments.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:152
+if (!b)
+  NonLiteral n; // expected-note {{non-literal type 'NonLiteral' cannot be 
used in a constant expression}}
+return 0;

Adjust for C++20/C++2b differences.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:156-158
+  constexpr auto non_literal_ok = non_literal(false); // expected-error 
{{constexpr variable 'non_literal_ok' must be initialized by a constant 
expression}} \
+  // expected-note {{in 
call}}
+  constexpr auto non_literal_ko = non_literal(true);

Guard calls to be C++2b only (since definition is not okay in C++20 mode). 
Adjust naming so that "ok" name is used for the C++2b-valid case.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:160-161
+}
+
+#endif
+

Move `#endif` up so the explicitly-`constexpr` lambda cases are also tried in 
C++20 mode.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111400

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


[PATCH] D121556: [randstruct] Add randomize structure layout support

2022-03-20 Thread Bill Wendling via Phabricator via cfe-commits
void updated this revision to Diff 416808.
void added a comment.

Move SEED into LangOpts.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121556

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/Randstruct.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Driver/Options.td
  clang/lib/AST/CMakeLists.txt
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Randstruct.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Sema/AnalysisBasedWarnings.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/unittests/AST/CMakeLists.txt
  clang/unittests/AST/RandstructTest.cpp

Index: clang/unittests/AST/RandstructTest.cpp
===
--- /dev/null
+++ clang/unittests/AST/RandstructTest.cpp
@@ -0,0 +1,409 @@
+//===- unittest/AST/RandstructTest.cpp ===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file contains tests for Clang's structure field layout randomization.
+//
+//===--===//
+
+/*
+ * Build this test suite by running `make ASTTests` in the build folder.
+ *
+ * Run this test suite by running the following in the build folder:
+ * ` ./tools/clang/unittests/AST/ASTTests
+ * --gtest_filter=StructureLayoutRandomization*`
+ */
+
+#include "clang/AST/Randstruct.h"
+#include "gtest/gtest.h"
+
+#include "DeclMatcher.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Testing/CommandLineArgs.h"
+#include "clang/Tooling/Tooling.h"
+
+#include 
+
+using namespace clang;
+using namespace clang::ast_matchers;
+using namespace clang::randstruct;
+
+using field_names = std::vector;
+
+namespace {
+
+std::unique_ptr makeAST(const std::string ) {
+  std::vector Args = getCommandLineArgsForTesting(Lang_C99);
+  Args.push_back("-frandstruct-seed=1234567890abcdef");
+  return tooling::buildASTFromCodeWithArgs(SourceCode, Args, "input.c");
+}
+
+RecordDecl *getRecordDeclFromAST(const ASTContext , const std::string ) {
+  return FirstDeclMatcher().match(C.getTranslationUnitDecl(),
+  recordDecl(hasName(Name)));
+}
+
+std::vector getFieldNamesFromRecord(const RecordDecl *RD) {
+  std::vector Fields;
+
+  Fields.reserve(8);
+  for (auto *Field : RD->fields())
+Fields.push_back(Field->getNameAsString());
+
+  return Fields;
+}
+
+bool isSubsequence(const field_names , const field_names ) {
+  unsigned SeqLen = Seq.size();
+  unsigned SubLen = Subseq.size();
+
+  bool IsSubseq = false;
+  for (unsigned I = 0; I < SeqLen; ++I)
+if (Seq[I] == Subseq[0]) {
+  IsSubseq = true;
+  for (unsigned J = 0; J + I < SeqLen && J < SubLen; ++J) {
+if (Seq[J + I] != Subseq[J]) {
+  IsSubseq = false;
+  break;
+}
+  }
+}
+
+  return IsSubseq;
+}
+
+} // end anonymous namespace
+
+namespace clang {
+namespace ast_matchers {
+
+#define RANDSTRUCT_TEST_SUITE_TEST StructureLayoutRandomizationTestSuiteTest
+
+TEST(RANDSTRUCT_TEST_SUITE_TEST, CanDetermineIfSubsequenceExists) {
+  const field_names Seq = {"a", "b", "c", "d"};
+
+  ASSERT_TRUE(isSubsequence(Seq, {"b", "c"}));
+  ASSERT_TRUE(isSubsequence(Seq, {"a", "b", "c", "d"}));
+  ASSERT_TRUE(isSubsequence(Seq, {"b", "c", "d"}));
+  ASSERT_TRUE(isSubsequence(Seq, {"a"}));
+  ASSERT_FALSE(isSubsequence(Seq, {"a", "d"}));
+}
+
+#define RANDSTRUCT_TEST StructureLayoutRandomization
+
+TEST(RANDSTRUCT_TEST, UnmarkedStruct) {
+  const std::unique_ptr AST = makeAST(R"c(
+struct test {
+int bacon;
+long lettuce;
+long long tomato;
+float mayonnaise;
+};
+  )c");
+
+  const RecordDecl *RD = getRecordDeclFromAST(AST->getASTContext(), "test");
+  const field_names Expected = {"bacon", "lettuce", "tomato", "mayonnaise"};
+
+  ASSERT_FALSE(RD->getAttr());
+  ASSERT_FALSE(RD->isRandomized());
+  ASSERT_EQ(Expected, getFieldNamesFromRecord(RD));
+}
+
+TEST(RANDSTRUCT_TEST, MarkedNoRandomize) {
+  const std::unique_ptr AST = makeAST(R"c(
+struct test {
+int bacon;
+long lettuce;
+long long tomato;
+float mayonnaise;
+} 

[PATCH] D122077: [InstCombine] Fold (ctpop(X) == 1) | (X == 0) into ctpop(X) < 2

2022-03-20 Thread Craig Topper via Phabricator via cfe-commits
craig.topper added inline comments.



Comment at: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp:921
+  if (IsAnd &&
+  match(Cmp0, m_ICmp(Pred0, m_Intrinsic(m_Value(X)),
+ m_SpecificInt(1))) &&

Since the m_ICmp matches are the same for And/Or can we share those and 
possibly early out from the function if they don't match. Then only use `IsAnd` 
to check the predicates and control the what we emit?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122077

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


[PATCH] D122083: [Concepts] Fix placeholder constraints when references are involved

2022-03-20 Thread Roy Jacobson via Phabricator via cfe-commits
royjacobson updated this revision to Diff 416803.
royjacobson edited the summary of this revision.
royjacobson added a comment.

I noticed issue #53911 which is very similar so I fixed it as well.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122083

Files:
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaTemplate/concepts.cpp


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 
'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 
'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not 
satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@
   }
 }
 namespace PR53911 {
-  template concept C = false;
+  template concept C = false; // expected-note 3 {{because 'false' 
evaluated to false}}
 
-  C auto *f1() {
-return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
+return (void*)nullptr;
   }
-  C auto *f2() {
-return (int*)nullptr; // FIXME: should error
+  C auto *f2() { // expected-error {{deduced type 'int' does not satisfy 'C'}}
+return (int*)nullptr;
+  }
+  C auto *f3() { // expected-error {{deduced type 'int' does not satisfy 
'C'}}
+return (int*)nullptr;
   }
 }
 
@@ -222,3 +225,26 @@
 };
 void (*f2)() = B::f; // expected-error {{address of overloaded function 'f' 
does not match required type}}
 }
+
+namespace PR54443 {
+
+template 
+struct is_same { static constexpr bool value = false; };
+
+template 
+struct is_same { static constexpr bool value = true; };
+
+template 
+concept same_as = is_same::value; // expected-note-re 4 {{because {{.*}} 
evaluated to false}}
+
+int const ();
+
+same_as auto i1 = f(); // expected-error {{deduced type 'int' does 
not satisfy 'same_as'}}
+same_as auto  = f();
+same_as auto & = f(); // expected-error {{deduced type 'const 
int &' does not satisfy 'same_as'}}
+
+same_as auto i4 = f(); // expected-error {{deduced type 'int' 
does not satisfy 'same_as'}}
+same_as auto  = f(); // expected-error {{deduced type 'const 
int' does not satisfy 'same_as'}}
+same_as auto & = f();
+
+}
Index: clang/lib/Sema/SemaTemplateDeduction.cpp
===
--- clang/lib/Sema/SemaTemplateDeduction.cpp
+++ clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -4769,12 +4769,14 @@
   return DAR_FailedAlreadyDiagnosed;
   }
 
-  if (const auto *AT = Type.getType()->getAs()) {
+  QualType MaybeAuto = Type.getType().getNonReferenceType();
+  while (MaybeAuto->isPointerType()) {
+MaybeAuto = MaybeAuto->getPointeeType();
+  }
+  if (const auto *AT = MaybeAuto->getAs()) {
 if (AT->isConstrained() && !IgnoreConstraints) {
-  auto ConstraintsResult =
-  CheckDeducedPlaceholderConstraints(*this, *AT,
- Type.getContainedAutoTypeLoc(),
- DeducedType);
+  auto ConstraintsResult = CheckDeducedPlaceholderConstraints(
+  *this, *AT, Type.getContainedAutoTypeLoc(), DeducedType);
   if (ConstraintsResult != DAR_Succeeded)
 return ConstraintsResult;
 }


Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -171,7 +171,7 @@
 }
 
 namespace PR49188 {
-  template concept C = false; // expected-note 6 {{because 'false' evaluated to false}}
+  template concept C = false; // expected-note 7 {{because 'false' evaluated to false}}
 
   C auto f1() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
@@ -189,7 +189,7 @@
   }
   C decltype(auto) f6() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
   }
-  C auto& f7() { // expected-error {{cannot form a reference to 'void'}}
+  C auto& f7() { // expected-error {{deduced type 'void' does not satisfy 'C'}}
 return void();
   }
   C auto& f8() {
@@ -199,13 +199,16 @@
   }
 }
 namespace PR53911 {
-  template concept C = false;
+  template concept C = false; // expected-note 3 {{because 'false' evaluated to false}}
 
-  C auto *f1() {
-return (void*)nullptr; // FIXME: should error
+  C auto *f1() { // expected-error {{deduced type 'void' does 

[PATCH] D122046: [clang] Remove Address::deprecated from MveEmitter

2022-03-20 Thread Nikita Popov via Phabricator via cfe-commits
nikic added inline comments.



Comment at: clang/utils/TableGen/MveEmitter.cpp:1197
+const Type *Ty = nullptr;
+if (auto *DI = dyn_cast(D->getArg(0))->getOperator())
+  if (auto *PTy = dyn_cast(getType(DI, Param)))

Should be either `cast` or check for nullptr before dereferencing?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122046

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


[PATCH] D111400: [Clang][C++2b] P2242R3: Non-literal variables [...] in constexpr

2022-03-20 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 416793.
cor3ntin added a comment.

- clang-format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111400

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constant-expression-cxx14.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1361,7 +1361,7 @@
 
   Non-literal variables (and labels and gotos) in constexpr functions
   https://wg21.link/P2242R3;>P2242R3
-  No
+  Clang 15
 
 
   Character encoding of diagnostic text
Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -0,0 +1,226 @@
+// RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++2b-compat
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2b %s -fcxx-exceptions -triple=x86_64-linux-gnu
+
+struct NonLiteral {
+  NonLiteral() {}
+};
+
+#if __cplusplus > 202002
+
+constexpr int f(int n) {  // expected-error {{constexpr function never produces a constant expression}}
+  static const int m = n; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return m;
+}
+constexpr int g(int n) {// expected-error {{constexpr function never produces a constant expression}}
+  thread_local const int m = n; // expected-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+  return m;
+}
+
+constexpr int h(int n) {  // expected-error {{constexpr function never produces a constant expression}}
+  static const int m = n; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return  - 
+}
+constexpr int i(int n) {// expected-error {{constexpr function never produces a constant expression}}
+  thread_local const int m = n; // expected-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+  return  - 
+}
+
+constexpr int j(int n) {
+  if (!n)
+return 0;
+  static const int m = n; // expected-warning{{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
+  return m;
+}
+constexpr int j0 = j(0);
+
+constexpr int k(int n) {
+  if (!n)
+return 0;
+  thread_local const int m = n; // expected-warning{{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
+
+  return m;
+}
+constexpr int k0 = k(0);
+
+constexpr int j_evaluated(int n) {
+  if (!n)
+return 0;
+  static const int m = n; // expected-warning{{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return m;
+}
+
+constexpr int je = j_evaluated(1); // expected-error {{constexpr variable 'je' must be initialized by a constant expression}}  \
+   // expected-note {{in call}}
+
+constexpr int k_evaluated(int n) {
+  if (!n)
+return 0;
+  thread_local const int m = n; // expected-warning{{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+
+  return m;
+}
+
+constexpr int ke = k_evaluated(1); // expected-error {{constexpr variable 'ke' must be initialized by a constant expression}} \
+   // expected-note {{in call}}
+
+constexpr int static_constexpr() { // 

[PATCH] D111400: [Clang][C++2b] P2242R3: Non-literal variables [...] in constexpr

2022-03-20 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 416792.
cor3ntin marked 5 inline comments as done.
cor3ntin added a comment.

- Tidy up tests
- Add comments
- Add a test with a non literal variable in dependant context as per Hubert's 
suggestion


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111400

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constant-expression-cxx14.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1361,7 +1361,7 @@
 
   Non-literal variables (and labels and gotos) in constexpr functions
   https://wg21.link/P2242R3;>P2242R3
-  No
+  Clang 15
 
 
   Character encoding of diagnostic text
Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -0,0 +1,232 @@
+// RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++2b-compat
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2b %s -fcxx-exceptions -triple=x86_64-linux-gnu
+
+struct NonLiteral {
+  NonLiteral() {}
+};
+
+#if __cplusplus > 202002
+
+constexpr int f(int n) {  // expected-error {{constexpr function never produces a constant expression}}
+  static const int m = n; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return m;
+}
+constexpr int g(int n) {// expected-error {{constexpr function never produces a constant expression}}
+  thread_local const int m = n; // expected-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+  return m;
+}
+
+constexpr int h(int n) {  // expected-error {{constexpr function never produces a constant expression}}
+  static const int m = n; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return  - 
+}
+constexpr int i(int n) {// expected-error {{constexpr function never produces a constant expression}}
+  thread_local const int m = n; // expected-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+  return  - 
+}
+
+constexpr int j(int n) {
+  if (!n)
+return 0;
+  static const int m = n; // expected-warning{{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
+  return m;
+}
+constexpr int j0 = j(0);
+
+constexpr int k(int n) {
+  if (!n)
+return 0;
+  thread_local const int m = n; // expected-warning{{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
+
+  return m;
+}
+constexpr int k0 = k(0);
+
+constexpr int j_evaluated(int n) {
+  if (!n)
+return 0;
+  static const int m = n; // expected-warning{{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return m;
+}
+
+constexpr int je = j_evaluated(1); // expected-error {{constexpr variable 'je' must be initialized by a constant expression}}  \
+   // expected-note {{in call}}
+
+constexpr int k_evaluated(int n) {
+  if (!n)
+return 0;
+  thread_local const int m = n; // expected-warning{{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+
+  return m;
+}
+
+constexpr int ke = k_evaluated(1); // expected-error {{constexpr variable 'ke' must be 

[PATCH] D122104: [X86][regcall] Support passing / returning structures

2022-03-20 Thread Phoebe Wang via Phabricator via cfe-commits
pengfei created this revision.
pengfei added reviewers: erichkeane, craig.topper, LiuChen3, LuoYuanke.
Herald added a project: All.
pengfei requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Currently, the regcall calling conversion in Clang doesn't match with
ICC when passing / returning structures. https://godbolt.org/z/axxKMKrW7

This patch tries to fix the problem to match with ICC.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122104

Files:
  clang/include/clang/CodeGen/CGFunctionInfo.h
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/TargetInfo.cpp
  clang/test/CodeGen/aarch64-neon-tbl.c
  clang/test/CodeGen/regcall2.c

Index: clang/test/CodeGen/regcall2.c
===
--- /dev/null
+++ clang/test/CodeGen/regcall2.c
@@ -0,0 +1,28 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -emit-llvm %s -o - -ffreestanding -target-feature +avx512vl -triple=x86_64-pc-win32 | FileCheck %s --check-prefix=Win
+// RUN: %clang_cc1 -emit-llvm %s -o - -ffreestanding -target-feature +avx512vl -triple=x86_64-pc-linux-gnu | FileCheck %s --check-prefix=Lin
+
+#include 
+
+typedef struct {
+  __m512d r1[4];
+  __m512 r2[4];
+} __sVector;
+__sVector A;
+
+__sVector __regcall foo(int a) {
+  return A;
+}
+
+double __regcall bar(__sVector a) {
+  return a.r1[0][4];
+}
+
+// FIXME: Do we need to change for Windows?
+// Win: define dso_local x86_regcallcc void @__regcall3__foo(%struct.__sVector* noalias sret(%struct.__sVector) align 64 %agg.result, i32 noundef %a) #0
+// Win: define dso_local x86_regcallcc double @__regcall3__bar(%struct.__sVector* noundef %a) #0
+// Win: attributes #0 = { noinline nounwind optnone "frame-pointer"="none" "min-legal-vector-width"="0" "no-builtins" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+avx,+avx2,+avx512f,+avx512vl,+crc32,+cx8,+f16c,+fma,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" }
+
+// Lin: define dso_local x86_regcallcc %struct.__sVector @__regcall3__foo(i32 noundef %a) #0
+// Lin: define dso_local x86_regcallcc double @__regcall3__bar([4 x <8 x double>] %a.coerce0, [4 x <16 x float>] %a.coerce1) #0
+// Lin: attributes #0 = { noinline nounwind optnone "frame-pointer"="none" "min-legal-vector-width"="512" "no-builtins" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+avx,+avx2,+avx512f,+avx512vl,+crc32,+cx8,+f16c,+fma,+mmx,+popcnt,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave" }
Index: clang/test/CodeGen/aarch64-neon-tbl.c
===
--- clang/test/CodeGen/aarch64-neon-tbl.c
+++ clang/test/CodeGen/aarch64-neon-tbl.c
@@ -42,7 +42,7 @@
   return vtbl2_s8(a, b);
 }
 
-// CHECK-LABEL: define{{.*}} <8 x i8> @test_vqtbl2_s8([2 x <16 x i8>] %a.coerce, <8 x i8> noundef %b) #0 {
+// CHECK-LABEL: define{{.*}} <8 x i8> @test_vqtbl2_s8([2 x <16 x i8>] %a.coerce, <8 x i8> noundef %b) #1 {
 // CHECK:   [[__P0_I:%.*]] = alloca %struct.int8x16x2_t, align 16
 // CHECK:   [[A:%.*]] = alloca %struct.int8x16x2_t, align 16
 // CHECK:   [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x2_t, %struct.int8x16x2_t* [[A]], i32 0, i32 0
@@ -89,7 +89,7 @@
   return vtbl3_s8(a, b);
 }
 
-// CHECK-LABEL: define{{.*}} <8 x i8> @test_vqtbl3_s8([3 x <16 x i8>] %a.coerce, <8 x i8> noundef %b) #0 {
+// CHECK-LABEL: define{{.*}} <8 x i8> @test_vqtbl3_s8([3 x <16 x i8>] %a.coerce, <8 x i8> noundef %b) #1 {
 // CHECK:   [[__P0_I:%.*]] = alloca %struct.int8x16x3_t, align 16
 // CHECK:   [[A:%.*]] = alloca %struct.int8x16x3_t, align 16
 // CHECK:   [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x3_t, %struct.int8x16x3_t* [[A]], i32 0, i32 0
@@ -142,7 +142,7 @@
   return vtbl4_s8(a, b);
 }
 
-// CHECK-LABEL: define{{.*}} <8 x i8> @test_vqtbl4_s8([4 x <16 x i8>] %a.coerce, <8 x i8> noundef %b) #0 {
+// CHECK-LABEL: define{{.*}} <8 x i8> @test_vqtbl4_s8([4 x <16 x i8>] %a.coerce, <8 x i8> noundef %b) #1 {
 // CHECK:   [[__P0_I:%.*]] = alloca %struct.int8x16x4_t, align 16
 // CHECK:   [[A:%.*]] = alloca %struct.int8x16x4_t, align 16
 // CHECK:   [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x4_t, %struct.int8x16x4_t* [[A]], i32 0, i32 0
@@ -352,7 +352,7 @@
   return vqtbx1_s8(a, b, c);
 }
 
-// CHECK-LABEL: define{{.*}} <8 x i8> @test_vqtbx2_s8(<8 x i8> noundef %a, [2 x <16 x i8>] %b.coerce, <8 x i8> noundef %c) #0 {
+// CHECK-LABEL: define{{.*}} <8 x i8> @test_vqtbx2_s8(<8 x i8> noundef %a, [2 x <16 x i8>] %b.coerce, <8 x i8> noundef %c) #1 {
 // CHECK:   [[__P1_I:%.*]] = alloca %struct.int8x16x2_t, align 16
 // CHECK:   [[B:%.*]] = alloca %struct.int8x16x2_t, align 16
 // CHECK:   [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.int8x16x2_t, %struct.int8x16x2_t* [[B]], i32 0, i32 0
@@ -373,7 +373,7 @@
   return 

[PATCH] D111400: [Clang][C++2b] P2242R3: Non-literal variables [...] in constexpr

2022-03-20 Thread Hubert Tong via Phabricator via cfe-commits
hubert.reinterpretcast added inline comments.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1904-1906
+if (!SemaRef.LangOpts.CPlusPlus2b &&
+CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(),
  diag::err_constexpr_local_var_non_literal_type,

hubert.reinterpretcast wrote:
> cor3ntin wrote:
> > hubert.reinterpretcast wrote:
> > > This seems to unconditionally error in pre-C++2b modes. For consistency, 
> > > this should be a `-Wc++2b-extensions` warning.
> > We agreed not have this an extension in earlier modes because a valid c++20 
> > program can sfinea on that. Is it not a direction you agree with anymore>
> I think, now that we have the lambda cases all working, we can be confident 
> that `return false;` in older modes is what this code is responsible for in 
> the SFINAE case.
> 
> For handling SFINAE-related cases, there may (eventually) be some 
> restructuring to allow focus on only the template-dependent cases, but C++23 
> might end up needing to do the checking even for non-dependent cases during 
> constant expression evaluation (because the template definition becomes 
> well-formed due to pending removal of IFNDR).
> 
> I've also found indications that Clang generally fails to perform strict 
> constant expression evaluation in relation to instantiations that fail to 
> satisfy the requirements for a constexpr function:
> ```
> template 
> struct A {
>   constexpr int f() {
> T t;  // cannot be trivial default initialization until P1331
>   // (not DR out of Cologne 2019)
> t = T();
> return 42 + t;
>   }
> };
> 
> template 
> short g(int, char (*)[N] = 0);
> 
> template 
> long g(void *);
> 
> struct Z {
>   constexpr Z() {}
>   constexpr operator int() { return 0; }
> };
> const int x = A().f();
> 
> extern decltype(g(0)) q;
> short q;
> ```
> 
Okay, GCC errors for the `NonLiteral` case in C++20 mode. I think that's good 
enough reason for us to leave Clang doing the same (as the patch currently 
does).

```
struct NonLiteral {
  NonLiteral() {}
};

constexpr auto dependent_var_def_lambda(bool b) {
  if (!b)
NonLiteral n;
  return 0;
}
```

https://godbolt.org/z/fM9fanxrG



Comment at: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp:17-22
+constexpr int g() { // expected-error {{constexpr function never produces a 
constant expression}}
+  goto test;// expected-note {{subexpression not valid in a constant 
expression}} \
+   // expected-warning {{use of this statement in a constexpr function 
is incompatible with C++ standards before C++2b}}
+test:
+  return 0;
+}

cor3ntin wrote:
> hubert.reinterpretcast wrote:
> > Still trying to make the choice of tests consistent between the different 
> > cases (static local variable, goto statement, etc.) and consistent within 
> > files...
> > 
> > The test that is here (function will unconditionally evaluate) seems to 
> > belong in `constant-expression-cxx2b.cpp`... or at least that is where the 
> > equivalent tests for the static local variable case, etc. is (and 
> > correctly, I think).
> > 
> > The test that should be here is the "conditionally will evaluate" case 
> > where the function is not called. That is, this file has tests that check 
> > that the warnings are produced purely from the definition being present.
> I'm not sure I understand. No call is made in that file.
The case here is unconditional and not called. So, it should be in 
`constant-expression-cxx2b.cpp` because that is the file with other 
unconditional (and not called) cases. That a call never produces a constant 
expression is a property of the evaluation rules.

The other file currently has `eval_goto::f`, which does have a condition gating 
the evaluation of the `goto` (and is called). A copy of that function (but no 
call) would be what fits in this file.



Comment at: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp:1-3
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu 
-std=c++11 -Werror=c++14-extensions -Werror=c++20-extensions 
-Werror=c++2b-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu 
-std=c++14 -DCXX14 -Werror=c++20-extensions -Werror=c++2b-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu 
-std=c++20 -DCXX14 -DCXX20 -Werror=c++2b-extensions %s

cor3ntin wrote:
> hubert.reinterpretcast wrote:
> > hubert.reinterpretcast wrote:
> > > cor3ntin wrote:
> > > > hubert.reinterpretcast wrote:
> > > > > The use `-Werror` hides potential issues where the error is 
> > > > > categorically produced (instead of under the warning group).
> > > > > 
> > > > > Considering that there is a relevant design consistency issue of 
> > > > > exactly that sort right now that this test could have highlighted 
> > > > > (but didn't), a change to stop using `-Werror` may be prudent.
> 

[PATCH] D121627: [IROutliner][NFC] Fix typo in doc of findOrCreatePHIInBlock

2022-03-20 Thread Hirochika Matsumoto via Phabricator via cfe-commits
hkmatsumoto updated this revision to Diff 416786.
hkmatsumoto added a comment.

Remove trailing space as well


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121627

Files:
  llvm/lib/Transforms/IPO/IROutliner.cpp


Index: llvm/lib/Transforms/IPO/IROutliner.cpp
===
--- llvm/lib/Transforms/IPO/IROutliner.cpp
+++ llvm/lib/Transforms/IPO/IROutliner.cpp
@@ -1554,12 +1554,12 @@
 /// function.
 ///
 /// \param PN [in] - The PHINode that we are finding the canonical numbers for.
-/// \param Region [in] - The OutlinableRegion containing \p PN. 
+/// \param Region [in] - The OutlinableRegion containing \p PN.
 /// \param OverallPhiBlock [in] - The overall PHIBlock we are trying to find
 /// \p PN in.
 /// \param OutputMappings [in] - The mapping of output values from outlined
 /// region to their original values.
-/// \param UsedPhis [in, out] - The PHINodes in the block that have already 
been
+/// \param UsedPHIs [in, out] - The PHINodes in the block that have already 
been
 /// matched.
 /// \return the newly found or created PHINode in \p OverallPhiBlock.
 static PHINode*


Index: llvm/lib/Transforms/IPO/IROutliner.cpp
===
--- llvm/lib/Transforms/IPO/IROutliner.cpp
+++ llvm/lib/Transforms/IPO/IROutliner.cpp
@@ -1554,12 +1554,12 @@
 /// function.
 ///
 /// \param PN [in] - The PHINode that we are finding the canonical numbers for.
-/// \param Region [in] - The OutlinableRegion containing \p PN. 
+/// \param Region [in] - The OutlinableRegion containing \p PN.
 /// \param OverallPhiBlock [in] - The overall PHIBlock we are trying to find
 /// \p PN in.
 /// \param OutputMappings [in] - The mapping of output values from outlined
 /// region to their original values.
-/// \param UsedPhis [in, out] - The PHINodes in the block that have already been
+/// \param UsedPHIs [in, out] - The PHINodes in the block that have already been
 /// matched.
 /// \return the newly found or created PHINode in \p OverallPhiBlock.
 static PHINode*
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122102: [clangd] Introduce "add subclass" tweak

2022-03-20 Thread Adrian Vogelsgesang via Phabricator via cfe-commits
avogelsgesang added reviewers: sammccall, nridge, njames93, hokein.
avogelsgesang added a comment.




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122102

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


[PATCH] D121627: [IROutliner][NFC] Fix typo in doc of findOrCreatePHIInBlock

2022-03-20 Thread Hirochika Matsumoto via Phabricator via cfe-commits
hkmatsumoto added a comment.

Ping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D121627

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


[PATCH] D122102: [clangd] Introduce "add subclass" tweak

2022-03-20 Thread Adrian Vogelsgesang via Phabricator via cfe-commits
avogelsgesang created this revision.
Herald added subscribers: usaxena95, kadircet, arphaman, mgorny.
Herald added a project: All.
avogelsgesang requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

This commit adds a new "add subclass" tweak which facilitates quick
scaffolding of inheritance hierarchies. The tweak can be triggered
on any class with virtual methods. It then inserts a new subclass
which overrides all virtual methods with dummy implementations.

There are two variations of this tweak:

1. A variant which overrides all virtual functions
2. A variant which overrides only pure virtual functions

This tweak also supports deeper inheritance hierarchies, and collects
the methods to be overriden not only from the immediate base class but
from the complete inheritance tree.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122102

Files:
  clang-tools-extra/clangd/AST.cpp
  clang-tools-extra/clangd/AST.h
  clang-tools-extra/clangd/refactor/InsertionPoint.cpp
  clang-tools-extra/clangd/refactor/tweaks/AddSubclass.cpp
  clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt
  clang-tools-extra/clangd/unittests/CMakeLists.txt
  clang-tools-extra/clangd/unittests/tweaks/AddSubclassTests.cpp

Index: clang-tools-extra/clangd/unittests/tweaks/AddSubclassTests.cpp
===
--- /dev/null
+++ clang-tools-extra/clangd/unittests/tweaks/AddSubclassTests.cpp
@@ -0,0 +1,526 @@
+//===-- AddSubclassTests.cpp *- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "Annotations.h"
+#include "TweakTesting.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+TWEAK_TEST(AddSubclassAllVirtuals);
+
+TEST_F(AddSubclassAllVirtualsTest, Prepare) {
+  // Not available if there are no virtual function
+  EXPECT_UNAVAILABLE("^struct ^Base { void foo(); };");
+  // Available on virtual functions
+  EXPECT_AVAILABLE("^struct ^Base { virtual void foo(); };");
+  // Available on pure virtual functions
+  EXPECT_AVAILABLE("^struct ^Base { virtual void foo() = 0; };");
+  // Available for inherited virtual functions
+  EXPECT_AVAILABLE(R"cpp(
+struct Base { virtual void foo() = 0; };
+^struct ^Intermediate : public Base {};
+)cpp");
+  // Available for inherited virtual functions, even if already overriden
+  EXPECT_AVAILABLE(R"cpp(
+struct Base { virtual void foo() = 0; };
+^struct ^Intermediate : public Base { void foo() override; };
+)cpp");
+}
+
+TEST_F(AddSubclassAllVirtualsTest, ApplyInDifferenctScopes) {
+  struct {
+llvm::StringRef TestSource;
+llvm::StringRef ExpectedSource;
+  } Cases[]{
+  // Basic case, outside any namespace
+  {
+  R"cpp(
+struct ^Base { virtual int foo() = 0; };
+)cpp",
+  R"cpp(
+struct Base { virtual int foo() = 0; };
+
+struct BaseSub : public Base {
+  using Base::Base;
+  int foo() override { return Base::foo(); }
+};
+)cpp",
+  },
+  // Inserted between two classes
+  {
+  R"cpp(
+struct ^Base { virtual int foo() = 0; };
+struct OtherStruct {};
+)cpp",
+  R"cpp(
+struct Base { virtual int foo() = 0; };
+
+struct BaseSub : public Base {
+  using Base::Base;
+  int foo() override { return Base::foo(); }
+};
+struct OtherStruct {};
+)cpp",
+  },
+  // Inside a namespace
+  {
+  R"cpp(
+namespace NS {
+struct ^Base { virtual int foo() = 0; };
+})cpp",
+  R"cpp(
+namespace NS {
+struct Base { virtual int foo() = 0; };
+
+struct BaseSub : public Base {
+  using Base::Base;
+  int foo() override { return Base::foo(); }
+};
+})cpp",
+  },
+  // Inside an outer class
+  {
+  R"cpp(
+struct Outer {
+struct ^Base { virtual int foo() = 0; };
+};)cpp",
+  R"cpp(
+struct Outer {
+struct Base { virtual int foo() = 0; };
+
+struct BaseSub : public Base {
+  using Base::Base;
+  int foo() override { return Base::foo(); }
+};
+};)cpp",
+  },
+  // Chooses a fresh unused name
+  {
+  R"cpp(
+struct ^Base { virtual int foo() = 0; };
+struct BaseSub;
+struct BaseSub1;
+struct BaseSub2;
+struct BaseSub4;
+)cpp",
+  R"cpp(
+struct Base { virtual int foo() = 0; };
+
+struct BaseSub3 : public Base {
+  using Base::Base;
+  int foo() override { return Base::foo(); }
+};
+struct BaseSub;
+struct BaseSub1;
+struct BaseSub2;
+struct BaseSub4;
+)cpp",
+  },
+  // Does not accidentally collide with a comment on the last line
+  // of the file without a newline.
+  {
+  R"cpp(
+struct ^Base { virtual int foo() = 0; };
+// Some comment...)cpp",
+

[PATCH] D122101: [clangd] Simplify `insertDecl` and support insertion after the last declaration in a file

2022-03-20 Thread Adrian Vogelsgesang via Phabricator via cfe-commits
avogelsgesang created this revision.
Herald added subscribers: usaxena95, kadircet, arphaman.
Herald added a project: All.
avogelsgesang requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

So far `insertDecl`, did not support insertion of new code after the
last top-level declaration in a file. This was, because a
`TranslationUnitDecl` does not have a valid `getEndLoc()`.

Also, the logic of `Anchor::Below` was somewhat surprising: I would have
expected `Below` to insert below the first match. Instead it insert
after the first contigous run of matches. I found this highly
unintuitive, and replaced it by an additional optional `First`/`Last`
flag which can be specified for an anchor.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122101

Files:
  clang-tools-extra/clangd/refactor/InsertionPoint.cpp
  clang-tools-extra/clangd/refactor/InsertionPoint.h
  clang-tools-extra/clangd/unittests/InsertionPointTests.cpp

Index: clang-tools-extra/clangd/unittests/InsertionPointTests.cpp
===
--- clang-tools-extra/clangd/unittests/InsertionPointTests.cpp
+++ clang-tools-extra/clangd/unittests/InsertionPointTests.cpp
@@ -29,7 +29,7 @@
 $b^// leading comment
 int b;
 $c^int c1; // trailing comment
-int c2;
+$c2^int c2;
 $a2^int a2;
   $end^};
   )cpp");
@@ -47,18 +47,24 @@
   auto  = cast(findDecl(AST, "ns"));
 
   // Test single anchors.
-  auto Point = [&](llvm::StringLiteral Prefix, Anchor::Dir Direction) {
-auto Loc = insertionPoint(NS, {Anchor{StartsWith(Prefix), Direction}});
+  auto Point = [&](llvm::StringLiteral Prefix, Anchor::Dir Direction,
+   Anchor::SearchDir SearchDirection = Anchor::First) {
+auto Loc = insertionPoint(
+NS, {Anchor{StartsWith(Prefix), Direction, SearchDirection}});
 return sourceLocToPosition(AST.getSourceManager(), Loc);
   };
   EXPECT_EQ(Point("a", Anchor::Above), Code.point("a"));
   EXPECT_EQ(Point("a", Anchor::Below), Code.point("b"));
   EXPECT_EQ(Point("b", Anchor::Above), Code.point("b"));
   EXPECT_EQ(Point("b", Anchor::Below), Code.point("c"));
-  EXPECT_EQ(Point("c", Anchor::Above), Code.point("c"));
-  EXPECT_EQ(Point("c", Anchor::Below), Code.point("a2"));
+  EXPECT_EQ(Point("c", Anchor::Above, Anchor::First), Code.point("c"));
+  EXPECT_EQ(Point("c", Anchor::Below, Anchor::First), Code.point("c2"));
+  EXPECT_EQ(Point("c", Anchor::Above, Anchor::Last), Code.point("c2"));
+  EXPECT_EQ(Point("c", Anchor::Below, Anchor::Last), Code.point("a2"));
+  EXPECT_EQ(Point("a2", Anchor::Above), Code.point("a2"));
+  EXPECT_EQ(Point("a2", Anchor::Below), Code.point("end"));
   EXPECT_EQ(Point("", Anchor::Above), Code.point("a"));
-  EXPECT_EQ(Point("", Anchor::Below), Code.point("end"));
+  EXPECT_EQ(Point("", Anchor::Below), Code.point("b"));
   EXPECT_EQ(Point("no_match", Anchor::Below), Position{});
 
   // Test anchor chaining.
@@ -83,6 +89,35 @@
 Code.point("end"));
 }
 
+TEST(InsertionPointTests, TopLevel) {
+  Annotations Code(R"cpp(
+  $a^int a;
+  $b^int b;
+  $end^)cpp");
+
+  auto HasName =
+  [&](llvm::StringLiteral S) -> std::function {
+return [S](const Decl *D) {
+  if (const auto *ND = llvm::dyn_cast(D))
+return ND->getNameAsString() == S;
+  return false;
+};
+  };
+
+  auto AST = TestTU::withCode(Code.code()).build();
+  auto  = *AST.getASTContext().getTranslationUnitDecl();
+
+  // Test single anchors.
+  auto Point = [&](llvm::StringLiteral Prefix, Anchor::Dir Direction) {
+auto Loc = insertionPoint(TUD, {Anchor{HasName(Prefix), Direction}});
+return sourceLocToPosition(AST.getSourceManager(), Loc);
+  };
+  EXPECT_EQ(Point("a", Anchor::Above), Code.point("a"));
+  EXPECT_EQ(Point("a", Anchor::Below), Code.point("b"));
+  EXPECT_EQ(Point("b", Anchor::Above), Code.point("b"));
+  EXPECT_EQ(Point("b", Anchor::Below), Code.point("end"));
+}
+
 // For CXX, we should check:
 // - special handling for access specifiers
 // - unwrapping of template decls
@@ -96,7 +131,7 @@
 $private^private:
   $field^int PrivField;
   $method^void privMethod();
-  template  void privTemplateMethod();
+  $template^template  void privTemplateMethod();
 $end^};
   )cpp");
 
@@ -114,11 +149,12 @@
   EXPECT_EQ(Point({IsMethod, Anchor::Above}, AS_public), Code.point("Method"));
   EXPECT_EQ(Point({IsMethod, Anchor::Below}, AS_public), Code.point("Field"));
   EXPECT_EQ(Point({Any, Anchor::Above}, AS_public), Code.point("Method"));
-  EXPECT_EQ(Point({Any, Anchor::Below}, AS_public), Code.point("private"));
+  EXPECT_EQ(Point({Any, Anchor::Below}, AS_public), Code.point("Method"));
   EXPECT_EQ(Point({IsMethod, Anchor::Above}, AS_private), Code.point("method"));
-  EXPECT_EQ(Point({IsMethod, Anchor::Below}, AS_private), Code.point("end"));
+  EXPECT_EQ(Point({IsMethod, Anchor::Below}, 

[PATCH] D122077: [InstCombine] Fold (ctpop(X) == 1) | (X == 0) into ctpop(X) < 2

2022-03-20 Thread Hirochika Matsumoto via Phabricator via cfe-commits
hkmatsumoto added inline comments.



Comment at: llvm/test/Transforms/InstCombine/ispow2.ll:538
 
 ; Negative test - wrong predicate (but this could reduce).
 

xbolva00 wrote:
> hkmatsumoto wrote:
> > xbolva00 wrote:
> > > Now reduced.
> > Since this is almost the first time contributing to LLVM, I'm not sure what 
> > I should do about this. Does it mean we should remove these reduced tests?
> just remove "(but this could reduce)" from the comment I think.
I get it, thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122077

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


[PATCH] D122077: [InstCombine] Fold (ctpop(X) == 1) | (X == 0) into ctpop(X) < 2

2022-03-20 Thread Hirochika Matsumoto via Phabricator via cfe-commits
hkmatsumoto updated this revision to Diff 416763.
hkmatsumoto added a comment.

Address code review, removing "but this could reduce" from comment


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122077

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  llvm/test/Transforms/InstCombine/icmp-or.ll
  llvm/test/Transforms/InstCombine/ispow2.ll

Index: llvm/test/Transforms/InstCombine/ispow2.ll
===
--- llvm/test/Transforms/InstCombine/ispow2.ll
+++ llvm/test/Transforms/InstCombine/ispow2.ll
@@ -535,15 +535,13 @@
   ret i1 %r
 }
 
-; Negative test - wrong predicate (but this could reduce).
+; Negative test - wrong predicate.
 
 define i1 @isnot_pow2_ctpop_wrong_pred1(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred1(
 ; CHECK-NEXT:[[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range [[RNG0]]
-; CHECK-NEXT:[[CMP:%.*]] = icmp eq i32 [[T0]], 1
-; CHECK-NEXT:[[ISZERO:%.*]] = icmp eq i32 [[X]], 0
-; CHECK-NEXT:[[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
-; CHECK-NEXT:ret i1 [[R]]
+; CHECK-NEXT:[[TMP1:%.*]] = icmp ult i32 [[T0]], 2
+; CHECK-NEXT:ret i1 [[TMP1]]
 ;
   %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
   %cmp = icmp eq i32 %t0, 1
@@ -555,10 +553,8 @@
 define i1 @isnot_pow2_ctpop_wrong_pred1_logical(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred1_logical(
 ; CHECK-NEXT:[[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range [[RNG0]]
-; CHECK-NEXT:[[CMP:%.*]] = icmp eq i32 [[T0]], 1
-; CHECK-NEXT:[[ISZERO:%.*]] = icmp eq i32 [[X]], 0
-; CHECK-NEXT:[[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
-; CHECK-NEXT:ret i1 [[R]]
+; CHECK-NEXT:[[TMP1:%.*]] = icmp ult i32 [[T0]], 2
+; CHECK-NEXT:ret i1 [[TMP1]]
 ;
   %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
   %cmp = icmp eq i32 %t0, 1
Index: llvm/test/Transforms/InstCombine/icmp-or.ll
===
--- llvm/test/Transforms/InstCombine/icmp-or.ll
+++ llvm/test/Transforms/InstCombine/icmp-or.ll
@@ -363,3 +363,131 @@
   %r = icmp sgt i8 %or, -1
   ret i1 %r
 }
+
+declare i32 @llvm.ctpop.i32(i32)
+
+; (icmp eq ctpop(X) 1) | (icmp eq X 0) --> icmp ult ctpop(X) 2
+
+define i1 @ctpop_or_eq_to_ctpop(i32 %0) {
+; CHECK-LABEL: @ctpop_or_eq_to_ctpop(
+; CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.ctpop.i32(i32 [[TMP0:%.*]]), !range [[RNG0:![0-9]+]]
+; CHECK-NEXT:[[TMP3:%.*]] = icmp ult i32 [[TMP2]], 2
+; CHECK-NEXT:ret i1 [[TMP3]]
+;
+  %2 = call i32 @llvm.ctpop.i32(i32 %0)
+  %3 = icmp eq i32 %2, 1
+  %4 = icmp eq i32 %0, 0
+  %5 = or i1 %4, %3
+  ret i1 %5
+}
+
+; negative test - wrong constants
+
+define i1 @not_ctpop_or_eq_to_ctpop(i32 %0) {
+; CHECK-LABEL: @not_ctpop_or_eq_to_ctpop(
+; CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.ctpop.i32(i32 [[TMP0:%.*]]), !range [[RNG0]]
+; CHECK-NEXT:[[TMP3:%.*]] = icmp eq i32 [[TMP2]], 2
+; CHECK-NEXT:[[TMP4:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT:[[TMP5:%.*]] = or i1 [[TMP4]], [[TMP3]]
+; CHECK-NEXT:ret i1 [[TMP5]]
+;
+  %2 = call i32 @llvm.ctpop.i32(i32 %0)
+  %3 = icmp eq i32 %2, 2
+  %4 = icmp eq i32 %0, 0
+  %5 = or i1 %4, %3
+  ret i1 %5
+}
+
+declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>)
+
+define <2 x i1> @ctpop_or_eq_to_ctpop_vec(<2 x i32> %0) {
+; CHECK-LABEL: @ctpop_or_eq_to_ctpop_vec(
+; CHECK-NEXT:[[TMP2:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[TMP0:%.*]])
+; CHECK-NEXT:[[TMP3:%.*]] = icmp ult <2 x i32> [[TMP2]], 
+; CHECK-NEXT:ret <2 x i1> [[TMP3]]
+;
+  %2 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %0)
+  %3 = icmp eq <2 x i32> %2, 
+  %4 = icmp eq <2 x i32> %0, 
+  %5 = or <2 x i1> %4, %3
+  ret <2 x i1> %5
+}
+
+; negative test - wrong constants
+
+define <2 x i1> @not_ctpop_or_eq_to_ctpop_vec(<2 x i32> %0) {
+; CHECK-LABEL: @not_ctpop_or_eq_to_ctpop_vec(
+; CHECK-NEXT:[[TMP2:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[TMP0:%.*]])
+; CHECK-NEXT:[[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], 
+; CHECK-NEXT:[[TMP4:%.*]] = icmp eq <2 x i32> [[TMP0]], zeroinitializer
+; CHECK-NEXT:[[TMP5:%.*]] = or <2 x i1> [[TMP4]], [[TMP3]]
+; CHECK-NEXT:ret <2 x i1> [[TMP5]]
+;
+  %2 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %0)
+  %3 = icmp eq <2 x i32> %2, 
+  %4 = icmp eq <2 x i32> %0, 
+  %5 = or <2 x i1> %4, %3
+  ret <2 x i1> %5
+}
+
+; (icmp ne ctpop(X) 1) & (icmp ne X 0) --> icmp uge ctpop(X) 2
+
+define i1 @ctpop_and_ne_to_ctpop(i32 %0) {
+; CHECK-LABEL: @ctpop_and_ne_to_ctpop(
+; CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.ctpop.i32(i32 [[TMP0:%.*]]), !range [[RNG0]]
+; CHECK-NEXT:[[TMP3:%.*]] = icmp ugt i32 [[TMP2]], 1
+; CHECK-NEXT:ret i1 [[TMP3]]
+;
+  %2 = call i32 @llvm.ctpop.i32(i32 %0)
+  %3 = icmp ne i32 %2, 1
+  %4 = icmp ne i32 %0, 0
+  %5 = and i1 %4, %3
+  ret i1 %5
+}
+
+; negative test - wrong constants
+
+define i1 

[PATCH] D122077: [InstCombine] Fold (ctpop(X) == 1) | (X == 0) into ctpop(X) < 2

2022-03-20 Thread Dávid Bolvanský via Phabricator via cfe-commits
xbolva00 added inline comments.



Comment at: llvm/test/Transforms/InstCombine/ispow2.ll:538
 
 ; Negative test - wrong predicate (but this could reduce).
 

hkmatsumoto wrote:
> xbolva00 wrote:
> > Now reduced.
> Since this is almost the first time contributing to LLVM, I'm not sure what I 
> should do about this. Does it mean we should remove these reduced tests?
just remove "(but this could reduce)" from the comment I think.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122077

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


[PATCH] D54943: [clang-tidy] implement const-transformation for cppcoreguidelines-const-correctness

2022-03-20 Thread Jonas Toth via Phabricator via cfe-commits
JonasToth added a comment.

ping @aaron.ballman @njames93 :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D54943

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


[PATCH] D122077: [InstCombine] Fold (ctpop(X) == 1) | (X == 0) into ctpop(X) < 2

2022-03-20 Thread Hirochika Matsumoto via Phabricator via cfe-commits
hkmatsumoto added inline comments.



Comment at: llvm/test/Transforms/InstCombine/ispow2.ll:538
 
 ; Negative test - wrong predicate (but this could reduce).
 

xbolva00 wrote:
> Now reduced.
Since this is almost the first time contributing to LLVM, I'm not sure what I 
should do about this. Does it mean we should remove these reduced tests?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122077

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


[PATCH] D122077: [InstCombine] Fold (ctpop(X) == 1) | (X == 0) into ctpop(X) < 2

2022-03-20 Thread Hirochika Matsumoto via Phabricator via cfe-commits
hkmatsumoto updated this revision to Diff 416762.
hkmatsumoto added a comment.

Address code reviews

- Fold (icmp ne ctpop(X) 1) & (icmp ne X 0) into (icmp ugt ctpop(X) 1) as well

foldOrOfCtpop folds the aforementioned pattern into (icmp **uge** ctpop(X) 2)
and that is later transformed into (icmp ugt ctpop(X) 1). I think this is fine.

- Add tests for vector type


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122077

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  llvm/test/Transforms/InstCombine/icmp-or.ll
  llvm/test/Transforms/InstCombine/ispow2.ll

Index: llvm/test/Transforms/InstCombine/ispow2.ll
===
--- llvm/test/Transforms/InstCombine/ispow2.ll
+++ llvm/test/Transforms/InstCombine/ispow2.ll
@@ -540,10 +540,8 @@
 define i1 @isnot_pow2_ctpop_wrong_pred1(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred1(
 ; CHECK-NEXT:[[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range [[RNG0]]
-; CHECK-NEXT:[[CMP:%.*]] = icmp eq i32 [[T0]], 1
-; CHECK-NEXT:[[ISZERO:%.*]] = icmp eq i32 [[X]], 0
-; CHECK-NEXT:[[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
-; CHECK-NEXT:ret i1 [[R]]
+; CHECK-NEXT:[[TMP1:%.*]] = icmp ult i32 [[T0]], 2
+; CHECK-NEXT:ret i1 [[TMP1]]
 ;
   %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
   %cmp = icmp eq i32 %t0, 1
@@ -555,10 +553,8 @@
 define i1 @isnot_pow2_ctpop_wrong_pred1_logical(i32 %x) {
 ; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred1_logical(
 ; CHECK-NEXT:[[T0:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range [[RNG0]]
-; CHECK-NEXT:[[CMP:%.*]] = icmp eq i32 [[T0]], 1
-; CHECK-NEXT:[[ISZERO:%.*]] = icmp eq i32 [[X]], 0
-; CHECK-NEXT:[[R:%.*]] = or i1 [[ISZERO]], [[CMP]]
-; CHECK-NEXT:ret i1 [[R]]
+; CHECK-NEXT:[[TMP1:%.*]] = icmp ult i32 [[T0]], 2
+; CHECK-NEXT:ret i1 [[TMP1]]
 ;
   %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)
   %cmp = icmp eq i32 %t0, 1
Index: llvm/test/Transforms/InstCombine/icmp-or.ll
===
--- llvm/test/Transforms/InstCombine/icmp-or.ll
+++ llvm/test/Transforms/InstCombine/icmp-or.ll
@@ -363,3 +363,131 @@
   %r = icmp sgt i8 %or, -1
   ret i1 %r
 }
+
+declare i32 @llvm.ctpop.i32(i32)
+
+; (icmp eq ctpop(X) 1) | (icmp eq X 0) --> icmp ult ctpop(X) 2
+
+define i1 @ctpop_or_eq_to_ctpop(i32 %0) {
+; CHECK-LABEL: @ctpop_or_eq_to_ctpop(
+; CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.ctpop.i32(i32 [[TMP0:%.*]]), !range [[RNG0:![0-9]+]]
+; CHECK-NEXT:[[TMP3:%.*]] = icmp ult i32 [[TMP2]], 2
+; CHECK-NEXT:ret i1 [[TMP3]]
+;
+  %2 = call i32 @llvm.ctpop.i32(i32 %0)
+  %3 = icmp eq i32 %2, 1
+  %4 = icmp eq i32 %0, 0
+  %5 = or i1 %4, %3
+  ret i1 %5
+}
+
+; negative test - wrong constants
+
+define i1 @not_ctpop_or_eq_to_ctpop(i32 %0) {
+; CHECK-LABEL: @not_ctpop_or_eq_to_ctpop(
+; CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.ctpop.i32(i32 [[TMP0:%.*]]), !range [[RNG0]]
+; CHECK-NEXT:[[TMP3:%.*]] = icmp eq i32 [[TMP2]], 2
+; CHECK-NEXT:[[TMP4:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT:[[TMP5:%.*]] = or i1 [[TMP4]], [[TMP3]]
+; CHECK-NEXT:ret i1 [[TMP5]]
+;
+  %2 = call i32 @llvm.ctpop.i32(i32 %0)
+  %3 = icmp eq i32 %2, 2
+  %4 = icmp eq i32 %0, 0
+  %5 = or i1 %4, %3
+  ret i1 %5
+}
+
+declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>)
+
+define <2 x i1> @ctpop_or_eq_to_ctpop_vec(<2 x i32> %0) {
+; CHECK-LABEL: @ctpop_or_eq_to_ctpop_vec(
+; CHECK-NEXT:[[TMP2:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[TMP0:%.*]])
+; CHECK-NEXT:[[TMP3:%.*]] = icmp ult <2 x i32> [[TMP2]], 
+; CHECK-NEXT:ret <2 x i1> [[TMP3]]
+;
+  %2 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %0)
+  %3 = icmp eq <2 x i32> %2, 
+  %4 = icmp eq <2 x i32> %0, 
+  %5 = or <2 x i1> %4, %3
+  ret <2 x i1> %5
+}
+
+; negative test - wrong constants
+
+define <2 x i1> @not_ctpop_or_eq_to_ctpop_vec(<2 x i32> %0) {
+; CHECK-LABEL: @not_ctpop_or_eq_to_ctpop_vec(
+; CHECK-NEXT:[[TMP2:%.*]] = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[TMP0:%.*]])
+; CHECK-NEXT:[[TMP3:%.*]] = icmp eq <2 x i32> [[TMP2]], 
+; CHECK-NEXT:[[TMP4:%.*]] = icmp eq <2 x i32> [[TMP0]], zeroinitializer
+; CHECK-NEXT:[[TMP5:%.*]] = or <2 x i1> [[TMP4]], [[TMP3]]
+; CHECK-NEXT:ret <2 x i1> [[TMP5]]
+;
+  %2 = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %0)
+  %3 = icmp eq <2 x i32> %2, 
+  %4 = icmp eq <2 x i32> %0, 
+  %5 = or <2 x i1> %4, %3
+  ret <2 x i1> %5
+}
+
+; (icmp ne ctpop(X) 1) & (icmp ne X 0) --> icmp uge ctpop(X) 2
+
+define i1 @ctpop_and_ne_to_ctpop(i32 %0) {
+; CHECK-LABEL: @ctpop_and_ne_to_ctpop(
+; CHECK-NEXT:[[TMP2:%.*]] = call i32 @llvm.ctpop.i32(i32 [[TMP0:%.*]]), !range [[RNG0]]
+; CHECK-NEXT:[[TMP3:%.*]] = icmp ugt i32 [[TMP2]], 1
+; CHECK-NEXT:ret i1 [[TMP3]]
+;
+  %2 = call i32 @llvm.ctpop.i32(i32 %0)
+  %3 = icmp ne i32 %2, 1
+  %4 = icmp ne 

[PATCH] D111400: [Clang][C++2b] P2242R3: Non-literal variables [...] in constexpr

2022-03-20 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added inline comments.



Comment at: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp:17-22
+constexpr int g() { // expected-error {{constexpr function never produces a 
constant expression}}
+  goto test;// expected-note {{subexpression not valid in a constant 
expression}} \
+   // expected-warning {{use of this statement in a constexpr function 
is incompatible with C++ standards before C++2b}}
+test:
+  return 0;
+}

hubert.reinterpretcast wrote:
> Still trying to make the choice of tests consistent between the different 
> cases (static local variable, goto statement, etc.) and consistent within 
> files...
> 
> The test that is here (function will unconditionally evaluate) seems to 
> belong in `constant-expression-cxx2b.cpp`... or at least that is where the 
> equivalent tests for the static local variable case, etc. is (and correctly, 
> I think).
> 
> The test that should be here is the "conditionally will evaluate" case where 
> the function is not called. That is, this file has tests that check that the 
> warnings are produced purely from the definition being present.
I'm not sure I understand. No call is made in that file.



Comment at: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp:16
+}
+
+constexpr int f(int x) {

hubert.reinterpretcast wrote:
> Add a `NonLiteral` case and a case with a labelled statement and no `goto`?
These tests exist in that same file



Comment at: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp:1-3
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu 
-std=c++11 -Werror=c++14-extensions -Werror=c++20-extensions 
-Werror=c++2b-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu 
-std=c++14 -DCXX14 -Werror=c++20-extensions -Werror=c++2b-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu 
-std=c++20 -DCXX14 -DCXX20 -Werror=c++2b-extensions %s

hubert.reinterpretcast wrote:
> hubert.reinterpretcast wrote:
> > cor3ntin wrote:
> > > hubert.reinterpretcast wrote:
> > > > The use `-Werror` hides potential issues where the error is 
> > > > categorically produced (instead of under the warning group).
> > > > 
> > > > Considering that there is a relevant design consistency issue of 
> > > > exactly that sort right now that this test could have highlighted (but 
> > > > didn't), a change to stop using `-Werror` may be prudent.
> > > This seems inconsistent with how that file is currently structured though
> > I meant to change the entire file to check for warnings instead of errors. 
> > I guess that really should be a separate patch.
> I guess the change will cause the "never produces a constant expression" 
> warning unless if that is suppressed with `-Wno-invalid-constexpr`.
Yes, we could cleanup this entire file to get rid of the #ifdef, then change 
how warnings are diagnosed.



Comment at: clang/test/SemaCXX/constant-expression-cxx2b.cpp:96-123
+int test_in_lambdas() {
+  auto a = [] constexpr {// expected-error{{constexpr function never 
produces a constant expression}}
+static const int m = 32; // expected-note {{control flows through the 
declaration of a static variable}} \
+ // expected-warning {{incompatible with C++ 
standards before C++2b}}
+return m;
+  };
+

hubert.reinterpretcast wrote:
> I think it would be more meaningful to have the explicitly `constexpr` lambda 
> tests in the file (see comment on the later code below) that also runs under 
> C++20 mode. The tests should be structured to demonstrate that the explicitly 
> `constexpr` lambdas are usable in constant expression evaluation even in 
> older modes.
That would just test the extension warnings which we already tests a bunch of 
time. I'm willing to add more tests but I question whether it would had any 
value


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111400

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


[PATCH] D111400: [Clang][C++2b] P2242R3: Non-literal variables [...] in constexpr

2022-03-20 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 416760.
cor3ntin added a comment.

Add a test for evaluated labels


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111400

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constant-expression-cxx14.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1361,7 +1361,7 @@
 
   Non-literal variables (and labels and gotos) in constexpr functions
   https://wg21.link/P2242R3;>P2242R3
-  No
+  Clang 15
 
 
   Character encoding of diagnostic text
Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -0,0 +1,215 @@
+// RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++2b-compat
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2b %s -fcxx-exceptions -triple=x86_64-linux-gnu
+
+struct NonLiteral {
+  NonLiteral() {}
+};
+
+#if __cplusplus > 202002
+
+constexpr int f(int n) {  // expected-error {{constexpr function never produces a constant expression}}
+  static const int m = n; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return m;
+}
+constexpr int g(int n) {// expected-error {{constexpr function never produces a constant expression}}
+  thread_local const int m = n; // expected-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+  return m;
+}
+
+constexpr int h(int n) {  // expected-error {{constexpr function never produces a constant expression}}
+  static const int m = n; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return  - 
+}
+constexpr int i(int n) {// expected-error {{constexpr function never produces a constant expression}}
+  thread_local const int m = n; // expected-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+  return  - 
+}
+
+constexpr int j(int n) {
+  if (!n)
+return 0;
+  static const int m = n; // expected-warning{{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
+  return m;
+}
+constexpr int j0 = j(0);
+
+constexpr int k(int n) {
+  if (!n)
+return 0;
+  thread_local const int m = n; // expected-warning{{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
+
+  return m;
+}
+constexpr int k0 = k(0);
+
+constexpr int j_evaluated(int n) {
+  if (!n)
+return 0;
+  static const int m = n; // expected-warning{{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return m;
+}
+
+constexpr int je = j_evaluated(1); // expected-error {{constexpr variable 'je' must be initialized by a constant expression}}  \
+   // expected-note {{in call}}
+
+constexpr int k_evaluated(int n) {
+  if (!n)
+return 0;
+  thread_local const int m = n; // expected-warning{{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+
+  return m;
+}
+
+constexpr int ke = k_evaluated(1); // expected-error {{constexpr variable 'ke' must be initialized by a constant expression}} \
+   // expected-note {{in call}}
+
+constexpr int 

[PATCH] D111400: [Clang][C++2b] P2242R3: Non-literal variables [...] in constexpr

2022-03-20 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 416758.
cor3ntin marked 2 inline comments as done.
cor3ntin added a comment.

- fix typos
- add tests for non-literals in lambdas
- run lambda tests in c++20 mode


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111400

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/SemaCXX/constant-expression-cxx14.cpp
  clang/test/SemaCXX/constant-expression-cxx2b.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1361,7 +1361,7 @@
 
   Non-literal variables (and labels and gotos) in constexpr functions
   https://wg21.link/P2242R3;>P2242R3
-  No
+  Clang 15
 
 
   Character encoding of diagnostic text
Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/constant-expression-cxx2b.cpp
@@ -0,0 +1,205 @@
+// RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx2a %s -fcxx-exceptions -triple=x86_64-linux-gnu -Wpre-c++2b-compat
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx2b %s -fcxx-exceptions -triple=x86_64-linux-gnu
+
+struct NonLiteral {
+  NonLiteral() {}
+};
+
+#if __cplusplus > 202002
+
+constexpr int f(int n) {  // expected-error {{constexpr function never produces a constant expression}}
+  static const int m = n; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return m;
+}
+constexpr int g(int n) {// expected-error {{constexpr function never produces a constant expression}}
+  thread_local const int m = n; // expected-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+  return m;
+}
+
+constexpr int h(int n) {  // expected-error {{constexpr function never produces a constant expression}}
+  static const int m = n; // expected-warning {{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return  - 
+}
+constexpr int i(int n) {// expected-error {{constexpr function never produces a constant expression}}
+  thread_local const int m = n; // expected-warning {{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+  return  - 
+}
+
+constexpr int j(int n) {
+  if (!n)
+return 0;
+  static const int m = n; // expected-warning{{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}}
+  return m;
+}
+constexpr int j0 = j(0);
+
+constexpr int k(int n) {
+  if (!n)
+return 0;
+  thread_local const int m = n; // expected-warning{{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}}
+
+  return m;
+}
+constexpr int k0 = k(0);
+
+constexpr int j_evaluated(int n) {
+  if (!n)
+return 0;
+  static const int m = n; // expected-warning{{definition of a static variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+  // expected-note {{control flows through the declaration of a static variable}}
+  return m;
+}
+
+constexpr int je = j_evaluated(1); // expected-error {{constexpr variable 'je' must be initialized by a constant expression}}  \
+   // expected-note {{in call}}
+
+constexpr int k_evaluated(int n) {
+  if (!n)
+return 0;
+  thread_local const int m = n; // expected-warning{{definition of a thread_local variable in a constexpr function is incompatible with C++ standards before C++2b}} \
+// expected-note {{control flows through the declaration of a thread_local variable}}
+
+  return m;
+}
+
+constexpr int ke = k_evaluated(1); // expected-error {{constexpr variable 'ke' must be initialized by a constant