[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-15 Thread Alexander Kornienko via Phabricator via cfe-commits
alexfh added a comment.

In D111283#3786678 , @mizvekov wrote:

> @alexfh This new revision that I just pushed should be good.
>
> Do you want to give it a look / test, or should we go ahead and merge it?

Thanks for the fix! If it fixes the test case I provided, that should be enough 
for now. If it breaks anything else, we'll find this out in a few days after 
you land the patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-15 Thread David Rector via Phabricator via cfe-commits
davrec added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12367
+  case Type::Class:
\
+llvm_unreachable("Unexpected " Kind ": " #Class);
+

aaronpuchert wrote:
> mizvekov wrote:
> > aaronpuchert wrote:
> > > mizvekov wrote:
> > > > davrec wrote:
> > > > > mizvekov wrote:
> > > > > > davrec wrote:
> > > > > > > mizvekov wrote:
> > > > > > > > davrec wrote:
> > > > > > > > > Could we just return `X` here? Would that just default to the 
> > > > > > > > > old behavior instead of crashing whenever unforeseen cases 
> > > > > > > > > arise?  
> > > > > > > > No, I think we should enforce the invariants and make sure we 
> > > > > > > > are handling everything that can be handled.
> > > > > > > > 
> > > > > > > > Classing `TemplateTypeParm`  as sugar-free was what was wrong 
> > > > > > > > and we missed this on the review.
> > > > > > > There might always going to be a few rare corner cases vulnerable 
> > > > > > > to this though, particularly as more types are added and the 
> > > > > > > people adding them don't pay strict attention to how to 
> > > > > > > incorporate them here, and don't write the requisite tests (which 
> > > > > > > seem very difficult to foresee and produce).  When those cases 
> > > > > > > arise we will be crashing even though we could produce a 
> > > > > > > perfectly good program with the intended semantics; the only 
> > > > > > > thing that would suffer for most users is slightly less clear 
> > > > > > > diagnostic messages for those rare cases.  I think it would be 
> > > > > > > better to let those cases gradually percolate to our attention 
> > > > > > > via bug reports concerning those diagnostics, rather than 
> > > > > > > inconveniencing the user and demanding immediate attention via 
> > > > > > > crashes.  Or am I missing something?
> > > > > > I could on the same argument remove all asserts here and just let 
> > > > > > the program not crash on unforeseen circumstances.
> > > > > > 
> > > > > > On the other hand, having these asserts here helps us catch bugs 
> > > > > > not only here, but in other parts of the code. For example uniquing 
> > > > > > / canonicalization bugs.
> > > > > > 
> > > > > > If someone changes the properties of a type so that the assumptions 
> > > > > > here are not valid anymore, it's helpful to have that pointed out 
> > > > > > soon.
> > > > > > 
> > > > > > Going for as an example this specific bug, if there werent those 
> > > > > > asserts / unreachables in place and we had weakened the validation 
> > > > > > here, it would take a very long time for us to figure out we were 
> > > > > > making the wrong assumption with regards to TemplateTypeParmType.
> > > > > > 
> > > > > > I'd rather figure that out sooner on CI / internal testing rather 
> > > > > > than have a bug created by a user two years from now.
> > > > > Yes its nicer to developers to get stack traces and reproductions 
> > > > > whenever something goes wrong, and crashing is a good way to get 
> > > > > those, but users probably won't be so thrilled about it.  Especially 
> > > > > given that the main selling point of this patch is that it makes 
> > > > > diagnostics nicer for users: isn't it a bit absurd to crash whenever 
> > > > > we can't guarantee our diagnostics will be perfect?
> > > > > 
> > > > > And again the real problem is future types not being properly 
> > > > > incorporated here and properly tested: i.e. the worry is that this 
> > > > > will be a continuing source of crashes, even if we handle all the 
> > > > > present types properly.
> > > > > 
> > > > > How about we leave it as an unreachable for now, to help ensure all 
> > > > > the present types are handled, but if months or years from now there 
> > > > > continue to be crashes due to this, then just return X (while maybe 
> > > > > write something to llvm::errs() to encourage users to report it), so 
> > > > > we don't make the perfect the enemy of the good.
> > > > It's not about crashing when it won't be perfect. We already do these 
> > > > kinds of things, see the FIXMEs around the TemplateArgument and 
> > > > NestedNameSpecifier, where we just return something worse than we wish 
> > > > to, just because we don't have time to implement it now.
> > > > 
> > > > These unreachables and asserts here are about testing / documenting our 
> > > > knowledge of the system and making it easier to find problems. These 
> > > > should be impossible to happen in correct code, and if they do happen 
> > > > because of mistakes, fixing them sooner is just going to save us 
> > > > resources.
> > > > 
> > > > `llvm::errs` suggestion I perceive as out of line with current practice 
> > > > in LLVM, we don't and have a system for producing diagnostics for 
> > > > results possibly affected by FIXME and TODO situations and the like, as 
> > > > far as I know, and I am not aware of any discussions 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-14 Thread Aaron Puchert via Phabricator via cfe-commits
aaronpuchert added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12367
+  case Type::Class:
\
+llvm_unreachable("Unexpected " Kind ": " #Class);
+

mizvekov wrote:
> aaronpuchert wrote:
> > mizvekov wrote:
> > > davrec wrote:
> > > > mizvekov wrote:
> > > > > davrec wrote:
> > > > > > mizvekov wrote:
> > > > > > > davrec wrote:
> > > > > > > > Could we just return `X` here? Would that just default to the 
> > > > > > > > old behavior instead of crashing whenever unforeseen cases 
> > > > > > > > arise?  
> > > > > > > No, I think we should enforce the invariants and make sure we are 
> > > > > > > handling everything that can be handled.
> > > > > > > 
> > > > > > > Classing `TemplateTypeParm`  as sugar-free was what was wrong and 
> > > > > > > we missed this on the review.
> > > > > > There might always going to be a few rare corner cases vulnerable 
> > > > > > to this though, particularly as more types are added and the people 
> > > > > > adding them don't pay strict attention to how to incorporate them 
> > > > > > here, and don't write the requisite tests (which seem very 
> > > > > > difficult to foresee and produce).  When those cases arise we will 
> > > > > > be crashing even though we could produce a perfectly good program 
> > > > > > with the intended semantics; the only thing that would suffer for 
> > > > > > most users is slightly less clear diagnostic messages for those 
> > > > > > rare cases.  I think it would be better to let those cases 
> > > > > > gradually percolate to our attention via bug reports concerning 
> > > > > > those diagnostics, rather than inconveniencing the user and 
> > > > > > demanding immediate attention via crashes.  Or am I missing 
> > > > > > something?
> > > > > I could on the same argument remove all asserts here and just let the 
> > > > > program not crash on unforeseen circumstances.
> > > > > 
> > > > > On the other hand, having these asserts here helps us catch bugs not 
> > > > > only here, but in other parts of the code. For example uniquing / 
> > > > > canonicalization bugs.
> > > > > 
> > > > > If someone changes the properties of a type so that the assumptions 
> > > > > here are not valid anymore, it's helpful to have that pointed out 
> > > > > soon.
> > > > > 
> > > > > Going for as an example this specific bug, if there werent those 
> > > > > asserts / unreachables in place and we had weakened the validation 
> > > > > here, it would take a very long time for us to figure out we were 
> > > > > making the wrong assumption with regards to TemplateTypeParmType.
> > > > > 
> > > > > I'd rather figure that out sooner on CI / internal testing rather 
> > > > > than have a bug created by a user two years from now.
> > > > Yes its nicer to developers to get stack traces and reproductions 
> > > > whenever something goes wrong, and crashing is a good way to get those, 
> > > > but users probably won't be so thrilled about it.  Especially given 
> > > > that the main selling point of this patch is that it makes diagnostics 
> > > > nicer for users: isn't it a bit absurd to crash whenever we can't 
> > > > guarantee our diagnostics will be perfect?
> > > > 
> > > > And again the real problem is future types not being properly 
> > > > incorporated here and properly tested: i.e. the worry is that this will 
> > > > be a continuing source of crashes, even if we handle all the present 
> > > > types properly.
> > > > 
> > > > How about we leave it as an unreachable for now, to help ensure all the 
> > > > present types are handled, but if months or years from now there 
> > > > continue to be crashes due to this, then just return X (while maybe 
> > > > write something to llvm::errs() to encourage users to report it), so we 
> > > > don't make the perfect the enemy of the good.
> > > It's not about crashing when it won't be perfect. We already do these 
> > > kinds of things, see the FIXMEs around the TemplateArgument and 
> > > NestedNameSpecifier, where we just return something worse than we wish 
> > > to, just because we don't have time to implement it now.
> > > 
> > > These unreachables and asserts here are about testing / documenting our 
> > > knowledge of the system and making it easier to find problems. These 
> > > should be impossible to happen in correct code, and if they do happen 
> > > because of mistakes, fixing them sooner is just going to save us 
> > > resources.
> > > 
> > > `llvm::errs` suggestion I perceive as out of line with current practice 
> > > in LLVM, we don't and have a system for producing diagnostics for results 
> > > possibly affected by FIXME and TODO situations and the like, as far as I 
> > > know, and I am not aware of any discussions in that direction. I expect a 
> > > lot of complexity and noise if we went this way.
> > > And I think this would have even less chance of working out if we started 
> > > 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-14 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 460021.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/utils/ci/buildkite-pipeline.yml

Index: libcxx/utils/ci/buildkite-pipeline.yml
===
--- libcxx/utils/ci/buildkite-pipeline.yml
+++ libcxx/utils/ci/buildkite-pipeline.yml
@@ -59,19 +59,6 @@
   limit: 2
 timeout_in_minutes: 120
 
-  - label: "Documentation"
-command: "libcxx/utils/ci/run-buildbot documentation"
-artifact_paths:
-  - "**/test-results.xml"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
   #
   # General testing with the default configuration, under all the supported
   # Standard modes, with Clang and GCC. This catches most issues upfront.
@@ -79,273 +66,6 @@
   #
   - wait
 
-  - label: "C++2b"
-command: "libcxx/utils/ci/run-buildbot generic-cxx2b"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++11"
-command: "libcxx/utils/ci/run-buildbot generic-cxx11"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++03"
-command: "libcxx/utils/ci/run-buildbot generic-cxx03"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "Modular build"
-command: "libcxx/utils/ci/run-buildbot generic-modules"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "GCC ${GCC_STABLE_VERSION} / C++latest"
-command: "libcxx/utils/ci/run-buildbot generic-gcc"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "gcc-${GCC_STABLE_VERSION}"
-CXX: "g++-${GCC_STABLE_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  #
-  # All other supported configurations of libc++.
-  #
-  - wait
-
-  - label: "C++20"
-command: "libcxx/utils/ci/run-buildbot generic-cxx20"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++17"
-command: "libcxx/utils/ci/run-buildbot generic-cxx17"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-# TODO (mordante) use head
-#CC: "clang-${LLVM_HEAD_VERSION}"
-#CXX: "clang++-${LLVM_HEAD_VERSION}"
-CC: "clang-15"
-CXX: "clang++-15"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-14 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 460010.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/utils/ci/buildkite-pipeline.yml

Index: libcxx/utils/ci/buildkite-pipeline.yml
===
--- libcxx/utils/ci/buildkite-pipeline.yml
+++ libcxx/utils/ci/buildkite-pipeline.yml
@@ -59,19 +59,6 @@
   limit: 2
 timeout_in_minutes: 120
 
-  - label: "Documentation"
-command: "libcxx/utils/ci/run-buildbot documentation"
-artifact_paths:
-  - "**/test-results.xml"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
   #
   # General testing with the default configuration, under all the supported
   # Standard modes, with Clang and GCC. This catches most issues upfront.
@@ -79,273 +66,6 @@
   #
   - wait
 
-  - label: "C++2b"
-command: "libcxx/utils/ci/run-buildbot generic-cxx2b"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++11"
-command: "libcxx/utils/ci/run-buildbot generic-cxx11"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++03"
-command: "libcxx/utils/ci/run-buildbot generic-cxx03"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "Modular build"
-command: "libcxx/utils/ci/run-buildbot generic-modules"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "GCC ${GCC_STABLE_VERSION} / C++latest"
-command: "libcxx/utils/ci/run-buildbot generic-gcc"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "gcc-${GCC_STABLE_VERSION}"
-CXX: "g++-${GCC_STABLE_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  #
-  # All other supported configurations of libc++.
-  #
-  - wait
-
-  - label: "C++20"
-command: "libcxx/utils/ci/run-buildbot generic-cxx20"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++17"
-command: "libcxx/utils/ci/run-buildbot generic-cxx17"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-# TODO (mordante) use head
-#CC: "clang-${LLVM_HEAD_VERSION}"
-#CXX: "clang++-${LLVM_HEAD_VERSION}"
-CC: "clang-15"
-CXX: "clang++-15"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 459959.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/utils/ci/buildkite-pipeline.yml

Index: libcxx/utils/ci/buildkite-pipeline.yml
===
--- libcxx/utils/ci/buildkite-pipeline.yml
+++ libcxx/utils/ci/buildkite-pipeline.yml
@@ -59,19 +59,6 @@
   limit: 2
 timeout_in_minutes: 120
 
-  - label: "Documentation"
-command: "libcxx/utils/ci/run-buildbot documentation"
-artifact_paths:
-  - "**/test-results.xml"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
   #
   # General testing with the default configuration, under all the supported
   # Standard modes, with Clang and GCC. This catches most issues upfront.
@@ -79,273 +66,6 @@
   #
   - wait
 
-  - label: "C++2b"
-command: "libcxx/utils/ci/run-buildbot generic-cxx2b"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++11"
-command: "libcxx/utils/ci/run-buildbot generic-cxx11"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++03"
-command: "libcxx/utils/ci/run-buildbot generic-cxx03"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "Modular build"
-command: "libcxx/utils/ci/run-buildbot generic-modules"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "GCC ${GCC_STABLE_VERSION} / C++latest"
-command: "libcxx/utils/ci/run-buildbot generic-gcc"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "gcc-${GCC_STABLE_VERSION}"
-CXX: "g++-${GCC_STABLE_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  #
-  # All other supported configurations of libc++.
-  #
-  - wait
-
-  - label: "C++20"
-command: "libcxx/utils/ci/run-buildbot generic-cxx20"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++17"
-command: "libcxx/utils/ci/run-buildbot generic-cxx17"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-# TODO (mordante) use head
-#CC: "clang-${LLVM_HEAD_VERSION}"
-#CXX: "clang++-${LLVM_HEAD_VERSION}"
-CC: "clang-15"
-CXX: "clang++-15"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

@vhscampos that issue should be fixed now as well, thanks for the report!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 459946.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/utils/ci/buildkite-pipeline.yml

Index: libcxx/utils/ci/buildkite-pipeline.yml
===
--- libcxx/utils/ci/buildkite-pipeline.yml
+++ libcxx/utils/ci/buildkite-pipeline.yml
@@ -59,19 +59,6 @@
   limit: 2
 timeout_in_minutes: 120
 
-  - label: "Documentation"
-command: "libcxx/utils/ci/run-buildbot documentation"
-artifact_paths:
-  - "**/test-results.xml"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
   #
   # General testing with the default configuration, under all the supported
   # Standard modes, with Clang and GCC. This catches most issues upfront.
@@ -79,273 +66,6 @@
   #
   - wait
 
-  - label: "C++2b"
-command: "libcxx/utils/ci/run-buildbot generic-cxx2b"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++11"
-command: "libcxx/utils/ci/run-buildbot generic-cxx11"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++03"
-command: "libcxx/utils/ci/run-buildbot generic-cxx03"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "Modular build"
-command: "libcxx/utils/ci/run-buildbot generic-modules"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "GCC ${GCC_STABLE_VERSION} / C++latest"
-command: "libcxx/utils/ci/run-buildbot generic-gcc"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "gcc-${GCC_STABLE_VERSION}"
-CXX: "g++-${GCC_STABLE_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  #
-  # All other supported configurations of libc++.
-  #
-  - wait
-
-  - label: "C++20"
-command: "libcxx/utils/ci/run-buildbot generic-cxx20"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++17"
-command: "libcxx/utils/ci/run-buildbot generic-cxx17"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-# TODO (mordante) use head
-#CC: "clang-${LLVM_HEAD_VERSION}"
-#CXX: "clang++-${LLVM_HEAD_VERSION}"
-CC: "clang-15"
-CXX: "clang++-15"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 459944.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/utils/ci/buildkite-pipeline.yml

Index: libcxx/utils/ci/buildkite-pipeline.yml
===
--- libcxx/utils/ci/buildkite-pipeline.yml
+++ libcxx/utils/ci/buildkite-pipeline.yml
@@ -59,19 +59,6 @@
   limit: 2
 timeout_in_minutes: 120
 
-  - label: "Documentation"
-command: "libcxx/utils/ci/run-buildbot documentation"
-artifact_paths:
-  - "**/test-results.xml"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
   #
   # General testing with the default configuration, under all the supported
   # Standard modes, with Clang and GCC. This catches most issues upfront.
@@ -79,273 +66,6 @@
   #
   - wait
 
-  - label: "C++2b"
-command: "libcxx/utils/ci/run-buildbot generic-cxx2b"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++11"
-command: "libcxx/utils/ci/run-buildbot generic-cxx11"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++03"
-command: "libcxx/utils/ci/run-buildbot generic-cxx03"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "Modular build"
-command: "libcxx/utils/ci/run-buildbot generic-modules"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "GCC ${GCC_STABLE_VERSION} / C++latest"
-command: "libcxx/utils/ci/run-buildbot generic-gcc"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "gcc-${GCC_STABLE_VERSION}"
-CXX: "g++-${GCC_STABLE_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  #
-  # All other supported configurations of libc++.
-  #
-  - wait
-
-  - label: "C++20"
-command: "libcxx/utils/ci/run-buildbot generic-cxx20"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++17"
-command: "libcxx/utils/ci/run-buildbot generic-cxx17"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-# TODO (mordante) use head
-#CC: "clang-${LLVM_HEAD_VERSION}"
-#CXX: "clang++-${LLVM_HEAD_VERSION}"
-CC: "clang-15"
-CXX: "clang++-15"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12367
+  case Type::Class:
\
+llvm_unreachable("Unexpected " Kind ": " #Class);
+

aaronpuchert wrote:
> mizvekov wrote:
> > davrec wrote:
> > > mizvekov wrote:
> > > > davrec wrote:
> > > > > mizvekov wrote:
> > > > > > davrec wrote:
> > > > > > > Could we just return `X` here? Would that just default to the old 
> > > > > > > behavior instead of crashing whenever unforeseen cases arise?  
> > > > > > No, I think we should enforce the invariants and make sure we are 
> > > > > > handling everything that can be handled.
> > > > > > 
> > > > > > Classing `TemplateTypeParm`  as sugar-free was what was wrong and 
> > > > > > we missed this on the review.
> > > > > There might always going to be a few rare corner cases vulnerable to 
> > > > > this though, particularly as more types are added and the people 
> > > > > adding them don't pay strict attention to how to incorporate them 
> > > > > here, and don't write the requisite tests (which seem very difficult 
> > > > > to foresee and produce).  When those cases arise we will be crashing 
> > > > > even though we could produce a perfectly good program with the 
> > > > > intended semantics; the only thing that would suffer for most users 
> > > > > is slightly less clear diagnostic messages for those rare cases.  I 
> > > > > think it would be better to let those cases gradually percolate to 
> > > > > our attention via bug reports concerning those diagnostics, rather 
> > > > > than inconveniencing the user and demanding immediate attention via 
> > > > > crashes.  Or am I missing something?
> > > > I could on the same argument remove all asserts here and just let the 
> > > > program not crash on unforeseen circumstances.
> > > > 
> > > > On the other hand, having these asserts here helps us catch bugs not 
> > > > only here, but in other parts of the code. For example uniquing / 
> > > > canonicalization bugs.
> > > > 
> > > > If someone changes the properties of a type so that the assumptions 
> > > > here are not valid anymore, it's helpful to have that pointed out soon.
> > > > 
> > > > Going for as an example this specific bug, if there werent those 
> > > > asserts / unreachables in place and we had weakened the validation 
> > > > here, it would take a very long time for us to figure out we were 
> > > > making the wrong assumption with regards to TemplateTypeParmType.
> > > > 
> > > > I'd rather figure that out sooner on CI / internal testing rather than 
> > > > have a bug created by a user two years from now.
> > > Yes its nicer to developers to get stack traces and reproductions 
> > > whenever something goes wrong, and crashing is a good way to get those, 
> > > but users probably won't be so thrilled about it.  Especially given that 
> > > the main selling point of this patch is that it makes diagnostics nicer 
> > > for users: isn't it a bit absurd to crash whenever we can't guarantee our 
> > > diagnostics will be perfect?
> > > 
> > > And again the real problem is future types not being properly 
> > > incorporated here and properly tested: i.e. the worry is that this will 
> > > be a continuing source of crashes, even if we handle all the present 
> > > types properly.
> > > 
> > > How about we leave it as an unreachable for now, to help ensure all the 
> > > present types are handled, but if months or years from now there continue 
> > > to be crashes due to this, then just return X (while maybe write 
> > > something to llvm::errs() to encourage users to report it), so we don't 
> > > make the perfect the enemy of the good.
> > It's not about crashing when it won't be perfect. We already do these kinds 
> > of things, see the FIXMEs around the TemplateArgument and 
> > NestedNameSpecifier, where we just return something worse than we wish to, 
> > just because we don't have time to implement it now.
> > 
> > These unreachables and asserts here are about testing / documenting our 
> > knowledge of the system and making it easier to find problems. These should 
> > be impossible to happen in correct code, and if they do happen because of 
> > mistakes, fixing them sooner is just going to save us resources.
> > 
> > `llvm::errs` suggestion I perceive as out of line with current practice in 
> > LLVM, we don't and have a system for producing diagnostics for results 
> > possibly affected by FIXME and TODO situations and the like, as far as I 
> > know, and I am not aware of any discussions in that direction. I expect a 
> > lot of complexity and noise if we went this way.
> > And I think this would have even less chance of working out if we started 
> > to incorporate the reporting of violation of invariants into that.
> > 
> > I think even just using raw `llvm::errs` on clang would be incorrect per 
> > design, and could likely break users that parse our output.
> > 
> > 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Aaron Puchert via Phabricator via cfe-commits
aaronpuchert added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12367
+  case Type::Class:
\
+llvm_unreachable("Unexpected " Kind ": " #Class);
+

mizvekov wrote:
> davrec wrote:
> > mizvekov wrote:
> > > davrec wrote:
> > > > mizvekov wrote:
> > > > > davrec wrote:
> > > > > > Could we just return `X` here? Would that just default to the old 
> > > > > > behavior instead of crashing whenever unforeseen cases arise?  
> > > > > No, I think we should enforce the invariants and make sure we are 
> > > > > handling everything that can be handled.
> > > > > 
> > > > > Classing `TemplateTypeParm`  as sugar-free was what was wrong and we 
> > > > > missed this on the review.
> > > > There might always going to be a few rare corner cases vulnerable to 
> > > > this though, particularly as more types are added and the people adding 
> > > > them don't pay strict attention to how to incorporate them here, and 
> > > > don't write the requisite tests (which seem very difficult to foresee 
> > > > and produce).  When those cases arise we will be crashing even though 
> > > > we could produce a perfectly good program with the intended semantics; 
> > > > the only thing that would suffer for most users is slightly less clear 
> > > > diagnostic messages for those rare cases.  I think it would be better 
> > > > to let those cases gradually percolate to our attention via bug reports 
> > > > concerning those diagnostics, rather than inconveniencing the user and 
> > > > demanding immediate attention via crashes.  Or am I missing something?
> > > I could on the same argument remove all asserts here and just let the 
> > > program not crash on unforeseen circumstances.
> > > 
> > > On the other hand, having these asserts here helps us catch bugs not only 
> > > here, but in other parts of the code. For example uniquing / 
> > > canonicalization bugs.
> > > 
> > > If someone changes the properties of a type so that the assumptions here 
> > > are not valid anymore, it's helpful to have that pointed out soon.
> > > 
> > > Going for as an example this specific bug, if there werent those asserts 
> > > / unreachables in place and we had weakened the validation here, it would 
> > > take a very long time for us to figure out we were making the wrong 
> > > assumption with regards to TemplateTypeParmType.
> > > 
> > > I'd rather figure that out sooner on CI / internal testing rather than 
> > > have a bug created by a user two years from now.
> > Yes its nicer to developers to get stack traces and reproductions whenever 
> > something goes wrong, and crashing is a good way to get those, but users 
> > probably won't be so thrilled about it.  Especially given that the main 
> > selling point of this patch is that it makes diagnostics nicer for users: 
> > isn't it a bit absurd to crash whenever we can't guarantee our diagnostics 
> > will be perfect?
> > 
> > And again the real problem is future types not being properly incorporated 
> > here and properly tested: i.e. the worry is that this will be a continuing 
> > source of crashes, even if we handle all the present types properly.
> > 
> > How about we leave it as an unreachable for now, to help ensure all the 
> > present types are handled, but if months or years from now there continue 
> > to be crashes due to this, then just return X (while maybe write something 
> > to llvm::errs() to encourage users to report it), so we don't make the 
> > perfect the enemy of the good.
> It's not about crashing when it won't be perfect. We already do these kinds 
> of things, see the FIXMEs around the TemplateArgument and 
> NestedNameSpecifier, where we just return something worse than we wish to, 
> just because we don't have time to implement it now.
> 
> These unreachables and asserts here are about testing / documenting our 
> knowledge of the system and making it easier to find problems. These should 
> be impossible to happen in correct code, and if they do happen because of 
> mistakes, fixing them sooner is just going to save us resources.
> 
> `llvm::errs` suggestion I perceive as out of line with current practice in 
> LLVM, we don't and have a system for producing diagnostics for results 
> possibly affected by FIXME and TODO situations and the like, as far as I 
> know, and I am not aware of any discussions in that direction. I expect a lot 
> of complexity and noise if we went this way.
> And I think this would have even less chance of working out if we started to 
> incorporate the reporting of violation of invariants into that.
> 
> I think even just using raw `llvm::errs` on clang would be incorrect per 
> design, and could likely break users that parse our output.
> 
> I think if months and years from now, if someone stumbled upon an assert 
> firing here and, instead of understanding what is happening and then fixing 
> the code, just removed / weakened 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

In D111283#3786610 , @vhscampos wrote:

> For reference, another small reproducer of the crash, but with a different 
> stack trace than the first example posted here:
>
>   // Must compile with -std=c++03 to crash
>   #include 
>   
>   int main(int, char**)
>   {
> int i[3] = {1, 2, 3};
> int j[3] = {4, 5, 6};
> std::swap(i, j);
>   
> return 0;
>   }
>
> Compile with -std=c++03 to reproduce the assertion failure.
> We found it by running the libcxx tests.

Thanks. Is this a different crash, or is It the same unreachable firing as the 
one @alexfh reported?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

@alexfh This new revision that I just pushed should be good.

Do you want to give it a look / test, or should we go ahead and merge it?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12367
+  case Type::Class:
\
+llvm_unreachable("Unexpected " Kind ": " #Class);
+

davrec wrote:
> mizvekov wrote:
> > davrec wrote:
> > > mizvekov wrote:
> > > > davrec wrote:
> > > > > Could we just return `X` here? Would that just default to the old 
> > > > > behavior instead of crashing whenever unforeseen cases arise?  
> > > > No, I think we should enforce the invariants and make sure we are 
> > > > handling everything that can be handled.
> > > > 
> > > > Classing `TemplateTypeParm`  as sugar-free was what was wrong and we 
> > > > missed this on the review.
> > > There might always going to be a few rare corner cases vulnerable to this 
> > > though, particularly as more types are added and the people adding them 
> > > don't pay strict attention to how to incorporate them here, and don't 
> > > write the requisite tests (which seem very difficult to foresee and 
> > > produce).  When those cases arise we will be crashing even though we 
> > > could produce a perfectly good program with the intended semantics; the 
> > > only thing that would suffer for most users is slightly less clear 
> > > diagnostic messages for those rare cases.  I think it would be better to 
> > > let those cases gradually percolate to our attention via bug reports 
> > > concerning those diagnostics, rather than inconveniencing the user and 
> > > demanding immediate attention via crashes.  Or am I missing something?
> > I could on the same argument remove all asserts here and just let the 
> > program not crash on unforeseen circumstances.
> > 
> > On the other hand, having these asserts here helps us catch bugs not only 
> > here, but in other parts of the code. For example uniquing / 
> > canonicalization bugs.
> > 
> > If someone changes the properties of a type so that the assumptions here 
> > are not valid anymore, it's helpful to have that pointed out soon.
> > 
> > Going for as an example this specific bug, if there werent those asserts / 
> > unreachables in place and we had weakened the validation here, it would 
> > take a very long time for us to figure out we were making the wrong 
> > assumption with regards to TemplateTypeParmType.
> > 
> > I'd rather figure that out sooner on CI / internal testing rather than have 
> > a bug created by a user two years from now.
> Yes its nicer to developers to get stack traces and reproductions whenever 
> something goes wrong, and crashing is a good way to get those, but users 
> probably won't be so thrilled about it.  Especially given that the main 
> selling point of this patch is that it makes diagnostics nicer for users: 
> isn't it a bit absurd to crash whenever we can't guarantee our diagnostics 
> will be perfect?
> 
> And again the real problem is future types not being properly incorporated 
> here and properly tested: i.e. the worry is that this will be a continuing 
> source of crashes, even if we handle all the present types properly.
> 
> How about we leave it as an unreachable for now, to help ensure all the 
> present types are handled, but if months or years from now there continue to 
> be crashes due to this, then just return X (while maybe write something to 
> llvm::errs() to encourage users to report it), so we don't make the perfect 
> the enemy of the good.
It's not about crashing when it won't be perfect. We already do these kinds of 
things, see the FIXMEs around the TemplateArgument and NestedNameSpecifier, 
where we just return something worse than we wish to, just because we don't 
have time to implement it now.

These unreachables and asserts here are about testing / documenting our 
knowledge of the system and making it easier to find problems. These should be 
impossible to happen in correct code, and if they do happen because of 
mistakes, fixing them sooner is just going to save us resources.

`llvm::errs` suggestion I perceive as out of line with current practice in 
LLVM, we don't and have a system for producing diagnostics for results possibly 
affected by FIXME and TODO situations and the like, as far as I know, and I am 
not aware of any discussions in that direction. I expect a lot of complexity 
and noise if we went this way.
And I think this would have even less chance of working out if we started to 
incorporate the reporting of violation of invariants into that.

I think even just using raw `llvm::errs` on clang would be incorrect per 
design, and could likely break users that parse our output.

I think if months and years from now, if someone stumbled upon an assert firing 
here and, instead of understanding what is happening and then fixing the code, 
just removed / weakened the assert, that would simply not be good and I hope a 
reviewer would stop that from happening :)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Victor Campos via Phabricator via cfe-commits
vhscampos added a comment.

For reference, another small reproducer of the crash, but with a different 
stack trace than the first example posted here:

  // Must compile with -std=c++03 to crash
  #include 
  
  int main(int, char**)
  {
int i[3] = {1, 2, 3};
int j[3] = {4, 5, 6};
std::swap(i, j);
  
return 0;
  }

Compile with -std=c++03 to reproduce the assertion failure.
We found it by running the libcxx tests.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread David Rector via Phabricator via cfe-commits
davrec added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12367
+  case Type::Class:
\
+llvm_unreachable("Unexpected " Kind ": " #Class);
+

mizvekov wrote:
> davrec wrote:
> > mizvekov wrote:
> > > davrec wrote:
> > > > Could we just return `X` here? Would that just default to the old 
> > > > behavior instead of crashing whenever unforeseen cases arise?  
> > > No, I think we should enforce the invariants and make sure we are 
> > > handling everything that can be handled.
> > > 
> > > Classing `TemplateTypeParm`  as sugar-free was what was wrong and we 
> > > missed this on the review.
> > There might always going to be a few rare corner cases vulnerable to this 
> > though, particularly as more types are added and the people adding them 
> > don't pay strict attention to how to incorporate them here, and don't write 
> > the requisite tests (which seem very difficult to foresee and produce).  
> > When those cases arise we will be crashing even though we could produce a 
> > perfectly good program with the intended semantics; the only thing that 
> > would suffer for most users is slightly less clear diagnostic messages for 
> > those rare cases.  I think it would be better to let those cases gradually 
> > percolate to our attention via bug reports concerning those diagnostics, 
> > rather than inconveniencing the user and demanding immediate attention via 
> > crashes.  Or am I missing something?
> I could on the same argument remove all asserts here and just let the program 
> not crash on unforeseen circumstances.
> 
> On the other hand, having these asserts here helps us catch bugs not only 
> here, but in other parts of the code. For example uniquing / canonicalization 
> bugs.
> 
> If someone changes the properties of a type so that the assumptions here are 
> not valid anymore, it's helpful to have that pointed out soon.
> 
> Going for as an example this specific bug, if there werent those asserts / 
> unreachables in place and we had weakened the validation here, it would take 
> a very long time for us to figure out we were making the wrong assumption 
> with regards to TemplateTypeParmType.
> 
> I'd rather figure that out sooner on CI / internal testing rather than have a 
> bug created by a user two years from now.
Yes its nicer to developers to get stack traces and reproductions whenever 
something goes wrong, and crashing is a good way to get those, but users 
probably won't be so thrilled about it.  Especially given that the main selling 
point of this patch is that it makes diagnostics nicer for users: isn't it a 
bit absurd to crash whenever we can't guarantee our diagnostics will be perfect?

And again the real problem is future types not being properly incorporated here 
and properly tested: i.e. the worry is that this will be a continuing source of 
crashes, even if we handle all the present types properly.

How about we leave it as an unreachable for now, to help ensure all the present 
types are handled, but if months or years from now there continue to be crashes 
due to this, then just return X (while maybe write something to llvm::errs() to 
encourage users to report it), so we don't make the perfect the enemy of the 
good.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12367
+  case Type::Class:
\
+llvm_unreachable("Unexpected " Kind ": " #Class);
+

davrec wrote:
> mizvekov wrote:
> > davrec wrote:
> > > Could we just return `X` here? Would that just default to the old 
> > > behavior instead of crashing whenever unforeseen cases arise?  
> > No, I think we should enforce the invariants and make sure we are handling 
> > everything that can be handled.
> > 
> > Classing `TemplateTypeParm`  as sugar-free was what was wrong and we missed 
> > this on the review.
> There might always going to be a few rare corner cases vulnerable to this 
> though, particularly as more types are added and the people adding them don't 
> pay strict attention to how to incorporate them here, and don't write the 
> requisite tests (which seem very difficult to foresee and produce).  When 
> those cases arise we will be crashing even though we could produce a 
> perfectly good program with the intended semantics; the only thing that would 
> suffer for most users is slightly less clear diagnostic messages for those 
> rare cases.  I think it would be better to let those cases gradually 
> percolate to our attention via bug reports concerning those diagnostics, 
> rather than inconveniencing the user and demanding immediate attention via 
> crashes.  Or am I missing something?
I could on the same argument remove all asserts here and just let the program 
not crash on unforeseen circumstances.

On the other hand, having these asserts here helps us catch bugs not only here, 
but in other parts of the code. For example uniquing / canonicalization bugs.

If someone changes the properties of a type so that the assumptions here are 
not valid anymore, it's helpful to have that pointed out soon.

Going for as an example this specific bug, if there werent those asserts / 
unreachables in place and we had weakened the validation here, it would take a 
very long time for us to figure out we were making the wrong assumption with 
regards to TemplateTypeParmType.

I'd rather figure that out sooner on CI / internal testing rather than have a 
bug created by a user two years from now.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread David Rector via Phabricator via cfe-commits
davrec added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12367
+  case Type::Class:
\
+llvm_unreachable("Unexpected " Kind ": " #Class);
+

mizvekov wrote:
> davrec wrote:
> > Could we just return `X` here? Would that just default to the old behavior 
> > instead of crashing whenever unforeseen cases arise?  
> No, I think we should enforce the invariants and make sure we are handling 
> everything that can be handled.
> 
> Classing `TemplateTypeParm`  as sugar-free was what was wrong and we missed 
> this on the review.
There might always going to be a few rare corner cases vulnerable to this 
though, particularly as more types are added and the people adding them don't 
pay strict attention to how to incorporate them here, and don't write the 
requisite tests (which seem very difficult to foresee and produce).  When those 
cases arise we will be crashing even though we could produce a perfectly good 
program with the intended semantics; the only thing that would suffer for most 
users is slightly less clear diagnostic messages for those rare cases.  I think 
it would be better to let those cases gradually percolate to our attention via 
bug reports concerning those diagnostics, rather than inconveniencing the user 
and demanding immediate attention via crashes.  Or am I missing something?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 459726.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/utils/ci/buildkite-pipeline.yml

Index: libcxx/utils/ci/buildkite-pipeline.yml
===
--- libcxx/utils/ci/buildkite-pipeline.yml
+++ libcxx/utils/ci/buildkite-pipeline.yml
@@ -59,19 +59,6 @@
   limit: 2
 timeout_in_minutes: 120
 
-  - label: "Documentation"
-command: "libcxx/utils/ci/run-buildbot documentation"
-artifact_paths:
-  - "**/test-results.xml"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
   #
   # General testing with the default configuration, under all the supported
   # Standard modes, with Clang and GCC. This catches most issues upfront.
@@ -79,273 +66,6 @@
   #
   - wait
 
-  - label: "C++2b"
-command: "libcxx/utils/ci/run-buildbot generic-cxx2b"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++11"
-command: "libcxx/utils/ci/run-buildbot generic-cxx11"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++03"
-command: "libcxx/utils/ci/run-buildbot generic-cxx03"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "Modular build"
-command: "libcxx/utils/ci/run-buildbot generic-modules"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "GCC ${GCC_STABLE_VERSION} / C++latest"
-command: "libcxx/utils/ci/run-buildbot generic-gcc"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "gcc-${GCC_STABLE_VERSION}"
-CXX: "g++-${GCC_STABLE_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  #
-  # All other supported configurations of libc++.
-  #
-  - wait
-
-  - label: "C++20"
-command: "libcxx/utils/ci/run-buildbot generic-cxx20"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++17"
-command: "libcxx/utils/ci/run-buildbot generic-cxx17"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-# TODO (mordante) use head
-#CC: "clang-${LLVM_HEAD_VERSION}"
-#CXX: "clang++-${LLVM_HEAD_VERSION}"
-CC: "clang-15"
-CXX: "clang++-15"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov edited the summary of this revision.
mizvekov updated this revision to Diff 459725.
Herald added subscribers: mstorsjo, arichardson.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/utils/ci/buildkite-pipeline.yml

Index: libcxx/utils/ci/buildkite-pipeline.yml
===
--- libcxx/utils/ci/buildkite-pipeline.yml
+++ libcxx/utils/ci/buildkite-pipeline.yml
@@ -59,19 +59,6 @@
   limit: 2
 timeout_in_minutes: 120
 
-  - label: "Documentation"
-command: "libcxx/utils/ci/run-buildbot documentation"
-artifact_paths:
-  - "**/test-results.xml"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
   #
   # General testing with the default configuration, under all the supported
   # Standard modes, with Clang and GCC. This catches most issues upfront.
@@ -79,273 +66,6 @@
   #
   - wait
 
-  - label: "C++2b"
-command: "libcxx/utils/ci/run-buildbot generic-cxx2b"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++11"
-command: "libcxx/utils/ci/run-buildbot generic-cxx11"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++03"
-command: "libcxx/utils/ci/run-buildbot generic-cxx03"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "Modular build"
-command: "libcxx/utils/ci/run-buildbot generic-modules"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "GCC ${GCC_STABLE_VERSION} / C++latest"
-command: "libcxx/utils/ci/run-buildbot generic-gcc"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "gcc-${GCC_STABLE_VERSION}"
-CXX: "g++-${GCC_STABLE_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  #
-  # All other supported configurations of libc++.
-  #
-  - wait
-
-  - label: "C++20"
-command: "libcxx/utils/ci/run-buildbot generic-cxx20"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-CC: "clang-${LLVM_HEAD_VERSION}"
-CXX: "clang++-${LLVM_HEAD_VERSION}"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- exit_status: -1  # Agent was lost
-  limit: 2
-timeout_in_minutes: 120
-
-  - label: "C++17"
-command: "libcxx/utils/ci/run-buildbot generic-cxx17"
-artifact_paths:
-  - "**/test-results.xml"
-  - "**/*.abilist"
-env:
-# TODO (mordante) use head
-#CC: "clang-${LLVM_HEAD_VERSION}"
-#CXX: "clang++-${LLVM_HEAD_VERSION}"
-CC: "clang-15"
-CXX: "clang++-15"
-agents:
-  queue: "libcxx-builders"
-  os: "linux"
-retry:
-  automatic:
-- 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12367
+  case Type::Class:
\
+llvm_unreachable("Unexpected " Kind ": " #Class);
+

davrec wrote:
> Could we just return `X` here? Would that just default to the old behavior 
> instead of crashing whenever unforeseen cases arise?  
No, I think we should enforce the invariants and make sure we are handling 
everything that can be handled.

Classing `TemplateTypeParm`  as sugar-free was what was wrong and we missed 
this on the review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread David Rector via Phabricator via cfe-commits
davrec added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12367
+  case Type::Class:
\
+llvm_unreachable("Unexpected " Kind ": " #Class);
+

Could we just return `X` here? Would that just default to the old behavior 
instead of crashing whenever unforeseen cases arise?  


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

Even simpler:

  template  using P = T;
  
  template  void j(P, T, A...);
  template  void j(P, T);
  
  void g() { j(P{}, int{}); }


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Alexander Kornienko via Phabricator via cfe-commits
alexfh added a comment.

I've reverted d200db38637884fd0b421802c6094b2a03ceb29e 
 in 
637da9de4c6619c0e179c2c2f0dbfebd08ac2a0f 
.

And a bit more compact test case:

  template 
  using P = int T::*;
  
  template 
  void j(P, T, A...);
  
  template 
  void j(P, T);
  
  struct S {
int b;
  };
  void g(P k, S s) { j(k, s); }


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-13 Thread Alexander Kornienko via Phabricator via cfe-commits
alexfh added a comment.

In D111283#3785259 , @alexfh wrote:

> In D111283#3785240 , @alexfh wrote:
>
>> In D111283#3783627 , @alexfh wrote:
>>
>>> Hi Matheus, an early heads up: this commit is causing clang crashes on some 
>>> of our code. I'll post more details a bit later.
>>
>> The stack trace of the failure looks like this:
>
> And the assertions-enabled build of clang prints this:
>
>   Unexpected sugar-free: TemplateTypeParm
>   UNREACHABLE executed at llvm-project/clang/lib/AST/ASTContext.cpp:12383!

Reduced test case:

  $ cat q.cc
  struct a {
int b;
  };
  template  using e = c d::*;
  struct f {
long b() const;
template  c g(e) const;
a h;
  };
  template 
  void j(e, const d *, i...);
  template  c j(e, const d *);
  template  c f::g(e k) const { return j(k, ); }
  long f::b() const { return g(::b); }



  $ ./clang-after q.cc
  ...
  1.   parser at end of file
  2.  q.cc:13:28: instantiating function definition 'f::g'
  ...
  clang-after: error: unable to execute command: Trace/breakpoint trap
  clang-after: error: clang frontend command failed due to signal (use -v to 
see invocation)

Please fix or revert soon.

Thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-12 Thread Alexander Kornienko via Phabricator via cfe-commits
alexfh added a comment.

In D111283#3785240 , @alexfh wrote:

> In D111283#3783627 , @alexfh wrote:
>
>> Hi Matheus, an early heads up: this commit is causing clang crashes on some 
>> of our code. I'll post more details a bit later.
>
> The stack trace of the failure looks like this:

And the assertions-enabled build of clang prints this:

  Unexpected sugar-free: TemplateTypeParm
  UNREACHABLE executed at llvm-project/clang/lib/AST/ASTContext.cpp:12383!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-12 Thread Alexander Kornienko via Phabricator via cfe-commits
alexfh added a comment.

In D111283#3783627 , @alexfh wrote:

> Hi Matheus, an early heads up: this commit is causing clang crashes on some 
> of our code. I'll post more details a bit later.

The stack trace of the failure looks like this:

   #0 0x564e08f78aca llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
(./clang-after+0x7778aca)
   #1 0x564e08f76b78 llvm::sys::RunSignalHandlers() 
(./clang-after+0x7776b78)   


   #2 0x564e08f10027 (anonymous 
namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) 
(./clang-after+0x7710027)
   #3 0x564e08f102bd CrashRecoverySignalHandler(int) 
(./clang-after+0x77102bd)
   #4 0x7f4773e731c0 __restore_rt
   #5 0x564e06591b6b (./clang-after+0x4d91b6b)
   #6 0x564e06374ef8 checkDeducedTemplateArguments(clang::ASTContext&, 
clang::DeducedTemplateArgument const&, clang::DeducedTemplateArgument const&) 
(./clang-after+0x4b74ef8)
   #7 0x564e0636b7b1 DeduceTemplateArgumentsByTypeMatch(clang::Sema&, 
clang::TemplateParameterList*, clang::QualType, clang::QualType, 
clang::sema::TemplateDeductionInfo&, 
llvm::SmallVectorImpl&, unsigned int, bool, 
bool) (./clang-after+0x4b6b7b1)
   #8 0x564e0636c896 DeduceTemplateArgumentsByTypeMatch(clang::Sema&, 
clang::TemplateParameterList*, clang::QualType, clang::QualType, 
clang::sema::TemplateDeductionInfo&, 
llvm::SmallVectorImpl&, unsigned int, bool, 
bool) (./clang-after+0x4b6c896)
   #9 0x564e06376430 DeduceTemplateArguments(clang::Sema&, 
clang::TemplateParameterList*, clang::QualType const*, unsigned int, 
clang::QualType const*, unsigned int, clang::sema::TemplateDeductionInfo&, 
llvm::SmallVectorImpl&, unsigned int, bool) 
(./clang-after+0x4b76430)
  #10 0x564e06370895 isAtLeastAsSpecializedAs(clang::Sema&, 
clang::SourceLocation, clang::FunctionTemplateDecl*, 
clang::FunctionTemplateDecl*, clang::TemplatePartialOrderingContext, unsigned 
int, bool) (./clang-after+0x4b70895)
  #11 0x564e063702c1 
