Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
2724 | You should re-flow the whole diagnostic to the usual 80-col limit. | |
clang/lib/Sema/SemaDeclCXX.cpp | ||
1903–1912 | Formatting looks off here (I was expecting the else if on the same line as the curly brace, but maybe clang-format is being weird?) | |
1907 | ||
clang/test/SemaCXX/constant-expression-cxx2b.cpp | ||
99 | Shouldn't this be a cxx2b-warning instead? |
- fix formatting
- use cxx2b in the test as per aaron request. This doesn't really matter as this part
of the test file is only executed in c++2b mode though.
clang/lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
1905 | This seems to trigger even when the type is dependent: <stdin>:1:36: warning: definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b [-Wpre-c++2b-compat] auto qq = [](auto x) { decltype(x) n; }; ^ 1 warning generated. This also seems to emit even when Kind is not Sema::CheckConstexprKind::Diagnose (unlike the static/thread_local case above). Is the CheckLiteralType logic not reusable for this? | |
clang/test/SemaCXX/constant-expression-cxx2b.cpp | ||
219 | Not sure how much we want the message in this case. The lambda is not marked constexpr (although it is implicitly constexpr in C++2b). Note that we don't get a message for this: auto qq = [] { return 0; static int x = 42; }; constexpr int qx = qq(); I am not sure how difficult it would be to come at this from the used-in-constant-evaluation side, but there is probably a larger class of messages in the same situation (so it would probably be a separate endeavour). |
- Check That the type is dependant
- Only emit the warning when Kind == Sema::CheckConstexprKind::Diagnose
clang/lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
1905 | You are right, thanks for noticing that, it was rather bogus. It leaves us with an uncovered scenario though: We do not emit the warning on template instantiation, and I don't think there is an easy way to do that. |
I'm seeing precommit CI failures:
Failed Tests (1):
Clang :: SemaCXX/constant-expression-cxx2b.cpp
clang/lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
1905 |
Huh? static bool CheckLiteralType(Sema &SemaRef, Sema::CheckConstexprKind Kind, SourceLocation Loc, QualType T, unsigned DiagID, Ts &&...DiagArgs) { ... } I would hope DiagArgs should do exactly that? :-) |
- Fix test
- Add a comment explaining why we do not use CheckLiteralType
@aaron,ballman I completely missed that...!
However, CheckLiteralType does a bunch of tests that we do not need
to diagnose *why* a type is not literal, which we do not care about here.
I tried to play around with the code and trying to use CheckLiteralType, or to modify
it for this scenario does not appear to me an improvenent, so I rather keep the change as is.
I also fixed the fail test, i think i accidentally removed a line from the test file...
No worries!
However, CheckLiteralType does a bunch of tests that we do not need
to diagnose *why* a type is not literal, which we do not care about here.
I think those kinds of diagnostics could be useful to a developer who has enabled this compat warning. It may not be immediately clear why the type is not a literal, and those notes can help some folks get to that answer much more quickly. Do you have some examples of whether the diagnostics clearly are distracting or useless?
clang/lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
1905 |
I believe the code paths that lead us here all come from Sema::CheckConstexprFunctionDefinition() which is called from Sema::ActOnFinishFunctionBody() which seems to be called when instantiating templates in Sema::InstantiateFunctionDefinition(), so perhaps some more investigation is needed as to why we're not reaching this for template instantiations. |
clang/lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
1905 | We could add something in addition of Sema::CheckConstexprKind::CheckValid and Sema::CheckConstexprKind::Diagnose, but
|
After talks with Aaron, I'm using CheckLiteralType
in all cases, which adds notes about why a type
is not literal.
We still need to branch on CPlusPlus2b because the
diagnostics take a variable number of arguments,
and I'd rather not have more diagnostics.
clang/lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
1905–1907 | Apply Aaron's suggestion (https://reviews.llvm.org/D122249?id=417358#inline-1168823) to the updated code. |
- Add a commebt to clarify which diagnostic message is being printed,
as per Aaron suggestion.
This LGTM (with minor comment). Please wait for Aaron to respond re: the handling of template instantiations.
clang/lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
1905 |
@aaron.ballman, do you have any position on whether we want this investigation before moving forward with this patch? | |
1912–1913 | Minor nit: The coding standards were updated (some time ago now) to recommend keeping if-else chains consistently braced or not-braced. |
LGTM
clang/lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
1905 |
@hubert.reinterpretcast -- I think @cor3ntin did that investigation and found that we don't make it to this code path because of https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaDecl.cpp#L14961. I think this is incremental progress, and we can handle the template instantiation cases in a follow-up. |
I thing to support the template case, we would have to modify TemplateDeclInstantiator::VisitVarDecl - which seems the best way to have a diagnostic without running through the whole function AST twice.
However, there is currently no check of any sort there so it would be a bit novel and odd!
Thank you both for the review
Edit: Longer comment
As per http://eel.is/c++draft/dcl.constexpr#7, the standard doesn't require to check the whole function on instantiation.
And there would be issue in doing that: all the warnings, emitted in other cases, would have to not be re-emitted
consider
constexpr void f(auto) { if(false) goto a; a:; } void g() { f(0); }
We do not want to warn twice here.
So we can't reuse the existing infrastructure.
The functions checking for constant-evaluations are not great either because they may ignore branches etc.
So I think the two options are
- During instantiation warn fir non-literal var decls if they are in the context of a constexpr function
- Make a new function like CheckConstexprFunctionBody for only that warning and go through the whole tree twice
- Modify CheckConstexprFunctionBody with a new Sema::CheckConstexprKind thing for instantiation, which also goes through the whole tree twice.
None of these options seem great.
You should re-flow the whole diagnostic to the usual 80-col limit.