Skip to content
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

[clang] Represent array refs as TemplateArgument::Declaration #80050

Merged
merged 1 commit into from
Jan 31, 2024

Conversation

bolshakov-a
Copy link
Contributor

This returns (probably temporarily) array-referring NTTP behavior to which was prior to #78041 because I'm fed up have no time to fix regressions.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 30, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 30, 2024

@llvm/pr-subscribers-clang

Author: Andrey Ali Khan Bolshakov (bolshakov-a)

Changes

This returns (probably temporarily) array-referring NTTP behavior to which was prior to #78041 because I'm fed up have no time to fix regressions.


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

1 Files Affected:

  • (modified) clang/lib/Sema/SemaTemplate.cpp (+24-20)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3f33ecb89502e..9e8d058041f04 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7417,9 +7417,9 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
     if (ArgResult.isInvalid())
       return ExprError();
 
-    // Prior to C++20, enforce restrictions on possible template argument
-    // values.
-    if (!getLangOpts().CPlusPlus20 && Value.isLValue()) {
+    if (Value.isLValue()) {
+      APValue::LValueBase Base = Value.getLValueBase();
+      auto *VD = const_cast<ValueDecl *>(Base.dyn_cast<const ValueDecl *>());
       //   For a non-type template-parameter of pointer or reference type,
       //   the value of the constant expression shall not refer to
       assert(ParamType->isPointerType() || ParamType->isReferenceType() ||
@@ -7428,8 +7428,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
       // -- a string literal
       // -- the result of a typeid expression, or
       // -- a predefined __func__ variable
-      APValue::LValueBase Base = Value.getLValueBase();
-      auto *VD = const_cast<ValueDecl *>(Base.dyn_cast<const ValueDecl *>());
       if (Base &&
           (!VD ||
            isa<LifetimeExtendedTemporaryDecl, UnnamedGlobalConstantDecl>(VD))) {
@@ -7437,24 +7435,30 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
             << Arg->getSourceRange();
         return ExprError();
       }
-      // -- a subobject [until C++20]
-      if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 &&
-          VD && VD->getType()->isArrayType() &&
+
+      if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 && VD &&
+          VD->getType()->isArrayType() &&
           Value.getLValuePath()[0].getAsArrayIndex() == 0 &&
           !Value.isLValueOnePastTheEnd() && ParamType->isPointerType()) {
-        // Per defect report (no number yet):
-        //   ... other than a pointer to the first element of a complete array
-        //       object.
-      } else if (!Value.hasLValuePath() || Value.getLValuePath().size() ||
-                 Value.isLValueOnePastTheEnd()) {
-        Diag(StartLoc, diag::err_non_type_template_arg_subobject)
-          << Value.getAsString(Context, ParamType);
-        return ExprError();
+        SugaredConverted = TemplateArgument(VD, ParamType);
+        CanonicalConverted = TemplateArgument(
+            cast<ValueDecl>(VD->getCanonicalDecl()), CanonParamType);
+        return ArgResult.get();
+      }
+
+      // -- a subobject [until C++20]
+      if (!getLangOpts().CPlusPlus20) {
+        if (!Value.hasLValuePath() || Value.getLValuePath().size() ||
+            Value.isLValueOnePastTheEnd()) {
+          Diag(StartLoc, diag::err_non_type_template_arg_subobject)
+              << Value.getAsString(Context, ParamType);
+          return ExprError();
+        }
+        assert((VD || !ParamType->isReferenceType()) &&
+               "null reference should not be a constant expression");
+        assert((!VD || !ParamType->isNullPtrType()) &&
+               "non-null value of type nullptr_t?");
       }
-      assert((VD || !ParamType->isReferenceType()) &&
-             "null reference should not be a constant expression");
-      assert((!VD || !ParamType->isNullPtrType()) &&
-             "non-null value of type nullptr_t?");
     }
 
     if (Value.isAddrLabelDiff())

@bolshakov-a
Copy link
Contributor Author

@erichkeane, @cor3ntin

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

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

Are there any release-notes that should be reverted with this? or at least modified, since this is reverting stuff?

Also, can you please add the tests/regressions that were found that have lead to this partial revert?

Also-- We hope you find more time to help with the regressions, your contributions so far have been really appreciated!

@cor3ntin
Copy link
Contributor

@AaronBallman @zygoloid
There probably is a missing ODR-use marking somewhere, if you have a clue
#78041 (comment)

Alas we do not seem to have a repro for the chromium-reported issue which make debugging it difficult.

@erichkeane
Copy link
Collaborator

@AaronBallman @zygoloid There probably is a missing ODR-use marking somewhere, if you have a clue #78041 (comment)

Alas we do not seem to have a repro for the chromium-reported issue which make debugging it difficult.

SMH

@bolshakov-a
Copy link
Contributor Author

Are there any release-notes that should be reverted with this? or at least modified, since this is reverting stuff?

No, it is intended only to fix potential bugs with already-written user's code (I suspect there are more places where OVE->getSourceExpr() should be checked, besides the last reported bug) without reverting the new NTTP feature (which may also contain bugs, but is marked as experimental). Just arrays are switched to the old mechanism.

Also, can you please add the tests/regressions that were found that have lead to this partial revert?

I'd add the test if the repro would be provided. As far, I can revert the changes in code from #79764, and the tests from it would test this change.

We hope you find more time to help with the regressions, your contributions so far have been really appreciated!

Thanks! Probably, on my vacation in summer...

Alas we do not seem to have a repro for the chromium-reported issue which make debugging it difficult.

Do you mean this? I've succeeded in reducing it to that.

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

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

I don't have concerns as written. @cor3ntin : feel free to accept if you like it too.

@bolshakov-a
Copy link
Contributor Author

The changes under that discussion could now be reverted as well because they are now useless. Should I make a separate commit inside this PR?

@jeremiahar
Copy link

This also avoids regressing #79957 (I cherrypicked this commit and compiled the test case locally)

This returns (probably temporarily) array-referring NTTP behavior
to which was prior to llvm#78041 to avoid regressions.
@bolshakov-a
Copy link
Contributor Author

@jeremiahar, thanks for reporting! Added a coverage mapping test case.

Copy link
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

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

I will accept that as it seems to unblock some folks,
but I'd like to understand the root cause and what a proper fix would look like

@bolshakov-a
Copy link
Contributor Author

I think the problem is that the generalized NTTP feature is still raw. It should not break already working features, namely array reference NTTPs, hence they are swithed back to the old TemplateArgument::Declaration, as they worked prior to #78041, from the new StructuralValue.

@bolshakov-a
Copy link
Contributor Author

what a proper fix would look like

Probably, some more OpaqueValueExpr handlers should be rewritten correctly.

@bolshakov-a
Copy link
Contributor Author

@cor3ntin, @erichkeane, could you merge it please?

@erichkeane erichkeane merged commit 9bf4e54 into llvm:main Jan 31, 2024
4 checks passed
@bolshakov-a
Copy link
Contributor Author

Thanks! Should I open an issue to backport this to RC?

@bolshakov-a bolshakov-a deleted the avoid_regressions branch January 31, 2024 15:12
@erichkeane
Copy link
Collaborator

Thanks! Should I open an issue to backport this to RC?

Please do!

@bolshakov-a
Copy link
Contributor Author

Please do!

#80150. I don't know, maybe, some more actions should be done. I cannot add "release:backport" label, at least.

@erichkeane
Copy link
Collaborator

Please do!

#80150. I don't know, maybe, some more actions should be done. I cannot add "release:backport" label, at least.

I think you just have to set hte milestone, which I did.

llvmbot pushed a commit to llvmbot/llvm-project that referenced this pull request Jan 31, 2024
…#80050)

This returns (probably temporarily) array-referring NTTP behavior to
which was prior to llvm#78041 because ~~I'm fed up~~ have no time to fix
regressions.

(cherry picked from commit 9bf4e54)
llvmbot pushed a commit to llvmbot/llvm-project that referenced this pull request Feb 4, 2024
…#80050)

This returns (probably temporarily) array-referring NTTP behavior to
which was prior to llvm#78041 because ~~I'm fed up~~ have no time to fix
regressions.

(cherry picked from commit 9bf4e54)
tstellar pushed a commit to tstellar/llvm-project that referenced this pull request Feb 14, 2024
…#80050)

This returns (probably temporarily) array-referring NTTP behavior to
which was prior to llvm#78041 because ~~I'm fed up~~ have no time to fix
regressions.

(cherry picked from commit 9bf4e54)
tstellar pushed a commit to tstellar/llvm-project that referenced this pull request Feb 14, 2024
…#80050)

This returns (probably temporarily) array-referring NTTP behavior to
which was prior to llvm#78041 because ~~I'm fed up~~ have no time to fix
regressions.

(cherry picked from commit 9bf4e54)
tstellar pushed a commit to tstellar/llvm-project that referenced this pull request Feb 14, 2024
…#80050)

This returns (probably temporarily) array-referring NTTP behavior to
which was prior to llvm#78041 because ~~I'm fed up~~ have no time to fix
regressions.

(cherry picked from commit 9bf4e54)
tstellar pushed a commit to tstellar/llvm-project that referenced this pull request Feb 14, 2024
…#80050)

This returns (probably temporarily) array-referring NTTP behavior to
which was prior to llvm#78041 because ~~I'm fed up~~ have no time to fix
regressions.

(cherry picked from commit 9bf4e54)
bolshakov-a added a commit to bolshakov-a/llvm-project that referenced this pull request Mar 20, 2024
Introduced in llvm#78041, originally reported as llvm#79957 and fixed partially
in llvm#80050.

`OpaqueValueExpr` used with `TemplateArgument::StructuralValue` has no
corresponding source expression.

A test case with subobject-referring NTTP added.
@pointhex pointhex mentioned this pull request May 7, 2024
efriedma-quic pushed a commit that referenced this pull request May 24, 2024
…#85837)

Introduced in #78041, originally reported as #79957 and fixed partially
in #80050.

`OpaqueValueExpr` used with `TemplateArgument::StructuralValue` has no
corresponding source expression.

A test case with subobject-referring NTTP added.
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.

5 participants