clang::Sema::getMoreSpecializedTemplate(clang::FunctionTemplateDecl*, 
clang::FunctionTemplateDecl*, clang::SourceLocation, 
clang::TemplatePartialOrderingContext, unsigned int, unsigned int, bool, bool) 
(./clang-after+0x4b702c1)
  #12 0x564e0626a07c clang::isBetterOverloadCandidate(clang::Sema&, 
clang::OverloadCandidate const&, clang::OverloadCandidate const&, 
clang::SourceLocation, clang::OverloadCandidateSet::CandidateSetKind) 
(./clang-after+0x4a6a07c)
  #13 0x564e0625e199 
clang::OverloadCandidateSet::BestViableFunction(clang::Sema&, 
clang::SourceLocation, clang::OverloadCandidate*&) (./clang-after+0x4a5e199)
  #14 0x564e06272aec clang::Sema::BuildOverloadedCallExpr(clang::Scope*, 
clang::Expr*, clang::UnresolvedLookupExpr*, clang::SourceLocation, 
llvm::MutableArrayRef, clang::SourceLocation, clang::Expr*, bool, 
bool) (./clang-after+0x4a72aec)
  #15 0x564e05fd3157 clang::Sema::BuildCallExpr(clang::Scope*, 
clang::Expr*, clang::SourceLocation, llvm::MutableArrayRef, 
clang::SourceLocation, clang::Expr*, bool, bool) (./clang-after+0x47d3157)
  #16 0x564e05feb5b6 clang::Sema::ActOnCallExpr(clang::Scope*, 
