-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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] Assertion compiling a varadic template when using C++20, but not C++17 #65982
Comments
@llvm/issue-subscribers-clang-frontend |
We are crashing in llvm-project/clang/lib/AST/ExprConstant.cpp Lines 6121 to 6125 in eb81493
b/c When we start MemberExpr 0x14a80a238 'int' lvalue .k 0x15a8c4ba8
|-NestedNameSpecifier TypeSpec 'struct A'
`-ImplicitCastExpr 0x14a80a208 'struct base' lvalue <UncheckedDerivedToBase (virtual base)>
`-ImplicitCastExpr 0x14a80a1e8 'struct A' lvalue <UncheckedDerivedToBase (A)>
`-DeclRefExpr 0x14a80a1c0 'X<A, B>':'struct X<struct A, struct B>' lvalue Var 0x14a809d88 'x' 'X<A, B>':'struct X<struct A, struct B>' We subtract once for the CC @zygoloid since he wrote this code in 31c69a3 and there is bad assumption someplace but it is not obvious where it is. |
It seems like we are not taking into account the case in which have nested casts. After entering the outer llvm-project/clang/lib/AST/ExprConstant.cpp Lines 6119 to 6126 in eb81493
However, we are not actually stepping over the inner ICE. @@ -6109,8 +6109,6 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr,
--PathLength;
} else if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
- // Step over a derived-to-base conversion.
- E = ICE->getSubExpr();
if (ICE->getCastKind() == CK_NoOp)
continue;
if (ICE->getCastKind() != CK_DerivedToBase &&
@@ -6125,6 +6123,10 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr,
.getAsBaseOrMember().getPointer()));
}
+ // Step over a derived-to-base conversion.
+ if (isa<ImplicitCastExpr>(ICE->getSubExpr()))
+ E = cast<ImplicitCastExpr>(ICE->getSubExpr())->getSubExpr();
+
// -- Otherwise, S(E) is empty.
} else {
break; @zygoloid, could this look like a proper fix? If so, would be happy to open a patch for it. |
It sounds like the AST representation might be broken here? Shouldn't each |
Hm, I think the problem here is likely to be that we're not handling virtual base classes properly in this code at all. We can't just truncate the path on the LHS in this case; we'd need to find the derived type that was the source of the derived -> base conversion. And we don't have enough information to do that. Fortunately, we don't actually need to do that at all, because a class with a virtual base class can never have a trivial default constructor, so if we see a conversion from derived to virtual base class, we're done finding entries in S(E) and can immediately stop. So: for (const CXXBaseSpecifier *Elt : llvm::reverse(ICE->path())) {
+ if (Elt->isVirtual()) {
+ // A class with virtual base classes never has a trivial default
+ // constructor, so S(E) is empty in this case.
+ E = nullptr;
+ break;
+ }
--PathLength;
- (void)Elt;
assert(declaresSameEntity(Elt->getType()->getAsCXXRecordDecl(),
LHS.Designator.Entries[PathLength]
.getAsBaseOrMember().getPointer()));
} |
Thanks for the answer! I see that now, indeed a default constructor is trivial if its class has no virtual base class, amongst others. Thus, no need for further derived-to-base analysis in this case, so it would make sense to bail out upon encountering a virtual base class. @zygoloid, do you want me to address this? |
I don't know if you realize you are creating duplicate responses or not. I made the change to a local branch and tested them and they don't seem to break anything. If you would like this to be your first clang change feel free to assign it to yourself and see the github documents here: https://llvm.org/docs/GitHub.html#github-reviews |
Apologies for that, I didn't mean to create any duplicate responses here. I didn't draw any conclusions about @zygoloid being OK with that, so I preferred to ensure myself I was not stepping over anyone else, waiting for their reply. I had quickly tested the change this morning locally as well, and it looked OK to me – but if you have a ready branch, please go ahead. |
@antoniofrighetto Please go ahead :) |
An assertion issue that arose when handling union member access with virtual base class has been addressed. As pointed out by @zygoloid, there is no need for further derived-to-base analysis in this instance, so we can bail out upon encountering a virtual base class. Minor refinement on the function name as we might not be handling a union. Reported-By: ormris Fixes: llvm#65982
An assertion issue that arose when handling union member access with virtual base class has been addressed. As pointed out by @zygoloid, there is no need for further derived-to-base analysis in this instance, so we can bail out upon encountering a virtual base class. Minor refinement on the function name as we might not be handling a union. Reported-By: ormris Fixes: llvm#65982
An assertion issue that arose when handling union member access with virtual base class has been addressed. As pointed out by @zygoloid, there is no need for further derived-to-base analysis in this instance, so we can bail out upon encountering a virtual base class. Minor refinement on the function name as we might not be handling a union. Reported-By: ormris Fixes: llvm#65982
/cherry-pick 660876a |
/branch llvm/llvm-project-release-prs/issue65982 |
An assertion issue that arose when handling union member access with virtual base class has been addressed. As pointed out by @zygoloid, there is no need for further derived-to-base analysis in this instance, so we can bail out upon encountering a virtual base class. Minor refinement on the function name as we might not be handling a union. Reported-By: ormris Fixes: llvm/llvm-project#65982 (cherry picked from commit 660876a4019b81b5a7427a3dcec5ce8c39cd1ee0)
/pull-request llvm/llvm-project-release-prs#703 |
Re-doing the cherry-pick to fix failing test. |
/branch llvm/llvm-project-release-prs/issue65982 |
An assertion issue that arose when handling union member access with virtual base class has been addressed. As pointed out by @zygoloid, there is no need for further derived-to-base analysis in this instance, so we can bail out upon encountering a virtual base class. Minor refinement on the function name as we might not be handling a union. Reported-By: ormris Fixes: llvm/llvm-project#65982 (cherry picked from commit 660876a4019b81b5a7427a3dcec5ce8c39cd1ee0)
An assertion issue that arose when handling union member access with virtual base class has been addressed. As pointed out by @zygoloid, there is no need for further derived-to-base analysis in this instance, so we can bail out upon encountering a virtual base class. Minor refinement on the function name as we might not be handling a union. Reported-By: ormris Fixes: llvm/llvm-project#65982 (cherry picked from commit 660876a4019b81b5a7427a3dcec5ce8c39cd1ee0)
When
-std=c++20
is specified, clang fails to build a simple program that instantiates a varadic template due to an assertion. Compiling the same program with-std=c++17
works as expected.Code:
Output:
The text was updated successfully, but these errors were encountered: