Skip to content

[Clang] Allow explicit member specialization to differ from template declaration wrt constexpr #145272

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

vikramRH
Copy link
Contributor

This attempts to fix #26078. However I have couple of fundamental questions with the 7.1.5 consexpr note
"[ Note: An explicit specialization can differ from the template declaration with respect to the constexpr specifier. — end note ]"

  1. Does it also apply to member specializations which are not function templates themselves ? (as in the example https://godbolt.org/z/c4bYY8rxb)
  2. if yes, then should it also apply to special member functions ? (constructors, destructors)

@erichkeane
Copy link
Collaborator

This attempts to fix #26078. However I have couple of fundamental questions with the 7.1.5 consexpr note "[ Note: An explicit specialization can differ from the template declaration with respect to the constexpr specifier. — end note ]"

Current quote: https://eel.is/c++draft/dcl.constexpr#note-1 is the same.

1. Does it also apply to member specializations which are not function templates themselves ? (as in the example https://godbolt.org/z/c4bYY8rxb)

I read that to do so, yes. It applies to ALL templates. An explicit specialization can change the constexpr/constevalness.

2. if yes, then should it also apply to special member functions ? (constructors, destructors)

I would say yes, it should. Any templated SMFs also can have it changed with an explicit specialization.

This is actually related to a topic that came up for Reflection last week in EWG. An 'explicit specialization' is a morally different 'entity'. So it is allowed to change quite a bit more from the primary template than we might otherwise expect. In this case, it is allowed to add/remove constexpr/consteval.

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.

it would be great to track down the history of this (https://github.com/cplusplus/draft) to see what changed around this, in case there is more we have to think about. We ALSO might be able to move the tests into the CWG issues section (though likely, not for functions!).

Also-also: this needs a release note.

@@ -12163,6 +12163,23 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
}
}

// C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr
Copy link
Collaborator

Choose a reason for hiding this comment

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

Update this to the latest wording please! it is actually no longer specific to functions.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Notes are not normative, we can not use solely notes to justify code. We need to reference normative wording or the CWG issue or paper that brought the note and justifies the intent more clearly.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like this note came as a drive by edit when fixing cwg699

Copy link
Collaborator

Choose a reason for hiding this comment

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

OldDecl ? OldDecl->getAsFunction() : nullptr;
if (InstantiationFunction &&
InstantiationFunction->getTemplateSpecializationKind() ==
TSK_ImplicitInstantiation &&
Copy link
Collaborator

Choose a reason for hiding this comment

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

The old-decl should be a primary template, right? What sort of thigns are we looking to avoid here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The old decl here is the member method of the classTemplateSpecializationDecl (implict instantiation of the template). would it be correct to mutate if old decl was any other kind (like explicit specialization decl) ? also I guess we cannot have a scenario where an old decl would directly be the primary template (i.e TemplateDecl) ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

That is what I'm wondering, I think from reading the standard that the ONLY thing that matters is that the current one is an explicit specialization. The kind of the 'old' thing we found is irrelevant. It should always end up being a primary template (but even if it isn't, it shouldn't matter?). And even the existence of it doesn't matter, so long as we know we are an explicit specialization.

InstantiationFunction->getTemplateSpecializationKind() ==
TSK_ImplicitInstantiation &&
(NewFD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization ||
NewFD->getTemplateSpecializationKind() == TSK_Undeclared)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is going on here? Why do you not need to handle TSK_ExplicitInstantiationDeclaration and TSK_ExplicitInstantiationDefinition? Can you play with examples a bit more to see if/when those should be applied?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will update the tests with additional examples..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Specialization differs from the template declaration with respect to the constexpr specifier
3 participants