clang::Expr*, clang::SourceLocation, llvm::MutableArrayRef, 
clang::SourceLocation, clang::Expr*) (./clang-after+0x47eb5b6)
  #17 0x564e063d0bc6 clang::TreeTransform<(anonymous 
namespace)::TemplateInstantiator>::TransformCallExpr(clang::CallExpr*) 
(./clang-after+0x4bd0bc6)
  #18 0x564e063c80f9 clang::Sema::SubstInitializer(clang::Expr*, 
clang::MultiLevelTemplateArgumentList const&, bool) (./clang-after+0x4bc80f9)
  #19 0x564e064057c8 
clang::Sema::InstantiateVariableInitializer(clang::VarDecl*, clang::VarDecl*, 
clang::MultiLevelTemplateArgumentList const&) (./clang-after+0x4c057c8)
  #20 0x564e063fa1be 
clang::Sema::BuildVariableInstantiation(clang::VarDecl*, clang::VarDecl*, 
clang::MultiLevelTemplateArgumentList const&, 
llvm::SmallVector*, 
clang::DeclContext*, clang::LocalInstantiationScope*, bool, 
clang::VarTemplateSpecializationDecl*) (./clang-after+0x4bfa1be)
  #21 0x564e063f99db 
clang::TemplateDeclInstantiator::VisitVarDecl(clang::VarDecl*, bool, 
llvm::ArrayRef*) (./clang-after+0x4bf99db)
  #22 0x564e0642f599 void llvm::function_ref::callback_fn(long) 
