This is an archive of the discontinued LLVM Phabricator instance.

[Clang] Tighten restrictions on enum out of range diagnostic to avoid constant initialization
ClosedPublic

Authored by shafik on Aug 14 2022, 10:24 PM.

Details

Summary

The restrictions added in D131704 were not sufficient to avoid all non-constant expression contexts. In particular constant initialization cases.

We need to check EvaluatingDecl to detect if the variable we are initializing is constexpr or not.

At this point it looks like this is the remaining case affecting various projects with this diagnostic.

Diff Detail

Event Timeline

shafik created this revision.Aug 14 2022, 10:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 14 2022, 10:24 PM
shafik requested review of this revision.Aug 14 2022, 10:24 PM

Thanks! With this, I think all my cases (that built before D131307) now build successfully again! (Can't say much about the code change itself, but I think it looks reasonable.)

aaron.ballman added inline comments.Aug 15 2022, 5:51 AM
clang/lib/AST/ExprConstant.cpp
13547–13551

This seems to be equivalent unless I'm misunderstanding something about the member dyn_cast.

13570–13577

Might as well test the easy condition before doing more work to get values and compare them.

I think we should rename NotConstexprVar to ConstexprVar so that we don't need the double negation here. WDYT?

clang/test/SemaCXX/constant-expression-cxx11.cpp
2424–2427

Do you think it's worth it to add this as a test as well?

consteval void testDefaultArgForParam2(E2 e2Param = (E2)-1) {
}

void test() {
  testDefaultArgForParam2(); // Make sure we get the error
  testDefaultArgForParam2((E2)0); // Make sure we don't get the error
}
shafik updated this revision to Diff 452775.Aug 15 2022, 12:17 PM
shafik marked an inline comment as done.
  • Changed NotConstexprVar to ConstExprVar
  • Moved checking of ConstexprVar up so that we do the less expensive check first
clang/lib/AST/ExprConstant.cpp
13547–13551

I think the problem is that PointerUnion requires that it be one of the static types it was defined with and in this case that is const ValueDecl *, const Expr * but maybe I am missing something.

13570–13577

Makes sense.

clang/test/SemaCXX/constant-expression-cxx11.cpp
2424–2427

It is a good idea but the diagnostic does not point to the line in test() which is unfortunate.

shafik added inline comments.Aug 15 2022, 2:09 PM
clang/lib/AST/ExprConstant.cpp
13547–13551

It looks like the big difference is that in doCastIfPossible(...) we end up calling Self::isPossible(f) which ends up in PointerUnion::isPossible...) which uses FirstIndexOfType and if the template arguments don't contain the type then it fail.

aaron.ballman added inline comments.Aug 16 2022, 6:42 AM
clang/lib/AST/ExprConstant.cpp
13547–13551

Whelp, TIL!

Then I guess I'd go with:

if (const auto *VD = dyn_cast_or_null<VarDecl>(Info.EvaluatingDecl.dyn_cast<const ValueDecl *>))

shafik updated this revision to Diff 453062.Aug 16 2022, 10:28 AM
shafik marked an inline comment as done.
  • Addressing comments on casting of EvaluatingDecl

I confirmed that this fixes all remaining issues on our end. Thank you!

Precommit CI failures are unrelated to this patch.

clang/lib/AST/ExprConstant.cpp
13547–13550

You already know that VD is nonnull, so no need for that check, and we can remove the predicate entirely because you're setting ConstexprVar based on isConstexpr() anyway.

shafik updated this revision to Diff 453350.Aug 17 2022, 11:07 AM
shafik marked 2 inline comments as done.
  • Simplify condition to set ConstexprVar even more
ayzhao added a subscriber: ayzhao.Aug 17 2022, 11:15 AM
wlei added a subscriber: wlei.Aug 17 2022, 12:07 PM
shafik updated this revision to Diff 453389.Aug 17 2022, 12:09 PM
shafik marked an inline comment as done.
  • Added consteval test with default parameters
This revision is now accepted and ready to land.Aug 17 2022, 12:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 17 2022, 2:14 PM

Thanks! It seems like this now finally works as it should again, with the code I regularly build.