[clang] Don't emit "no member" diagnostic if the lookup fails on an invalid record decl.

The "no member" diagnostic is likely bogus.

Reviewed By: sammccall, #libc

Differential Revision: https://reviews.llvm.org/D86765
This commit is contained in:
Haojian Wu 2020-09-28 15:08:28 +02:00
parent 1696dd27fb
commit bf890dcb0f
3 changed files with 33 additions and 2 deletions

View File

@ -2581,6 +2581,13 @@ ExprResult Sema::BuildQualifiedDeclarationNameExpr(
NameInfo, /*TemplateArgs=*/nullptr);
if (R.empty()) {
// Don't diagnose problems with invalid record decl, the secondary no_member
// diagnostic during template instantiation is likely bogus, e.g. if a class
// is invalid because it's derived from an invalid base class, then missing
// members were likely supposed to be inherited.
if (const auto *CD = dyn_cast<CXXRecordDecl>(DC))
if (CD->isInvalidDecl())
return ExprError();
Diag(NameInfo.getLoc(), diag::err_no_member)
<< NameInfo.getName() << DC << SS.getRange();
return ExprError();

View File

@ -89,3 +89,29 @@ namespace T7 {
};
}
namespace T8 {
template <int>
struct flag {
static constexpr bool value = true;
};
template <class T>
struct trait : flag<sizeof(T)> {};
template <class T, bool Inferred = trait<T>::value>
struct a {};
template <class T>
class b {
a<T> x;
using U = a<T>;
};
template <int>
struct Impossible {
static_assert(false, ""); // expected-error {{static_assert failed}}
};
// verify "no member named 'value'" bogus diagnostic is not emitted.
trait<b<Impossible<0>>>::value;
} // namespace T8

View File

@ -45,8 +45,6 @@ int main(int, char**) {
SPtr<3> s3(nullptr, Deleter{}); // OK
}
// expected-error-re@memory:* 2 {{static_assert failed{{.*}} "default_delete cannot be instantiated for function types"}}
// FIXME: suppress this bogus diagnostic, see https://reviews.llvm.org/D86685.
// expected-error@memory:* 0+ {{no member named 'value' in}}
{
SPtr<4> s4(getFn<4>()); // expected-note {{requested here}}
SPtr<5> s5(getFn<5>(), std::default_delete<FnType<5>>{}); // expected-note {{requested here}}