(./clang-after+0x4c2f599)
  #23 0x564e05cc55ee 
clang::Sema::runWithSufficientStackSpace(clang::SourceLocation, 
llvm::function_ref) (./clang-after+0x44c55ee)
  #24 0x564e06406ceb clang::Sema::SubstDecl(clang::Decl*, 
clang::DeclContext*, clang::MultiLevelTemplateArgumentList const&) 
(./clang-after+0x4c06ceb)
  #25 0x564e063e91ac clang::TreeTransform<(anonymous 
namespace)::TemplateInstantiator>::TransformDeclStmt(clang::DeclStmt*) 
(./clang-after+0x4be91ac)
  #26 0x564e063e08c7 clang::TreeTransform<(anonymous 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-12 Thread Yuanfang Chen via Phabricator via cfe-commits
ychen added a comment.

In D111283#3784702 , @mizvekov wrote:

> In D111283#3784663 , @ychen wrote:
>
>> Thanks for the link. I'm not blocked by any of these patches, instead just 
>> trying to have a mental model of when to expect the sugared type :-). For 
>> partial ordering, the `TemplateSpecializationType` could be dependent, since 
>> the injected template arguments are dependent, I guess that's the reason 
>> there is the `ElaboratedType`?
>
> The ElaboratedType is a sort of a `companion node` to other nodes that 
> represent things in the language which can have (non-dependent) nested name 
> qualifiers (a NNS for short) and / or an elaborated type specifier (such as 
> the `struct` in `struct A`).
>
> It's only purpose is to carry that extra bit of data, like some external 
> storage really, and it shouldn't affect the semantics of the program once the 
> source code is parsed into an AST.
>
> Here, in your example, the ElaboratedType is there, as a companion to that 
> TemplateSpecializationType, just to say that this template specialization was 
> written without any name qualifiers nor elaboration.

Very helpful explanation :-).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-12 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

In D111283#3784663 , @ychen wrote:

> Thanks for the link. I'm not blocked by any of these patches, instead just 
> trying to have a mental model of when to expect the sugared type :-). For 
> partial ordering, the `TemplateSpecializationType` could be dependent, since 
> the injected template arguments are dependent, I guess that's the reason 
> there is the `ElaboratedType`?

The ElaboratedType is a sort of a `companion node` to other nodes that 
represent things in the language which can have (non-dependent) nested name 
qualifiers (a NNS for short) and / or an elaborated type specifier (such as the 
`struct` in `struct A`).

It's only purpose is to carry that extra bit of data, like some external 
storage really, and it shouldn't affect the semantics of the program once the 
source code is parsed into an AST.

Here, in your example, the ElaboratedType is there, as a companion to that 
TemplateSpecializationType, just to say that this template specialization was 
written without any name qualifiers nor elaboration.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-12 Thread Yuanfang Chen via Phabricator via cfe-commits
ychen added a comment.

In D111283#3784648 , @mizvekov wrote:

> In D111283#3784615 , @ychen wrote:
>
>> `A` is currently modeled as ElaboratedType. It was 
>> `TemplateSpecializationType` before. Reading comments for `ElaboratedType`, 
>> it looks like sugar type might not be needed here?
>
> Ah you might be seeing an ElaboratedTYpe here, where there was none before, 
> perhaps because of https://reviews.llvm.org/D112374, and not because of this 
> patch.
>
> Yeah ElaboratedType is just sugar that should have no effect on partial 
> ordering. But then I think no sugar should have effect on partial ordering. 
> What is stopping you from just looking at the canonical type instead? On a 
> canonical type, you would never see an ElaboratedType node, or a 
> TemplateSpecializationType which is not dependent.

Thanks for the link. I'm not blocked by any of these patches, instead just 
trying to have a mental model of when to expect the sugared type :-). For 
partial ordering, the `TemplateSpecializationType` could be dependent, since 
the injected template arguments are dependent, I guess that's the reason there 
is the `ElaboratedType`?

> Is this related to the AutoType canonicalization issues we were discussing in 
> the other patch of yours?

Nope. I found this AST difference while investigating D133683 
.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-12 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

In D111283#3784615 , @ychen wrote:

> `A` is currently modeled as ElaboratedType. It was 
> `TemplateSpecializationType` before. Reading comments for `ElaboratedType`, 
> it looks like sugar type might not be needed here?

Ah you might be seeing an ElaboratedTYpe here, where there was none before, 
perhaps because of https://reviews.llvm.org/D112374, and not because of this 
patch.

Yeah ElaboratedType is just sugar that should have no effect on partial 
ordering. But then I think no sugar should have effect on partial ordering. 
What is stopping you from just looking at the canonical type instead? On a 
canonical type, you would never see an ElaboratedType node, or a 
TemplateSpecializationType which is not dependent.

Is this related to the AutoType canonicalization issues we were discussing in 
the other patch of yours?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-12 Thread Yuanfang Chen via Phabricator via cfe-commits
ychen added a comment.

In D111283#3783338 , @mizvekov wrote:

> In D111283#3783250 , @ychen wrote:
>
>> Hi @mizvekov , I noticed that deduction for partial ordering also inherits 
>> this new behavior. Do you think partial ordering could opt out of this, or 
>> is it better for partial ordering to deal with the new sugared types?
>
> I would expect partial ordering to be performed only using canonical types, 
> that type sugar should make no difference there.
>
> Note that previous to this patch, we would already produce sugar on 
> deduction, but the behavior with regards to deducing the same template 
> parameter from multiple places was pretty badly behaved: We would just keep 
> the sugar from the first deduction, and ignore any subsequent ones. That 
> meant that the deduction order had an effect on the result. With this patch, 
> deduction becomes order agnostic.

I see. I  think it is definitely a good thing. I'm still learning what the 
expected AST should look like during the partial ordering.

> What kind of difference are you seeing?

For

  template  struct A {};
  
  template 
  bool foo(A);
  
  template 
  bool foo(A);
  
  template  bool bar()
  {
  return foo(Tuple{});
  }

`A` is currently modeled as ElaboratedType. It was 
`TemplateSpecializationType` before. Reading comments for `ElaboratedType`, it 
looks like sugar type might not be needed here?

  ElaboratedType 0xd79c8f0 'A' sugar dependent
  `-TemplateSpecializationType 0xd79c8b0 'A' dependent A
`-TemplateArgument type 'T'
  `-TemplateTypeParmType 0xd79c7f0 'T' dependent depth 0 index 0
`-TemplateTypeParm 0xd79c768 'T'


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-12 Thread Alexander Kornienko via Phabricator via cfe-commits
alexfh added a comment.

Hi Matheus, an early heads up: this commit is causing clang crashes on some of 
our code. I'll post more details a bit later.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-12 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

In D111283#3783250 , @ychen wrote:

> Hi @mizvekov , I noticed that deduction for partial ordering also inherits 
> this new behavior. Do you think partial ordering could opt out of this, or is 
> it better for partial ordering to deal with the new sugared types?

I would expect partial ordering to be performed only using canonical types, 
that type sugar should make no difference there.

Note that previous to this patch, we would already produce sugar on deduction, 
but the behavior with regards to deducing the same template parameter from 
multiple places was pretty badly behaved: We would just keep the sugar from the 
first deduction, and ignore any subsequent ones. That meant that the deduction 
order had an effect on the result. With this patch, deduction becomes order 
agnostic.

What kind of difference are you seeing?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-12 Thread Yuanfang Chen via Phabricator via cfe-commits
ychen added a comment.

Hi @mizvekov , I noticed that deduction for partial ordering also inherits this 
new behavior. Do you think partial ordering could opt out of this, or is it 
better for partial ordering to deal with the new sugared types?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-08 Thread Matheus Izvekov via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd200db386378: [clang] template / auto deduction deduces 
common sugar (authored by mizvekov).

Changed prior to commit:
  https://reviews.llvm.org/D111283?vs=458587=458786#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp

Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-07 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

In D111283#3771900 , @erichkeane 
wrote:

> Thanks for your patience, this was a sizable review that it took a while to 
> be able to make time for.  A handful of non-functional reviews, but the 
> functionality looks fine.

Thanks, I appreciate the effort!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-07 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov marked an inline comment as done.
mizvekov added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12139
+return X;
+  assert(declaresSameEntity(X, Y));
+  for (const Decl *DX : X->redecls()) {

erichkeane wrote:
> As a nit, I'd prefer this assert above the 'if' above, that way it catches 
> Nulls in that case. It seems that the 'contract' for this function is no null 
> values, so we want to catch this ASAP.
Actually we want to handle the case they are both null, in which case we return 
null as well.
This case would trip the assert below, as `declaresSameEntity` considers that 
not the same entity.

For example, unconstrained AutoType will have null ConceptDecl.

In the D130308 patch, we add another variant, `getCommonDeclChecked, which 
requires non-null inputs, which can be used in places where non-null is 
required.

I went ahead and moved the introduction of `getCommonDeclChecked` to this 
patch, even though there is only one use of it.



Comment at: clang/lib/AST/ASTContext.cpp:12154
+T *getCommonDecl(T *X, T *Y) {
+  return cast_or_null(
+  getCommonDecl(const_cast(cast_or_null(X)),

erichkeane wrote:
> Do we REALLY need to tolerate  'null' here as well?  It seems we should do a 
> normal cast and have the cast assert.
Yes, as above.



Comment at: clang/lib/AST/ASTContext.cpp:12172
+
+static auto getCommonTypeArray(ASTContext , ArrayRef Xs,
+   ArrayRef Ys,

erichkeane wrote:
> Please comment these functions, it isn't clear on read through what you mean 
> by 'Array' here.  You probably mean for this to be something like 
> `getCommonTypes`.
Yeah that name works as well.



Comment at: clang/lib/AST/ASTContext.cpp:12241
+
+template  static auto *getCommonSizeExpr(T *X, T *Y) {
+  assert(X->getSizeExpr() == Y->getSizeExpr());

erichkeane wrote:
> I guess I don't see the po int of the next 3 functions?  There is no sugaring 
> or anything, AND they already assume they are the same 
> expression/element/etc? 
Well the point is to not repeat the assert in all use sites.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-07 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov edited the summary of this revision.
mizvekov updated this revision to Diff 458587.
mizvekov marked 5 inline comments as done.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- libcxx/DELETE.ME
+++ libcxx/DELETE.ME
@@ -1 +1,2 @@
 D133262
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-06 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

Thanks for your patience, this was a sizable review that it took a while to be 
able to make time for.  A handful of non-functional reviews, but the 
functionality looks fine.




Comment at: clang/lib/AST/ASTContext.cpp:12139
+return X;
+  assert(declaresSameEntity(X, Y));
+  for (const Decl *DX : X->redecls()) {

As a nit, I'd prefer this assert above the 'if' above, that way it catches 
Nulls in that case. It seems that the 'contract' for this function is no null 
values, so we want to catch this ASAP.



Comment at: clang/lib/AST/ASTContext.cpp:12154
+T *getCommonDecl(T *X, T *Y) {
+  return cast_or_null(
+  getCommonDecl(const_cast(cast_or_null(X)),

Do we REALLY need to tolerate  'null' here as well?  It seems we should do a 
normal cast and have the cast assert.



Comment at: clang/lib/AST/ASTContext.cpp:12172
+
+static auto getCommonTypeArray(ASTContext , ArrayRef Xs,
+   ArrayRef Ys,

Please comment these functions, it isn't clear on read through what you mean by 
'Array' here.  You probably mean for this to be something like `getCommonTypes`.



Comment at: clang/lib/AST/ASTContext.cpp:12204
+  }
+  llvm_unreachable("");
+}

Please give me a message here, just anything reasonably descriptive so that 
when it shows up I have something to grep.



Comment at: clang/lib/AST/ASTContext.cpp:12241
+
+template  static auto *getCommonSizeExpr(T *X, T *Y) {
+  assert(X->getSizeExpr() == Y->getSizeExpr());

I guess I don't see the po int of the next 3 functions?  There is no sugaring 
or anything, AND they already assume they are the same expression/element/etc? 



Comment at: clang/lib/AST/ASTContext.cpp:12323
+  case EST_NoThrow:
+llvm_unreachable("handled above");
+

something a little more unique in this (and others!) would be appreciated.



Comment at: clang/lib/AST/ASTContext.cpp:12116
+// If we reach the canonical declaration, then Y is older.
+if (DX->isCanonicalDecl())
+  return Y;

davrec wrote:
> I think "canonical" should be replaced with "first" here and 
> `isCanonicalDecl()` with `isFirstDecl()`.  So far as I can tell 
> `getCanonicalDecl()` returns `getFirstDecl()` everywhere for now, but that 
> could conceivably change, and in any case the goal of this code is to find 
> which is older, so "first" would be clearer as well.
For class types, canonical decl is usually the definition if one exists.  So I 
assume we do mean 'first' here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-05 Thread David Rector via Phabricator via cfe-commits
davrec accepted this revision.
davrec added a comment.

I hope I'm not stepping on any toes given the recent changes in code ownership, 
but I'm accepting this and D130308  because

1. They are a nice improvement to the AST that naturally follows from the 
earlier work adding sugar to type deductions,
2. I have given it a fairly close look and it LGTM,
3. @rsmith has taken a step back and so may not be available to give it a final 
look,
4. @mizvekov has verified that the performance impact is negligible, and
5. Other reviewers seem to have at least given it a once over and have not 
identified major issues.

Anyone object/need more time to review?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-01 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added inline comments.



Comment at: clang/include/clang/AST/ASTContext.h:2819-2823
+  // For two canonically equal types, return a type which has
+  // the common sugar between them. If Unqualified is true,
+  // both types need only be the same unqualified type.
+  // The result will drop the qualifiers which do not occur
+  // in both types.

ChuanqiXu wrote:
> For this comment, I want to know what if `X`and `Y` is not equal. Is there an 
> assertion failure or special type returned?
Assertion failure, the function is supposed to handle only the case where 
`hasSame[Unqualified]Type(X, Y) == true`.

It will always return a type `R` for which `hasSame[Unqualified]Type(R, Y) == 
true` also holds, so there are no special return values.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-09-01 Thread Chuanqi Xu via Phabricator via cfe-commits
ChuanqiXu added inline comments.



Comment at: clang/include/clang/AST/ASTContext.h:2819-2823
+  // For two canonically equal types, return a type which has
+  // the common sugar between them. If Unqualified is true,
+  // both types need only be the same unqualified type.
+  // The result will drop the qualifiers which do not occur
+  // in both types.

For this comment, I want to know what if `X`and `Y` is not equal. Is there an 
assertion failure or special type returned?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-28 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 456196.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-28 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

llvm-compile-time-tracker stats for this patch: 
http://llvm-compile-time-tracker.com/compare.php?from=f7a33090a91015836497c75f173775392ab0304d=771076b836b331f50f8a852fba1353aa60865e30=instructions

For the next one on the stack, which hooks the new mechanism here to more 
places: 
http://llvm-compile-time-tracker.com/compare.php?from=771076b836b331f50f8a852fba1353aa60865e30=56a1894e70ff387d0b7791564a12a5879655c86f=instructions

For the one after that, which extends this mechanism to cover sugar nodes: 
http://llvm-compile-time-tracker.com/compare.php?from=56a1894e70ff387d0b7791564a12a5879655c86f=96a13ce3e1776de824585182603f01258332d2c8=instructions

They all look to be within what you would expect from noise alone.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-21 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov edited the summary of this revision.
mizvekov updated this revision to Diff 454303.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-18 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

In D111283#3733415 , @v.g.vassilev 
wrote:

> Thanks for working on this! I left some comments. I did not look very deep in 
> the patch but it seems quite consistent to the rest of the code in Sema.

Thanks!

> Can you provide some performance numbers for this patch. I believe that the 
> less confident reviewers will be more comfortable letting that patch in.

Yeah, sounds good.




Comment at: clang/lib/AST/ASTContext.cpp:12129
+  return cast_or_null(
+  getCommonDecl(const_cast(cast_or_null(X)),
+const_cast(cast_or_null(Y;

v.g.vassilev wrote:
> Maybe `getCommonDecl` should take `const Decl*` instead of `const_cast`-ing 
> here.
If getCommonDecl took `const Decl`, I believe I would still need to 
`const_cast` to `const Decl *` anyway, because otherwise we would end up in 
infinite recursion into this function template.

And I would then in addition need to const_cast in the return value, which 
would make the whole thing more complicated.



Comment at: clang/lib/AST/ASTContext.cpp:12408
+  case Type::BlockPointer: {
+const auto *PX = cast(X), *PY = 
cast(Y);
+return Ctx.getBlockPointerType(getCommonPointeeType(Ctx, PX, PY));

v.g.vassilev wrote:
> Defining decl groups does not seem common in the llvm/clang codebase. I don't 
> think we have a specific rule discouraging that. However, I think stepping 
> through with a debugger will be harder. Maybe make this and other occurrences 
> more consistent to the rest of the codebase?
Though in these cases the expression is just a cast, you would so rarely need 
to step into them as there is very little interesting going on in there.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-18 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 453824.
mizvekov marked an inline comment as done.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-18 Thread Vassil Vassilev via Phabricator via cfe-commits
v.g.vassilev added a comment.

Thanks for working on this! I left some comments. I did not look very deep in 
the patch but it seems quite consistent to the rest of the code in Sema.

Can you provide some performance numbers for this patch. I believe that the 
less confident reviewers will be more comfortable letting that patch in. I 
think this work is important and should be merged before GSoC ends. It will 
allow clang to diagnose better errors in template instantiations even for cases 
such as llvm.org/PR12853




Comment at: clang/lib/AST/ASTContext.cpp:12129
+  return cast_or_null(
+  getCommonDecl(const_cast(cast_or_null(X)),
+const_cast(cast_or_null(Y;

Maybe `getCommonDecl` should take `const Decl*` instead of `const_cast`-ing 
here.



Comment at: clang/lib/AST/ASTContext.cpp:12172
+return TemplateArgument(
+Ctx.getCommonSugaredType(X.getNullPtrType(), Y.getNullPtrType()), 
true);
+  default:





Comment at: clang/lib/AST/ASTContext.cpp:12408
+  case Type::BlockPointer: {
+const auto *PX = cast(X), *PY = 
cast(Y);
+return Ctx.getBlockPointerType(getCommonPointeeType(Ctx, PX, PY));

Defining decl groups does not seem common in the llvm/clang codebase. I don't 
think we have a specific rule discouraging that. However, I think stepping 
through with a debugger will be harder. Maybe make this and other occurrences 
more consistent to the rest of the codebase?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-18 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov marked 3 inline comments as done.
mizvekov added a comment.

In D111283#3721905 , @davrec wrote:

> But instead of defining it and getting into details it might be clearer, and 
> certainly would have saved me the most time, for the description to simply 
> note that this patch introduces `ASTContext::getCommonSugaredType(QualType X, 
> QualType Y, bool Unqualified = false)`, and puts it to use in type deduction 
> for binary expressions etc., and give an example or two to demonstrate.  
> (More generally on a large patch I prefer a description to give me a few 
> starting points, the primary changes which necessitate all the others.)

Done, thanks for the feedback!

> Re the patch itself: it looks good to me other than a few nits, but this has 
> such a broad and deep span (intricate details of the AST + intricate details 
> of Sema) it is difficult to give it a final thumbs up - really hoping @rsmith 
> might take a final look.  But if time runs out it is definitely worth 
> accepting as is and seeing how it goes; the benefits exceed the risks.  I 
> will try to take a close look at the other patches on your stack, but the 
> same probably applies.  You've done a tremendous amount of work here, very 
> impressive.

Yeah, but we made good progress here, thanks again!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-18 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov edited the summary of this revision.
mizvekov updated this revision to Diff 453779.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-14 Thread David Rector via Phabricator via cfe-commits
davrec added a comment.

> The second paragraph is talking about 'Canonical nodes', not 'Canonical 
> types'.
>
> A canonical node is a type node for which 'isSugared' method returns false.

Thanks for the clarification, but note that that term is not in general use so 
far as I'm aware.   But instead of defining it and getting into details it 
might be clearer, and certainly would have saved me the most time, for the 
description to simply note that this patch introduces 
`ASTContext::getCommonSugaredType(QualType X, QualType Y, bool Unqualified = 
false)`, and puts it to use in type deduction for binary expressions etc., and 
give an example or two to demonstrate.  (More generally on a large patch I 
prefer a description to give me a few starting points, the primary changes 
which necessitate all the others.)

Re the patch itself: it looks good to me other than a few nits, but this has 
such a broad and deep span (intricate details of the AST + intricate details of 
Sema) it is difficult to give it a final thumbs up - really hoping @rsmith 
might take a final look.  But if time runs out it is definitely worth accepting 
as is and seeing how it goes; the benefits exceed the risks.  I will try to 
take a close look at the other patches on your stack, but the same probably 
applies.  You've done a tremendous amount of work here, very impressive.




Comment at: clang/include/clang/AST/ASTContext.h:2807
 
+  FunctionProtoType::ExceptionSpecInfo
+  getCommonExceptionSpec(FunctionProtoType::ExceptionSpecInfo ESI1,

A clearer name might be `combineExceptionSpecs`, or the original 
`mergeExceptionSpecs`, since this is getting the union of their sets of 
exception specs, whereas getCommon* suggests getting the intersection, e.g. 
getCommonSugaredType is getting the intersection of two "sets" of type sugar in 
a sense.  

Also, please add some brief documentation to the function.



Comment at: clang/include/clang/AST/ASTContext.h:2825
+  // the common sugared type between them.
+  void mergeTypeLists(SmallVectorImpl , ArrayRef X,
+  ArrayRef Y);

Any reason this is public?  Or in the header at all?  Seems like it could be a 
static function in the cpp.



Comment at: clang/lib/AST/ASTContext.cpp:12116
+// If we reach the canonical declaration, then Y is older.
+if (DX->isCanonicalDecl())
+  return Y;

I think "canonical" should be replaced with "first" here and 
`isCanonicalDecl()` with `isFirstDecl()`.  So far as I can tell 
`getCanonicalDecl()` returns `getFirstDecl()` everywhere for now, but that 
could conceivably change, and in any case the goal of this code is to find 
which is older, so "first" would be clearer as well.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-11 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

In D111283#3716104 , @davrec wrote:

> The first paragraph says X and Y must have the same canonical type, the 
> second suggests they need not.

The first paragraph is talking about canonical equality, or if you take it that 
types 'refer' to their canonical types, referential equality.
Ie 'X.getCanonicalType() == Y.getCanonicalType()'

For short, when there is referential equality, I will say that the types are 
'the same'. This matches terminology in Clang, for example see the helper 
ASTContext::hasSameType.

When there is structural equality, ie 'X == Y', I will say for short the types 
are 'identical'.

The second paragraph is talking about 'Canonical nodes', not 'Canonical types'.

A canonical node is a type node for which 'isSugared' method returns false.
This is not the same thing as saying that a Canonical node is a canonical type.

For example, 'PointerType' nodes are always canonical nodes, because it has an 
'isSugared' implementation which always returns false:

  bool isSugared() const { return false; }

But pointer types can be non-canonical, in particular when the PointeeType is 
not a canonical type.

In D111283#3716104 , @davrec wrote:

> In all the test cases, they have the same canonical type.

Well not exactly, we also handle and test the case they are also the same when 
'unqualified'.

The case here is function types that differ only in top-level qualifiers of 
parameters, so this is used only when we are recursing down a FunctionType.

Those FunctionTypes should be treated as the same, ie you can't overload based 
on differences in top-level qualifiers of function parameters.
But this should not be treated as a semantic adjustment, like we do for decays, 
eg in array parameters, because we still need to consider those qualifiers on 
the parameter itself within the function definition, unlike what happens with 
decays (where we basically just rewrite the type of the parameter).

See the `t8` and `t11` test cases in `clang/test/SemaCXX/sugared-auto.cpp`, 
which test top-level differences in const and ObjectiveC lifetime qualifiers 
respectively.

> IIUC the second paragraph only applies to the stuff done in D130308 
> ; is that correct?

No, it's talking about the stuff in this patch.

In this patch, we unify Canonical nodes that differ, but don't unify different 
non-canonical nodes (ie those which 'isSugared()' returns true), that last part 
is done in D130308 .

> If so, the description should clearly state this patch only handles the case 
> when the canonical types of X and Y are identical, and note that if the 
> canonical types of X and Y differ, this patch does nothing, but D130308 
>  adds some additional logic to search for 
> common sugar in child type nodes of X and Y to use in the merged type.

Well it's not that we do nothing if the types are not the same!
That the inputs should be the same (but not necessaritly identical) is an 
invariant, ie a contract to use this function.
In a debug build, we will check that this invariant is respected, asserting 
otherwise.

> And of course please add a full description to D130308 
>  as well when you have a chance.

Sure.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-11 Thread David Rector via Phabricator via cfe-commits
davrec added a comment.

This part of the description is confusing:

> We take two types, X and Y, which we wish to unify as input.
> These types must have the same (qualified or unqualified) canonical
> type.
>
> We dive down fast through top-level type sugar nodes, to the
> underlying canonical node. If these canonical nodes differ, we
> build a common one out of the two, unifying any sugar they had.
> Note that this might involve a recursive call to unify any children
> of those. We then return that canonical node, handling any qualifiers.
>
> If they don't differ, we walk up the list of sugar type nodes we dived
> through, finding the last identical pair, and returning that as the
> result, again handling qualifiers.

The first paragraph says X and Y must have the same canonical type, the second 
suggests they need not.  In all the test cases, they have the same canonical 
type.

IIUC the second paragraph only applies to the stuff done in D130308 
; is that correct?

If so, the description should clearly state this patch only handles the case 
when the canonical types of X and Y are identical, and note that if the 
canonical types of X and Y differ, this patch does nothing, but D130308 
 adds some additional logic to search for 
common sugar in child type nodes of X and Y to use in the merged type.

And of course please add a full description to D130308 
 as well when you have a chance.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-11 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

In D111283#3712348 , @erichkeane 
wrote:

> This is a sizable patch, and it isn't really clear from context what I'm 
> looking at.  Can you please improve the description/commit message to better 
> clarify what you are trying to do, what you did, and how you are trying to 
> accomplish it?

Updated description, also, for reference, the other patches that continue this 
work are D111509  and D130308 
.

Thanks for taking a look!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-11 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov edited the summary of this revision.
mizvekov updated this revision to Diff 451799.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-08-10 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

This is a sizable patch, and it isn't really clear from context what I'm 
looking at.  Can you please improve the description/commit message to better 
clarify what you are trying to do, what you did, and how you are trying to 
accomplish it?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-27 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 447973.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-23 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 447086.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-18 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 445647.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-18 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 445635.
mizvekov marked an inline comment as done.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++14 -fms-extensions -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec -Wno-c++17-compat-mangling
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +17,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +53,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +72,160 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  static_assert(__is_same(A, B), ""); \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-17 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:11578
+  default:
+return X;
+  }

rsmith wrote:
> mizvekov wrote:
> > rsmith wrote:
> > > For `TemplateArgument::ArgKind::Declaration`, I think it'd make sense to 
> > > take the common type of the `getParamTypeForDecl`s.
> > Yeah, but this has been dead code since we went back to canonical template 
> > parameter / arguments.
> > I have removed it and put some unreachables in place.
> > We will circle back around to add it with this suggestion later.
> This will need to deal with all the cases that can arrive here. If it sees 
> resolved template arguments, then this includes `Type`, `Declaration`, 
> `NullPtr`, `Integral`, `Template`, `TemplateExpansion`, and `Pack`. If it 
> sees unresolved template arguments, then this includes at least `Type`, 
> `Expression`, `Template`, and `TemplateExpansion`. This function currently 
> doesn't cover either set, so I strongly suspect that this `llvm_unreachable` 
> is actually reachable.
> 
> Can we just `return X;` on all the cases we don't currently handle?
Yeah I will just return X for the peace of mind for now, but I think what is 
happening here is that we only see unresolved template arguments, so we would 
theoretically be missing the handling of Template and TemplateExpansion cases.

The problem is, I think we are not actually preserving type sugar of those two 
cases, because of a profiling bug.
I pointed this problem out recently in this revision: 
https://reviews.llvm.org/D126172

So this is probably pretty hard to test right now, and we would not even get 
any results from handling it, so I will
leave a FIXME instead.



Comment at: clang/lib/AST/ASTContext.cpp:12378-12379
+
+if (EPIX.EllipsisLoc != EPIY.EllipsisLoc)
+  EPIX.EllipsisLoc = SourceLocation();
+EPIX.HasTrailingReturn = EPIX.HasTrailingReturn && EPIY.HasTrailingReturn;

rsmith wrote:
> Can we cope with a variadic function with no ellipsis location? I'd expect 
> that to confuse some parts of Clang. Picking one of the two arbitrarily isn't 
> great but may be the best we can do.
> Can we cope with a variadic function with no ellipsis location? I'd expect 
> that to confuse some parts of Clang. Picking one of the two arbitrarily isn't 
> great but may be the best we can do.

Will leave that out for now with a FIXME.



Comment at: clang/lib/Sema/SemaTemplateDeduction.cpp:4715-4716
+ "substituting template parameter for 'auto' failed");
+  if (!Result.isNull())
+Deduced[0] = DeducedTemplateArgument(Result);
+  if (auto TDK = DeduceTemplateArgumentsFromCallArgument(

rsmith wrote:
> I do like this approach to repeated deduction, but I'm not sure that it 
> actually works. For example:
> 
> ```
> void f();
> void g();
> void g(int);
> auto h(bool b) {
>   if (b) return f;
>   return g;
> }
> ```
> I think this is required to fail to compile, because we can't deduce the 
> return type from the returned expression `g`. But I think what will happen 
> here is that we'll say that `g` is a non-deduced context and then succeed 
> because we pre-populated the deduced type from the `void(*)()` from `f`.
> 
> Instead, how about not pre-populating `Deduced[0]`, and instead "deducing" 
> the template parameter from `Result` after we check for the `TDK_Incomplete` 
> case below? That should still let us reuse the logic for merging deductions.
Nice find. We don't actually need to repeat the deduction. We only need to 
return Inconsistent deduction if Result and Deduced[0] are different, and get 
the common sugar otherwise.

We already had to do so for the `decltype(auto)` case, and we could have 
totally resugared the initializer lists but forgot as you pointed out, and we 
had to make this same check for that case anyway.

So I combined all these cases, further simplifying things, and added the new 
test case for initializer_list.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-17 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 445364.
mizvekov marked 9 inline comments as done.
Herald added subscribers: usaxena95, kadircet, arphaman.
Herald added a project: clang-tools-extra.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang-tools-extra/clangd/unittests/ASTTests.cpp
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +16,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +52,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +71,134 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-17 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 445358.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec
+
+namespace std {
+template struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
 
 enum class N {};
 
@@ -9,6 +16,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -25,6 +52,9 @@
 N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
 N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
 
+auto x6 = { Man(), Dog() };
+N t6 = x6; // expected-error {{from 'std::initializer_list' (aka 'initializer_list')}}
+
 } // namespace variable
 
 namespace function_basic {
@@ -41,3 +71,134 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^__strong)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-12 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov marked 2 inline comments as done.
mizvekov added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12225-12227
+#define NON_CANONICAL_TYPE(Class, Base) UNEXPECTED_TYPE(Class, "non-canonical")
+#define TYPE(Class, Base)
+#include "clang/AST/TypeNodes.inc"

rsmith wrote:
> What guarantees that we won't see never-canonical types here?
> 
> I understand why we won't see sugar-free types (we can't have two `Type*`s 
> that are different but represent the same type if they're sugar-free), and 
> why we won't see non-unique types here (we can't have two `Type*`s that are 
> different but represent the same type if they're not uniqued). But why can't 
> we find, say, two different `TypedefType`s here that desugar to the same type?
The idea is that this function is only called from a context where 
removeDifferentTopLevelSugar / unwrapSugar will have removed all top-level 
nodes which are sugar. So in particular, we will never see here any type nodes 
which have an implementation for is isSugared which always returns true, such 
as the TypedefType case.

So this is peculiar to this initial implementation, which never tries to 
"merge" sugar nodes.
There is value in trying to merge those, but you can imagine that the 
implementation for that is much more complicated and needs more thinking to get 
right and efficient.

For example for the TypedefType case right now:

If we had two different typedefs with the same underlying type, then there 
seems to be no sensible choice here except stripping off the typedef, I mean 
what Decl would we put on the TypedefType? Right now nullptr would not work 
since we always take the underlying type from the Decl, but even if it did, the 
value of having a nullptr decl seems questionable given the amount of trouble 
this could cause in other code.

If the TypedefTypes pointed to the same TypedefDecl, then it would make sense 
to create a new one with the "common" Decl between them, such as the earliest 
declaration or the canonical one, but might not be worth the extra complexity 
in the overall logic just for this effect.

Note that on my D127695, I implemented resugared TypedefTypes, which can have a 
different (but canonically the same) underlying type. With that, we would have 
more to do here and I think then it would be worth improving this further.

Otherwise, there is other interesting sugar we could try merging in the future 
as well, such as ElaboratedType and alias TemplateSpecializationTypes.



Comment at: clang/lib/AST/ASTContext.cpp:12253-12254
+const auto *AX = cast(X), *AY = cast(Y);
+assert(AX->getDeducedType().isNull());
+assert(AY->getDeducedType().isNull());
+assert(AX->getKeyword() == AY->getKeyword());

rsmith wrote:
> I don't understand why the deduced type must be null here. I think it usually 
> will be, because if the deduced type were non-null, it would have to be 
> identical (because we know desugaring one more level results in identical 
> types), and in that case we'd typically have produced the same `AutoType`. 
> But it seems like we could have two constrained `AutoType`s here that desugar 
> to the same type but differ in the spelling of their constraints, in which 
> case the common type should presumably have a deduced type. I wonder if we 
> should just be checking `AX->getDeducedType() == AY->getDeducedType()` here 
> and passing in `AX->getDeducedType()` as the deduced type below?
Well if they desugared to anything, then they would never show up in this 
function, they would have been stripped off by unwrapSugar as I explained in 
the previous comment.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-12 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

In D111283#3646066 , @Mordante wrote:

> The libc++ build failures are due a broken libc++ HEAD. The current HEAD 
> should work again.

Thanks for letting me know! Pushed my patches again just to have a look at the 
result, haven't made any changes yet.

And Richard, tons of thanks again for the review!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-12 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 444065.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
@@ -9,6 +9,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -41,3 +61,123 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^__strong)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
+
+using fp3 = SARS (*)() throw(Man);
+using fp4 = Ebola (*)() throw(Vibrio);
+auto t7(fp3 a, fp4 b) {
+  if (false)
+return true ? a : b;
+  if (false)
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}
+
+using fp5 = void (*)(const Man);
+using fp6 = void (*)(Dog);
+TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced as 'void (*)(Animal)' (aka 'void (*)(int)')}}
+
+using fp7 = void (*)(ConstMan);
+using 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-12 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:12177
+return X;
+  assert(X->getCanonicalDecl() == Y->getCanonicalDecl());
+  // FIXME: Could return the earliest declaration between those two.





Comment at: clang/lib/AST/ASTContext.cpp:12205
+  llvm::DenseMap Found;
+  for (auto Ts : {X, Y})
+for (QualType T : Ts) {

Please add braces to this outer  `for`.



Comment at: clang/lib/AST/ASTContext.cpp:12225-12227
+#define NON_CANONICAL_TYPE(Class, Base) UNEXPECTED_TYPE(Class, "non-canonical")
+#define TYPE(Class, Base)
+#include "clang/AST/TypeNodes.inc"

What guarantees that we won't see never-canonical types here?

I understand why we won't see sugar-free types (we can't have two `Type*`s that 
are different but represent the same type if they're sugar-free), and why we 
won't see non-unique types here (we can't have two `Type*`s that are different 
but represent the same type if they're not uniqued). But why can't we find, 
say, two different `TypedefType`s here that desugar to the same type?



Comment at: clang/lib/AST/ASTContext.cpp:12253-12254
+const auto *AX = cast(X), *AY = cast(Y);
+assert(AX->getDeducedType().isNull());
+assert(AY->getDeducedType().isNull());
+assert(AX->getKeyword() == AY->getKeyword());

I don't understand why the deduced type must be null here. I think it usually 
will be, because if the deduced type were non-null, it would have to be 
identical (because we know desugaring one more level results in identical 
types), and in that case we'd typically have produced the same `AutoType`. But 
it seems like we could have two constrained `AutoType`s here that desugar to 
the same type but differ in the spelling of their constraints, in which case 
the common type should presumably have a deduced type. I wonder if we should 
just be checking `AX->getDeducedType() == AY->getDeducedType()` here and 
passing in `AX->getDeducedType()` as the deduced type below?



Comment at: clang/lib/AST/ASTContext.cpp:12327-12328
+return Ctx.getLValueReferenceType(getCommonPointeeType(Ctx, PX, PY),
+  PX->isSpelledAsLValue() &&
+  PY->isSpelledAsLValue());
+  }

If either of them was spelled as an lvalue then the pointee type was spelled as 
either an lvalue reference or a non-reference for that input type, and we'll 
strip off the spelling-as-rvalue-reference part of the other type when finding 
the common type. The only case in which I think it makes sense to retain the 
"spelled as rvalue" flag would be if *both* sides were lvalue references 
spelled as rvalue references.



Comment at: clang/lib/AST/ASTContext.cpp:12378-12379
+
+if (EPIX.EllipsisLoc != EPIY.EllipsisLoc)
+  EPIX.EllipsisLoc = SourceLocation();
+EPIX.HasTrailingReturn = EPIX.HasTrailingReturn && EPIY.HasTrailingReturn;

Can we cope with a variadic function with no ellipsis location? I'd expect that 
to confuse some parts of Clang. Picking one of the two arbitrarily isn't great 
but may be the best we can do.



Comment at: clang/lib/AST/ASTContext.cpp:12464
+TY->getTemplateName()),
+As, QualType(TX, 0));
+  }

No-op change, but this would make it a bit more obvious to a reader why it's OK 
to pass in `TX` here.



Comment at: clang/lib/AST/ASTContext.cpp:11578
+  default:
+return X;
+  }

mizvekov wrote:
> rsmith wrote:
> > For `TemplateArgument::ArgKind::Declaration`, I think it'd make sense to 
> > take the common type of the `getParamTypeForDecl`s.
> Yeah, but this has been dead code since we went back to canonical template 
> parameter / arguments.
> I have removed it and put some unreachables in place.
> We will circle back around to add it with this suggestion later.
This will need to deal with all the cases that can arrive here. If it sees 
resolved template arguments, then this includes `Type`, `Declaration`, 
`NullPtr`, `Integral`, `Template`, `TemplateExpansion`, and `Pack`. If it sees 
unresolved template arguments, then this includes at least `Type`, 
`Expression`, `Template`, and `TemplateExpansion`. This function currently 
doesn't cover either set, so I strongly suspect that this `llvm_unreachable` is 
actually reachable.

Can we just `return X;` on all the cases we don't currently handle?



Comment at: clang/lib/AST/ASTContext.cpp:11861
+   *IY = cast(Y);
+assert(IX->getDecl() == IY->getDecl());
+return Ctx.getInjectedClassNameType(

mizvekov wrote:
> rsmith wrote:
> > I think this should probably be a `declaresSameEntity` check: we might be 
> > comparing injected class names from two different merged modules with two 
> > 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-12 Thread Mark de Wever via Phabricator via cfe-commits
Mordante added a comment.

The libc++ build failures are due a broken libc++ HEAD. The current HEAD should 
work again.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-11 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 443749.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
@@ -9,6 +9,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -41,3 +61,123 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^__strong)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
+
+using fp3 = SARS (*)() throw(Man);
+using fp4 = Ebola (*)() throw(Vibrio);
+auto t7(fp3 a, fp4 b) {
+  if (false)
+return true ? a : b;
+  if (false)
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}
+
+using fp5 = void (*)(const Man);
+using fp6 = void (*)(Dog);
+TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced as 'void (*)(Animal)' (aka 'void (*)(int)')}}
+
+using fp7 = void (*)(ConstMan);
+using 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-11 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 443734.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
@@ -9,6 +9,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -41,3 +61,123 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^__strong)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
+
+using fp3 = SARS (*)() throw(Man);
+using fp4 = Ebola (*)() throw(Vibrio);
+auto t7(fp3 a, fp4 b) {
+  if (false)
+return true ? a : b;
+  if (false)
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}
+
+using fp5 = void (*)(const Man);
+using fp6 = void (*)(Dog);
+TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced as 'void (*)(Animal)' (aka 'void (*)(int)')}}
+
+using fp7 = void (*)(ConstMan);
+using 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-11 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:11551-11552
+if (Unqualified && !Ctx.hasSameType(X, Y)) {
+  assert(Ctx.hasSameUnqualifiedType(X, Y));
+  auto XQuals = X.getCVRQualifiers(), YQuals = Y.getCVRQualifiers();
+  X.addFastQualifiers(YQuals & ~XQuals);

rsmith wrote:
> What should happen if there's a qualifier difference other than a CVR 
> qualifier? Eg, address space or ObjC lifetime.
I have updated the `ASContext::getCommonSugaredType` to accept an `Unqualified` 
parameter to handle this case.
We will strip qualifiers from each other until the types are the same.



Comment at: clang/lib/AST/ASTContext.cpp:11578
+  default:
+return X;
+  }

rsmith wrote:
> For `TemplateArgument::ArgKind::Declaration`, I think it'd make sense to take 
> the common type of the `getParamTypeForDecl`s.
Yeah, but this has been dead code since we went back to canonical template 
parameter / arguments.
I have removed it and put some unreachables in place.
We will circle back around to add it with this suggestion later.



Comment at: clang/lib/AST/ASTContext.cpp:11790-11801
+if (EPIX.ExceptionSpec.Exceptions.size() ==
+EPIY.ExceptionSpec.Exceptions.size()) {
+  auto E = getCommonTypeArray(Ctx, EPIX.ExceptionSpec.Exceptions,
+  EPIY.ExceptionSpec.Exceptions);
+  EPIX.ExceptionSpec.Exceptions = E;
+  return Ctx.getFunctionType(R, P, EPIX);
+} else {

rsmith wrote:
> This seems a bit suspicious: `getCommonTypeArray` assumes the two arrays 
> contain the same types in the same order, but if the arrays can be different 
> sizes, is it really correct to assume that they contain the same types if 
> they're the same size?
> 
> Can we make this work the same way that the conditional expression handling 
> deals with differing lists of exception types?
Handled this with a new `ASTContext::mergeTypeLists` that does what the 
conditional expression handling did, while getting the common sugar of types 
when they occur in both lists.



Comment at: clang/lib/AST/ASTContext.cpp:11861
+   *IY = cast(Y);
+assert(IX->getDecl() == IY->getDecl());
+return Ctx.getInjectedClassNameType(

rsmith wrote:
> I think this should probably be a `declaresSameEntity` check: we might be 
> comparing injected class names from two different merged modules with two 
> different declarations for the same class definition. The right declaration 
> to use is the one that is chosen to be "the" definition.
Implemented this with a new getCommonDecl function, which for now will just 
fall back to the canonical decl if they differ.

Wonder if there is a cheap way to determine which of the two decls was declared 
earlier. Have to look this up, but would a simple pointer comparison be 
guaranteed to work? Eg would the earliest declaration, since being created 
earlier and allocated earlier, be guaranteed by design to have a lower (or 
greater) pointer value?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-07-11 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov edited the summary of this revision.
mizvekov updated this revision to Diff 443731.
mizvekov marked 2 inline comments as done.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify -xobjective-c++ %s -std=c++20 -fblocks -fobjc-arc -fobjc-runtime-has-weak -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
@@ -9,6 +9,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -41,3 +61,123 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^__strong)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
+
+using fp3 = SARS (*)() throw(Man);
+using fp4 = Ebola (*)() throw(Vibrio);
+auto t7(fp3 a, fp4 b) {
+  if (false)
+return true ? a : b;
+  if (false)
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}
+
+using fp5 = void (*)(const Man);
+using fp6 = void (*)(Dog);
+TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-05-26 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 432339.
mizvekov added a comment.

- Just rebase, no review comments addressed yet.
- One small churn in test/SemaCXX/deduced-return-void.cpp, which is new since 
last rebase. As this patch uses the template deduction machinery to also handle 
the mutiple return statements, we detect the inconsistent deduction before 
substitution, so we don't error out trying to form the reference to void.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/deduced-return-void.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
@@ -9,6 +9,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -41,3 +61,115 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
+
+using fp3 = SARS (*)() throw(Man);
+using fp4 = Ebola (*)() throw(Vibrio);
+auto t7(fp3 a, fp4 b) {
+  if (false)
+return true ? a : b;
+  if (false)
+return a;
+  

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2022-05-24 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.
Herald added a project: All.



Comment at: clang/lib/AST/ASTContext.cpp:11551-11552
+if (Unqualified && !Ctx.hasSameType(X, Y)) {
+  assert(Ctx.hasSameUnqualifiedType(X, Y));
+  auto XQuals = X.getCVRQualifiers(), YQuals = Y.getCVRQualifiers();
+  X.addFastQualifiers(YQuals & ~XQuals);

What should happen if there's a qualifier difference other than a CVR 
qualifier? Eg, address space or ObjC lifetime.



Comment at: clang/lib/AST/ASTContext.cpp:11578
+  default:
+return X;
+  }

For `TemplateArgument::ArgKind::Declaration`, I think it'd make sense to take 
the common type of the `getParamTypeForDecl`s.



Comment at: clang/lib/AST/ASTContext.cpp:11603
+ ? X->getQualifier()
+ : Ctx.getCanonicalNestedNameSpecifier(X->getQualifier());
+}

Might be worth adding a `FIXME` to keep as much common NNS sugar as we can?



Comment at: clang/lib/AST/ASTContext.cpp:11632-11633
+
+static QualType getCommonCanonicalType(ASTContext , const Type *X,
+   const Type *Y) {
+  Type::TypeClass TC = X->getTypeClass();

I don't understand this function name: there's only one canonical 
representation of a type, so this seems paradoxical. I think 
`getCommonDesugaredType` is probably a clearer name for what this is doing.



Comment at: clang/lib/AST/ASTContext.cpp:11790-11801
+if (EPIX.ExceptionSpec.Exceptions.size() ==
+EPIY.ExceptionSpec.Exceptions.size()) {
+  auto E = getCommonTypeArray(Ctx, EPIX.ExceptionSpec.Exceptions,
+  EPIY.ExceptionSpec.Exceptions);
+  EPIX.ExceptionSpec.Exceptions = E;
+  return Ctx.getFunctionType(R, P, EPIX);
+} else {

This seems a bit suspicious: `getCommonTypeArray` assumes the two arrays 
contain the same types in the same order, but if the arrays can be different 
sizes, is it really correct to assume that they contain the same types if 
they're the same size?

Can we make this work the same way that the conditional expression handling 
deals with differing lists of exception types?



Comment at: clang/lib/AST/ASTContext.cpp:11861
+   *IY = cast(Y);
+assert(IX->getDecl() == IY->getDecl());
+return Ctx.getInjectedClassNameType(

I think this should probably be a `declaresSameEntity` check: we might be 
comparing injected class names from two different merged modules with two 
different declarations for the same class definition. The right declaration to 
use is the one that is chosen to be "the" definition.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-11-16 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 387566.
mizvekov added a comment.

.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test 5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
@@ -9,6 +9,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -41,3 +61,115 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
+
+using fp3 = SARS (*)() throw(Man);
+using fp4 = Ebola (*)() throw(Vibrio);
+auto t7(fp3 a, fp4 b) {
+  if (false)
+return true ? a : b;
+  if (false)
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}
+
+using fp5 = void (*)(const Man);
+using fp6 = void (*)(Dog);
+TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
+
+using fp6 = void (*)(ConstMan);
+using fp7 = void (*)(ConstDog);
+TEST_AUTO(t10, fp6, fp7); // 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-11-16 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 387554.
mizvekov added a comment.

- Fix rebuilding Template Specializations


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  clang/test/SemaTemplate/deduction.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaTemplate/deduction.cpp
===
--- clang/test/SemaTemplate/deduction.cpp
+++ clang/test/SemaTemplate/deduction.cpp
@@ -162,6 +162,15 @@
 
 } // namespace test4
 
+namespace test5 {
+
+template  class a {};
+template  void c(b, b);
+template  void c(a, a);
+void d() { c(a(), a()); }
+
+} // namespace test 5
+
 // Verify that we can deduce enum-typed arguments correctly.
 namespace test14 {
   enum E { E0, E1 };
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
@@ -9,6 +9,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -41,3 +61,115 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
+
+using fp3 = SARS (*)() throw(Man);
+using fp4 = Ebola (*)() throw(Vibrio);
+auto t7(fp3 a, fp4 b) {
+  if (false)
+return true ? a : b;
+  if (false)
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}
+
+using fp5 = void (*)(const Man);
+using fp6 = void (*)(Dog);
+TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
+
+using fp6 = void (*)(ConstMan);
+using fp7 = void 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-11-15 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 387404.
mizvekov added a comment.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

- Add `libcxx/DELETE.ME` to trigger libcxx CI.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D111283
Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
@@ -9,6 +9,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -41,3 +61,115 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
+
+using fp3 = SARS (*)() throw(Man);
+using fp4 = Ebola (*)() throw(Vibrio);
+auto t7(fp3 a, fp4 b) {
+  if (false)
+return true ? a : b;
+  if (false)
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}
+
+using fp5 = void (*)(const Man);
+using fp6 = void (*)(Dog);
+TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
+
+using fp6 = void (*)(ConstMan);
+using fp7 = void (*)(ConstDog);
+TEST_AUTO(t10, fp6, fp7); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
+
+TEST_AUTO(t11, Man Angiosperm::*, Dog Gymnosperm::*) // expected-error {{but deduced as 'Animal Plant::*'}}
+
+TEST_DAUTO(t12, const Man &, const Dog &) // expected-error {{but deduced as 'const Animal &' (aka 'const int &')}}
+
+TEST_DAUTO(t13, Man &&, Dog &&) // expected-error {{but deduced as 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-31 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 383653.
mizvekov added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp

Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
@@ -9,6 +9,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -41,3 +61,115 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
+
+using fp3 = SARS (*)() throw(Man);
+using fp4 = Ebola (*)() throw(Vibrio);
+auto t7(fp3 a, fp4 b) {
+  if (false)
+return true ? a : b;
+  if (false)
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}
+
+using fp5 = void (*)(const Man);
+using fp6 = void (*)(Dog);
+TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
+
+using fp6 = void (*)(ConstMan);
+using fp7 = void (*)(ConstDog);
+TEST_AUTO(t10, fp6, fp7); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
+
+TEST_AUTO(t11, Man Angiosperm::*, Dog Gymnosperm::*) // expected-error {{but deduced as 'Animal Plant::*'}}
+
+TEST_DAUTO(t12, const Man &, const Dog &) // expected-error {{but deduced as 'const Animal &' (aka 'const int &')}}
+
+TEST_DAUTO(t13, Man &&, Dog &&) // expected-error {{but deduced as 'Animal &&' (aka 'int &&')}}
+
+using matrix_man = Man __attribute__((matrix_type(4, 4)));
+using matrix_dog = Dog __attribute__((matrix_type(4, 4)));
+TEST_AUTO(t14, matrix_man, matrix_dog) // expected-error {{but deduced as 'Animal __attribute__((matrix_type(4, 4)))'}}
+
+using vector_man = Man 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-21 Thread Louis Dionne via Phabricator via cfe-commits
ldionne added a comment.

In D111283#3056748 , @rsmith wrote:

> Do you have examples showing what this does in practice for errors in 
> real-world code? I'm concerned that stripping back to the common type sugar 
> may produce an unintuitive result in some cases, although it certainly does 
> seem at least theoretically nice to use a commutative and associative 
> function to combine deductions like this. The kind of thing I'd be worried 
> about would be (eg) a container where the `iterator` and `const_iterator` are 
> the same, but where the common sugar of `T::iterator` and `T::const_iterator` 
> are some internal type that the user has never heard of. In general it seems 
> like this sugar stripping could result in types that are distant from the 
> user's code. As an extreme example, in the case where one of the types is 
> canonical and the other is not, it seems like stripping all the way back to 
> the canonical type would be worse than ignoring the canonical version of the 
> type and keeping the sugared version.

FWIW, I believe in those cases the best tool might be some sort of attribute to 
treat an alias like a "strong typedef".


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-12 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov marked 3 inline comments as done.
mizvekov added inline comments.



Comment at: clang/test/SemaCXX/sugared-auto.cpp:146
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, 
Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}

mizvekov wrote:
> rsmith wrote:
> > rsmith wrote:
> > > Why don't we get `Virus` as the deduced return type from line 143 here?
> > Oh, never mind, we've not updated the conditional expression handling to 
> > use `getCommonSugar` yet. We probably should -- it currently has a very 
> > minimal form of the same thing; see `Sema::FindCompositePointerType`. That 
> > can presumably be changed to use `getCommonSugar` once it strips down to a 
> > common type. On around `SemaExprCXX.cpp:6870`:
> > ```
> > -  QualType Composite = Composite1;
> > +  QualType Composite = Context.getCommonSugar(Composite1, Composite2);
> > ```
> Yeah, if you look into the next patch in the stack, which is still WIP, there 
> is a change that fixes this aspect of this test case, but it's a different 
> change than what you are proposing here. I will take a look again, but are 
> you proposing that I add this sort of changes to this same patch, or keep 
> things separate as I am trying to do?
> Either answer is fine, less patches means less rebuild time for me :-)
This is done in https://reviews.llvm.org/D111509


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-12 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 379179.
mizvekov added a comment.

- Introduce TDK_ALreadyDiagnosed.

Addresses rsmith's review comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp

Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
@@ -9,6 +9,26 @@
 using Man = Animal;
 using Dog = Animal;
 
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
 namespace variable {
 
 auto x1 = Animal();
@@ -41,3 +61,115 @@
 N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
 
 } // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using block_dog = void (^)(Dog);
+TEST_AUTO(t5, block_man, block_dog) // expected-error {{but deduced as 'void (^)(Animal)'}}
+
+using fp1 = SARS (*)(Man, DogPtr) throw(Vibrio);
+using fp2 = Ebola (*)(Dog, ManPtr) throw(Bacilli);
+TEST_AUTO(t6, fp1, fp2); // expected-error {{but deduced as 'Virus (*)(Animal, Animal *) throw(Bacteria)' (aka 'void (*)(int, int *) throw(Bacteria)')}}
+
+using fp3 = SARS (*)() throw(Man);
+using fp4 = Ebola (*)() throw(Vibrio);
+auto t7(fp3 a, fp4 b) {
+  if (false)
+return true ? a : b;
+  if (false)
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}
+
+using fp5 = void (*)(const Man);
+using fp6 = void (*)(Dog);
+TEST_AUTO(t8, fp5, fp6); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
+
+using fp6 = void (*)(ConstMan);
+using fp7 = void (*)(ConstDog);
+TEST_AUTO(t10, fp6, fp7); // expected-error {{but deduced as 'void (*)(const Animal)' (aka 'void (*)(const int)')}}
+
+TEST_AUTO(t11, Man Angiosperm::*, Dog Gymnosperm::*) // expected-error {{but deduced as 'Animal Plant::*'}}
+
+TEST_DAUTO(t12, const Man &, const Dog &) // expected-error {{but deduced as 'const Animal &' (aka 'const int &')}}
+
+TEST_DAUTO(t13, Man &&, Dog &&) // expected-error {{but deduced as 'Animal &&' (aka 'int &&')}}
+
+using matrix_man = Man __attribute__((matrix_type(4, 4)));
+using matrix_dog = Dog __attribute__((matrix_type(4, 4)));
+TEST_AUTO(t14, matrix_man, matrix_dog) // expected-error {{but deduced as 'Animal 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-12 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov added a comment.

In D111283#3056748 , @rsmith wrote:

> Do you have examples showing what this does in practice for errors in 
> real-world code? I'm concerned that stripping back to the common type sugar 
> may produce an unintuitive result in some cases, although it certainly does 
> seem at least theoretically nice to use a commutative and associative 
> function to combine deductions like this. The kind of thing I'd be worried 
> about would be (eg) a container where the `iterator` and `const_iterator` are 
> the same, but where the common sugar of `T::iterator` and `T::const_iterator` 
> are some internal type that the user has never heard of. In general it seems 
> like this sugar stripping could result in types that are distant from the 
> user's code. As an extreme example, in the case where one of the types is 
> canonical and the other is not, it seems like stripping all the way back to 
> the canonical type would be worse than ignoring the canonical version of the 
> type and keeping the sugared version.

I don't have handy access to very large code bases where this could be deployed 
experimentally, but this is something I can try to look into.

> Perhaps we could treat canonical types as a special case (effectively 
> assuming they came from taking a type and canonicalizing it at some point, 
> rather than from a type the user wrote) and when combining two types, use the 
> non-canonical type if one of them is canonical, and otherwise use the common 
> sugar. That should still be commutative and associative and generally 
> well-behaved, but won't degrade badly when given a canonical type as input. I 
> think that still leaves the possibility of a surprising outcome when 
> combining types that both desugar to some internal type, though I'm not sure 
> what we can do about that other than make an arbitrary choice of which type 
> sugar we like more.

The thing I would be concerned with this special case is that it would also 
give surprising results, ie it could deduce that Socrates is a Dog.
I guess there are two use cases scenarios here, one where we have this 
transparent hierarchy, and this algorithm gives results that make intuitive 
sense,
and the other where we have some typedef which we want to be opaque in order to 
not expose internal details.

So exploring your example, suppose we try to deduce from an iterator and a 
const_iterator.
We have some options here:

- We deduce as either iterator or const_iterator. If there is an IS-A 
relationship between them, and we pick the right choice, then we pack up and go 
home, job well done. If there is no such relationship, neither answer seems 
right.
- We deduce the canonical type, which might be something like `struct 
vendor::detail::Foo *`. This exposes internal details, but at least it has some 
vocabulary information, so you know this is a pointer to an object of some 
internal class. It's not good from a user friendliness PoV, but it's good from 
a 'I want to debug this thing' perspective.
- We deduce to some type sugar which is meant to be internal, like 
`vendor::detail::iterator_t`. This is not very good, maybe it's worse from a 
user friendliness PoV than the bullet point above as we expose even more 
internal details. But maybe in some cases it's better as the vendor can also 
pick a name for the typedef which is more explanatory than the the canonical 
type, which will still be available in the 'aka', so from the debuggability 
perspective this also seems better.
- We create some new type sugar which wraps the information that some type was 
deduced from two other types. This might be too much information overload, and 
we still need to have an answer to the 'single step desugar' of it, so I am not 
exploring this much further for now ;)

The problem of hiding internal details in error messages is a general problem, 
that maybe this solution would make a bit worse in some cases,
but that also means that solutions to the general problem can also remedy the 
problems we cause here.
One such idea (not proposing formally, just giving an example) would be an 
attribute on typedefs which hides the underlying sugar,
making it AS-IF the typedef was written on the canonical type. But it would 
still not hide the canonical type which is also
implementation detail, so not a huge win.

Going back to the 'treat canonical types as not written' workaround, I think 
there are too many cases where we are doing the wrong thing here in clang.
Basically any type written bare without any name / keyword qualifiers will not 
be treated by some ElaboratedType like mechanism. I suppose that as we fix
those problems, the need for this workaround will sort of disappear. I am not 
too opposed to it, but I think it might be better to give less, but more 
correct information, than
to some times make wild guesses ;-P

> I've not yet done any detailed review of the common type sugar computation 
> mechanism.

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-11 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/test/SemaCXX/sugared-auto.cpp:146
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, 
Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}

rsmith wrote:
> Why don't we get `Virus` as the deduced return type from line 143 here?
Oh, never mind, we've not updated the conditional expression handling to use 
`getCommonSugar` yet. We probably should -- it currently has a very minimal 
form of the same thing; see `Sema::FindCompositePointerType`. That can 
presumably be changed to use `getCommonSugar` once it strips down to a common 
type. On around `SemaExprCXX.cpp:6870`:
```
-  QualType Composite = Composite1;
+  QualType Composite = Context.getCommonSugar(Composite1, Composite2);
```


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-11 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added a comment.

Do you have examples showing what this does in practice for errors in 
real-world code? I'm concerned that stripping back to the common type sugar may 
produce an unintuitive result in some cases, although it certainly does seem at 
least theoretically nice to use a commutative and associative function to 
combine deductions like this. The kind of thing I'd be worried about would be 
(eg) a container where the `iterator` and `const_iterator` are the same, but 
where the common sugar of `T::iterator` and `T::const_iterator` are some 
internal type that the user has never heard of. In general it seems like this 
sugar stripping could result in types that are distant from the user's code. As 
an extreme example, in the case where one of the types is canonical and the 
other is not, it seems like stripping all the way back to the canonical type 
would be worse than ignoring the canonical version of the type and keeping the 
sugared version.

Perhaps we could treat canonical types as a special case (effectively assuming 
they came from taking a type and canonicalizing it at some point, rather than 
from a type the user wrote) and when combining two types, use the non-canonical 
type if one of them is canonical, and otherwise use the common sugar. That 
should still be commutative and associative and generally well-behaved, but 
won't degrade badly when given a canonical type as input. I think that still 
leaves the possibility of a surprising outcome when combining types that both 
desugar to some internal type, though I'm not sure what we can do about that 
other than make an arbitrary choice of which type sugar we like more.

I've not yet done any detailed review of the common type sugar computation 
mechanism.




Comment at: clang/lib/Sema/SemaExprCXX.cpp:2008
+DeduceAutoType(AllocTypeInfo->getTypeLoc(), Deduce, DeducedType, Info);
+if (Result != TDK_Success && Result != TDK_MiscellaneousDeductionFailure)
   return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)

Previously we distinguished between "auto deduction failed and already issued a 
diagnostic" and "auto deduction failed but no diagnostic has been issued". This 
allowed us to be sure we always issue exactly one diagnostic for each deduction 
failure. We seem to have lost that distinction -- 
`TDK_MiscellaneousDeductionFailure` does not indicate that a diagnostic has 
already been issued, and if an auto deduction fails for this reason, we now 
might produce no diagnostics at all.



Comment at: clang/test/SemaCXX/sugared-auto.cpp:146
+return a;
+  return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, 
Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
+}

Why don't we get `Virus` as the deduced return type from line 143 here?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

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


[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-11 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 378840.
mizvekov added a comment.

rebase.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp

Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,31 +1,175 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
-using T1 = int;
-auto x1 = T1();
-N t1 = x1;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-using T2 = T1 *;
-auto x2 = T2();
-N t2 = x2;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T2' (aka 'int *')}}
-
-auto *x3 = T2();
-N t3 = x3;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1 *' (aka 'int *')}}
-
-auto f1() { return T1(); }
-auto x4 = f1();
-N t4 = x4;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-decltype(auto) f2() { return T1(); }
-auto x5 = f2();
-N t5 = x5;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-auto x6 = [a = T1()] { return a; }();
-N t6 = x6;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
+using Animal = int;
+
+using AnimalPtr = Animal *;
+
+using Man = Animal;
+using Dog = Animal;
+
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
+namespace variable {
+
+auto x1 = Animal();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x2 = AnimalPtr();
+N t2 = x2; // expected-error {{lvalue of type 'AnimalPtr' (aka 'int *')}}
+
+auto *x3 = AnimalPtr();
+N t3 = x3; // expected-error {{lvalue of type 'Animal *' (aka 'int *')}}
+
+// Each variable deduces separately.
+auto x4 = Man(), x5 = Dog();
+N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
+N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
+
+} // namespace variable
+
+namespace function_basic {
+
+auto f1() { return Animal(); }
+auto x1 = f1();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+decltype(auto) f2() { return Animal(); }
+auto x2 = f2();
+N t2 = x2; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x3 = [a = Animal()] { return a; }();
+N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+} // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-11 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 378603.
mizvekov added a comment.

.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp

Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,31 +1,175 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
-using T1 = int;
-auto x1 = T1();
-N t1 = x1;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-using T2 = T1 *;
-auto x2 = T2();
-N t2 = x2;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T2' (aka 'int *')}}
-
-auto *x3 = T2();
-N t3 = x3;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1 *' (aka 'int *')}}
-
-auto f1() { return T1(); }
-auto x4 = f1();
-N t4 = x4;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-decltype(auto) f2() { return T1(); }
-auto x5 = f2();
-N t5 = x5;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-auto x6 = [a = T1()] { return a; }();
-N t6 = x6;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
+using Animal = int;
+
+using AnimalPtr = Animal *;
+
+using Man = Animal;
+using Dog = Animal;
+
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
+namespace variable {
+
+auto x1 = Animal();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x2 = AnimalPtr();
+N t2 = x2; // expected-error {{lvalue of type 'AnimalPtr' (aka 'int *')}}
+
+auto *x3 = AnimalPtr();
+N t3 = x3; // expected-error {{lvalue of type 'Animal *' (aka 'int *')}}
+
+// Each variable deduces separately.
+auto x4 = Man(), x5 = Dog();
+N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
+N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
+
+} // namespace variable
+
+namespace function_basic {
+
+auto f1() { return Animal(); }
+auto x1 = f1();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+decltype(auto) f2() { return Animal(); }
+auto x2 = f2();
+N t2 = x2; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x3 = [a = Animal()] { return a; }();
+N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+} // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-11 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 378600.
mizvekov added a comment.

- Handle different top level qualifiers in function parameters.
- More test cases.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp

Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,31 +1,175 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
-using T1 = int;
-auto x1 = T1();
-N t1 = x1;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-using T2 = T1 *;
-auto x2 = T2();
-N t2 = x2;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T2' (aka 'int *')}}
-
-auto *x3 = T2();
-N t3 = x3;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1 *' (aka 'int *')}}
-
-auto f1() { return T1(); }
-auto x4 = f1();
-N t4 = x4;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-decltype(auto) f2() { return T1(); }
-auto x5 = f2();
-N t5 = x5;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-auto x6 = [a = T1()] { return a; }();
-N t6 = x6;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
+using Animal = int;
+
+using AnimalPtr = Animal *;
+
+using Man = Animal;
+using Dog = Animal;
+
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using ConstMan = const Man;
+using ConstDog = const Dog;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
+namespace variable {
+
+auto x1 = Animal();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x2 = AnimalPtr();
+N t2 = x2; // expected-error {{lvalue of type 'AnimalPtr' (aka 'int *')}}
+
+auto *x3 = AnimalPtr();
+N t3 = x3; // expected-error {{lvalue of type 'Animal *' (aka 'int *')}}
+
+// Each variable deduces separately.
+auto x4 = Man(), x5 = Dog();
+N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
+N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
+
+} // namespace variable
+
+namespace function_basic {
+
+auto f1() { return Animal(); }
+auto x1 = f1();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+decltype(auto) f2() { return Animal(); }
+auto x2 = f2();
+N t2 = x2; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x3 = [a = Animal()] { return a; }();
+N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+} // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-10 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 378501.
mizvekov added a comment.

.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp

Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,31 +1,160 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
-using T1 = int;
-auto x1 = T1();
-N t1 = x1;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-using T2 = T1 *;
-auto x2 = T2();
-N t2 = x2;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T2' (aka 'int *')}}
-
-auto *x3 = T2();
-N t3 = x3;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1 *' (aka 'int *')}}
-
-auto f1() { return T1(); }
-auto x4 = f1();
-N t4 = x4;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-decltype(auto) f2() { return T1(); }
-auto x5 = f2();
-N t5 = x5;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-auto x6 = [a = T1()] { return a; }();
-N t6 = x6;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
+using Animal = int;
+
+using AnimalPtr = Animal *;
+
+using Man = Animal;
+using Dog = Animal;
+
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Plant;
+using Gymnosperm = Plant;
+using Angiosperm = Plant;
+
+namespace variable {
+
+auto x1 = Animal();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x2 = AnimalPtr();
+N t2 = x2; // expected-error {{lvalue of type 'AnimalPtr' (aka 'int *')}}
+
+auto *x3 = AnimalPtr();
+N t3 = x3; // expected-error {{lvalue of type 'Animal *' (aka 'int *')}}
+
+// Each variable deduces separately.
+auto x4 = Man(), x5 = Dog();
+N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
+N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
+
+} // namespace variable
+
+namespace function_basic {
+
+auto f1() { return Animal(); }
+auto x1 = f1();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+decltype(auto) f2() { return Animal(); }
+auto x2 = f2();
+N t2 = x2; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x3 = [a = Animal()] { return a; }();
+N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+} // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-08 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 378406.
mizvekov added a comment.

- Tests and fix for dynamic exception spec corner case.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp

Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,31 +1,158 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix -Wno-dynamic-exception-spec
 
 enum class N {};
 
-using T1 = int;
-auto x1 = T1();
-N t1 = x1;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-using T2 = T1 *;
-auto x2 = T2();
-N t2 = x2;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T2' (aka 'int *')}}
-
-auto *x3 = T2();
-N t3 = x3;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1 *' (aka 'int *')}}
-
-auto f1() { return T1(); }
-auto x4 = f1();
-N t4 = x4;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-decltype(auto) f2() { return T1(); }
-auto x5 = f2();
-N t5 = x5;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-auto x6 = [a = T1()] { return a; }();
-N t6 = x6;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
+using Animal = int;
+
+using AnimalPtr = Animal *;
+
+using Man = Animal;
+using Dog = Animal;
+
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+using Bacteria = float;
+using Bacilli = Bacteria;
+using Vibrio = Bacteria;
+
+struct Zoo;
+
+namespace variable {
+
+auto x1 = Animal();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x2 = AnimalPtr();
+N t2 = x2; // expected-error {{lvalue of type 'AnimalPtr' (aka 'int *')}}
+
+auto *x3 = AnimalPtr();
+N t3 = x3; // expected-error {{lvalue of type 'Animal *' (aka 'int *')}}
+
+// Each variable deduces separately.
+auto x4 = Man(), x5 = Dog();
+N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
+N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
+
+} // namespace variable
+
+namespace function_basic {
+
+auto f1() { return Animal(); }
+auto x1 = f1();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+decltype(auto) f2() { return Animal(); }
+auto x2 = f2();
+N t2 = x2; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x3 = [a = Animal()] { return a; }();
+N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+} // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) \
+  auto X(A a, B b) {   \
+if (0) \
+  return a;\
+if (0) \
+  return b;\
+return N();\
+  }
+#define TEST_DAUTO(X, A, B) \
+  decltype(auto) X(A a, B b) {  \
+if (0)  \
+  return static_cast(a); \
+if (0)  \
+  return static_cast(b); \
+return N(); \
+  }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int *)   // expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t4, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as 

[PATCH] D111283: [clang] template / auto deduction deduces common sugar

2021-10-08 Thread Matheus Izvekov via Phabricator via cfe-commits
mizvekov updated this revision to Diff 378388.
mizvekov retitled this revision from "[clang] WIP: template / auto deduction 
deduces common sugar" to "[clang] template / auto deduction deduces common 
sugar".
mizvekov edited the summary of this revision.
mizvekov added a comment.

- Add missing tests, not marked as WIP anymore.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D111283

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/SemaCXX/sugared-auto.cpp

Index: clang/test/SemaCXX/sugared-auto.cpp
===
--- clang/test/SemaCXX/sugared-auto.cpp
+++ clang/test/SemaCXX/sugared-auto.cpp
@@ -1,31 +1,133 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fblocks -fenable-matrix
 
 enum class N {};
 
-using T1 = int;
-auto x1 = T1();
-N t1 = x1;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-using T2 = T1 *;
-auto x2 = T2();
-N t2 = x2;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T2' (aka 'int *')}}
-
-auto *x3 = T2();
-N t3 = x3;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1 *' (aka 'int *')}}
-
-auto f1() { return T1(); }
-auto x4 = f1();
-N t4 = x4;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-decltype(auto) f2() { return T1(); }
-auto x5 = f2();
-N t5 = x5;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
-
-auto x6 = [a = T1()] { return a; }();
-N t6 = x6;
-// expected-error@-1 {{cannot initialize a variable of type 'N' with an lvalue of type 'T1' (aka 'int')}}
+using Animal = int;
+
+using AnimalPtr = Animal *;
+
+using Man = Animal;
+using Dog = Animal;
+
+using ManPtr = Man *;
+using DogPtr = Dog *;
+
+using SocratesPtr = ManPtr;
+
+using Virus = void;
+using SARS = Virus;
+using Ebola = Virus;
+
+struct Zoo;
+
+namespace variable {
+
+auto x1 = Animal();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x2 = AnimalPtr();
+N t2 = x2; // expected-error {{lvalue of type 'AnimalPtr' (aka 'int *')}}
+
+auto *x3 = AnimalPtr();
+N t3 = x3; // expected-error {{lvalue of type 'Animal *' (aka 'int *')}}
+
+// Each variable deduces separately.
+auto x4 = Man(), x5 = Dog();
+N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
+N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
+
+} // variable
+
+namespace function_basic {
+
+auto f1() { return Animal(); }
+auto x1 = f1();
+N t1 = x1; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+decltype(auto) f2() { return Animal(); }
+auto x2 = f2();
+N t2 = x2; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+auto x3 = [a = Animal()] { return a; }();
+N t3 = x3; // expected-error {{lvalue of type 'Animal' (aka 'int')}}
+
+} // namespace function_basic
+
+namespace function_multiple_basic {
+
+N t1 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t2 = []() -> decltype(auto) { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Man();
+  return Dog();
+}();
+
+N t3 = [] { // expected-error {{rvalue of type 'Animal' (aka 'int')}}
+  if (true)
+return Dog();
+  auto x = Man();
+  return x;
+}();
+
+N t4 = [] { // expected-error {{rvalue of type 'int'}}
+  if (true)
+return Dog();
+  return 1;
+}();
+
+N t5 = [] { // expected-error {{rvalue of type 'Virus' (aka 'void')}}
+  if (true)
+return Ebola();
+  return SARS();
+}();
+
+N t6 = [] { // expected-error {{rvalue of type 'void'}}
+  if (true)
+return SARS();
+  return;
+}();
+
+} // namespace function_multiple_basic
+
+#define TEST_AUTO(X, A, B) auto X(A a, B b) { if (0) return a; if (0) return b; return N(); }
+#define TEST_DAUTO(X, A, B) decltype(auto) X(A a, B b) { \
+  if (0) return static_cast(a); \
+  if (0) return static_cast(b); \
+  return N(); }
+
+namespace misc {
+
+TEST_AUTO(t1, ManPtr, DogPtr)  // expected-error {{but deduced as 'Animal *' (aka 'int *')}}
+TEST_AUTO(t2, ManPtr, int*)// expected-error {{but deduced as 'int *'}}
+TEST_AUTO(t3, SocratesPtr, ManPtr) // expected-error {{but deduced as 'ManPtr' (aka 'int *')}}
+
+TEST_AUTO(t1, _Atomic(Man), _Atomic(Dog)) // expected-error {{but deduced as '_Atomic(Animal)'}}
+
+using block_man = void (^)(Man);
+using