Skip to content

[Clang][Interp] Visit DecompositionDecl and create a local variable #100400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 25, 2024

Conversation

yronglin
Copy link
Contributor

@yronglin yronglin commented Jul 24, 2024

The following code should be well-formed:

float decompose_complex(_Complex float cf) {
  static _Complex float scf;
  auto &[sre, sim] = scf;
  // ok, this is references initialized by constant expressions all the way down
  static_assert(&sre == &__real scf);
  static_assert(&sim == &__imag scf);

  auto [re, im] = cf;
  return re*re + im*im;
}

We should visit DecompositionDecl and create a local variable but not a create a dummy value directly.

@yronglin yronglin requested a review from tbaederr as a code owner July 24, 2024 15:14
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jul 24, 2024
@llvmbot
Copy link
Member

llvmbot commented Jul 24, 2024

@llvm/pr-subscribers-clang

Author: None (yronglin)

Changes

The following code should be well-formed:

float decompose_complex(_Complex float cf) {
  static _Complex float scf;
  auto &[sre, sim] = scf;
  // ok, this is references initialized by constant expressions all the way down
  static_assert(&sre == &__real scf);
  static_assert(&sim == &__imag scf);

  auto [re, im] = cf;
  return re*re + im*im;
}

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

2 Files Affected:

  • (modified) clang/lib/AST/Interp/Compiler.cpp (+11-2)
  • (modified) clang/test/SemaCXX/cxx1z-decomposition.cpp (+1)
diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp
index 0fc93c14131e6..6e2f0dbc39dcf 100644
--- a/clang/lib/AST/Interp/Compiler.cpp
+++ b/clang/lib/AST/Interp/Compiler.cpp
@@ -3593,8 +3593,14 @@ VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD) {
   if (R.notCreated())
     return R;
 
-  if (R)
-    return true;
+  if (R) {
+    bool Ok = true;
+    if (const auto *DD = dyn_cast<DecompositionDecl>(VD))
+      for (const auto *BD : DD->bindings())
+        if (const auto *HoldingVar = BD->getHoldingVar())
+          Ok &= this->visitDecl(HoldingVar);
+    return Ok;
+  }
 
   if (!R && Context::shouldBeGloballyIndexed(VD)) {
     if (auto GlobalIndex = P.getGlobal(VD)) {
@@ -5234,6 +5240,9 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
           return false;
         };
 
+        if (isa<DecompositionDecl>(VD))
+          return revisit(VD);
+
         // Visit local const variables like normal.
         if ((VD->hasGlobalStorage() || VD->isLocalVarDecl() ||
              VD->isStaticDataMember()) &&
diff --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp b/clang/test/SemaCXX/cxx1z-decomposition.cpp
index 305a9ac2ebc24..19c730303625e 100644
--- a/clang/test/SemaCXX/cxx1z-decomposition.cpp
+++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -std=c++17 -Wc++20-extensions -verify=expected %s
 // RUN: %clang_cc1 -std=c++20 -Wpre-c++20-compat -verify=expected %s
+// RUN: %clang_cc1 -std=c++20 -Wpre-c++20-compat -fexperimental-new-constant-interpreter -verify=expected %s
 
 void use_from_own_init() {
   auto [a] = a; // expected-error {{binding 'a' cannot appear in the initializer of its own decomposition declaration}}

@yronglin yronglin changed the title [Clang][Interp] Fix handling of DecompositionDecl [Clang][Interp] Visit DecompositionDecl and create a local variable but not a create a dummy value directly Jul 24, 2024
@yronglin yronglin changed the title [Clang][Interp] Visit DecompositionDecl and create a local variable but not a create a dummy value directly [Clang][Interp] Visit DecompositionDecl and create a local variable Jul 24, 2024
Copy link
Contributor

@tbaederr tbaederr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with the suggested changes. This might not be perfect wrt. revisiting DecompositionDecls, but we can handle problems when they arise.

Signed-off-by: yronglin <[email protected]>
@yronglin yronglin merged commit 534e2dd into llvm:main Jul 25, 2024
7 checks passed
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
…#100400)

Summary:
The following code should be well-formed:
```C++
float decompose_complex(_Complex float cf) {
  static _Complex float scf;
  auto &[sre, sim] = scf;
  // ok, this is references initialized by constant expressions all the way down
  static_assert(&sre == &__real scf);
  static_assert(&sim == &__imag scf);

  auto [re, im] = cf;
  return re*re + im*im;
}

```
We should visit `DecompositionDecl` and create a local variable but not
a create a dummy value directly.

---------

Signed-off-by: yronglin <[email protected]>

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60250516
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants