aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaojian Wu <hokein.wu@gmail.com>2020-09-28 15:08:28 +0200
committerHaojian Wu <hokein.wu@gmail.com>2020-09-28 15:10:00 +0200
commitbf890dcb0f5eb05b1a98cbd1cdd24c0c4ece8f8d (patch)
tree2acb622bf4297b8fd93ff8426ff46791d9fb3c7e
parent1696dd27fb619fbf6d28cf6aa0d74cf8ef883723 (diff)
downloadllvm-bf890dcb0f5eb05b1a98cbd1cdd24c0c4ece8f8d.zip
llvm-bf890dcb0f5eb05b1a98cbd1cdd24c0c4ece8f8d.tar.gz
llvm-bf890dcb0f5eb05b1a98cbd1cdd24c0c4ece8f8d.tar.bz2
[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
-rw-r--r--clang/lib/Sema/SemaExpr.cpp7
-rw-r--r--clang/test/SemaCXX/access-base-class.cpp26
-rw-r--r--libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp2
3 files changed, 33 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 9cd5a35..a7c0766 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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();
diff --git a/clang/test/SemaCXX/access-base-class.cpp b/clang/test/SemaCXX/access-base-class.cpp
index f676e19..2ed40ed 100644
--- a/clang/test/SemaCXX/access-base-class.cpp
+++ b/clang/test/SemaCXX/access-base-class.cpp
@@ -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
diff --git a/libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp b/libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
index 0bba136..5727db6 100644
--- a/libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
+++ b/libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/function_type_default_deleter.fail.cpp
@@ -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}}