Since rL274049, for an inheriting constructor declaration, the name of the using declaration (and using shadow declaration comes from the using declaration) is the name of a derived class, not the base class (line 8225-8232 of lib/Sema/SemaDeclCXX.cpp in https://reviews.llvm.org/rL274049). Because of this, name-based lookup performed inside Sema::LookupConstructors returns not only CXXConstructorDecls but also Using(Shadow)Decls, which results assertion failure reported in PR 29087.
Details
- Reviewers
aaron.ballman rsmith - Commits
- rG6c2a4d630ec3: Merging r287999:
rGfec8345108c1: Adjust type-trait evaluation to properly handle Using(Shadow)Decls
rC287999: Adjust type-trait evaluation to properly handle Using(Shadow)Decls
rL287999: Adjust type-trait evaluation to properly handle Using(Shadow)Decls
Diff Detail
Event Timeline
lib/Sema/SemaExprCXX.cpp | ||
---|---|---|
4403 | This isn't really right: a UsingShadowDecl whose underlying declaration is a constructor should itself act like a constructor. This could matter in some obscure cases: struct B; struct A { A(B&); }; struct B : A { using A::A; }; What does __has_nothrow_copy(B) return? It should probably be false, since copying a non-const B object will invoke the A(B&) constructor, which may throw, even though the B(const B&) constructor does not. However, these __has_* traits should be considered deprecated and are essentially useless, so perhaps it doesn't matter too much whether we get these corner cases right. We also get the constructor template case "wrong" here, which I would imagine comes up a lot more frequently. | |
test/SemaCXX/crash-has-nothrow-constructor.cpp | ||
1 ↗ | (On Diff #71560) | Please add these tests into some existing test file for the type traits rather than adding two new files. |
Updated diff. For ConstructorUsingShadowDecl, test with its target CXXConstructorDecl, but only when it is not a default/copy/move constructor.
@rsmith Thank you for your review! I added tests to cxx11-crashes.cpp, as the goal of this patch is not handling __has_* traits right but preventing ICE. Also, I tried to use ConstructorUsingShadowDecl::getConstructor instead of ConstructorUsingShadowDecl::getTargetDecl followed by casting, but clang build was failed with undefined references. I wonder if the definition of ConstructorUsingShadowDecl::getConstructor is missed in https://reviews.llvm.org/rL274049.
lib/Sema/SemaExprCXX.cpp | ||
---|---|---|
4401–4402 | You also need to handle the case of an inherited constructor template (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()) will do the right thing in both cases). | |
4406–4408 | This is better written as auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl()); | |
4409–4412 | This is not necessary: Sema has already filtered out the ones that aren't inherited. |
You also need to handle the case of an inherited constructor template (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()) will do the right thing in both cases).