[clang] [Clang][Sema] Fix crash in CheckUsingDeclQualifier due to diagnostic missing an argument (PR #161277)
Shafik Yaghmour via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 30 13:38:07 PDT 2025
https://github.com/shafik updated https://github.com/llvm/llvm-project/pull/161277
>From 227d45e09c1fa20f35ca0142ba93276fe37e6ab0 Mon Sep 17 00:00:00 2001
From: Shafik Yaghmour <shafik.yaghmour at intel.com>
Date: Mon, 29 Sep 2025 13:54:54 -0700
Subject: [PATCH 1/3] [Clang][Sema] Fix crash in CheckUsingDeclQualifier due to
diagnostic missing an argument
Crash report came in and it was pretty obvious the diagnostic line was just
missing an argument. I supplied the argument and added a test.
Fixes: https://github.com/llvm/llvm-project/issues/161072
---
clang/lib/Sema/SemaDeclCXX.cpp | 2 +-
clang/test/SemaCXX/cxx98-compat.cpp | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 63ce87b9b0607..7fa411fd817ae 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -13643,7 +13643,7 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc, bool HasTypename,
if (Cxx20Enumerator) {
Diag(NameLoc, diag::warn_cxx17_compat_using_decl_non_member_enumerator)
- << SS.getRange();
+ << SS.getScopeRep() << SS.getRange();
return false;
}
diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp
index 8e7acf73923e5..5651eee5a5c41 100644
--- a/clang/test/SemaCXX/cxx98-compat.cpp
+++ b/clang/test/SemaCXX/cxx98-compat.cpp
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s
// RUN: %clang_cc1 -fsyntax-only -std=c++14 -Wc++98-compat -verify %s -DCXX14COMPAT
// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat -verify %s -DCXX14COMPAT -DCXX17COMPAT
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -Wc++98-compat -verify %s -DCXX14COMPAT -DCXX17COMPAT -DCXX20COMPAT
namespace std {
struct type_info;
@@ -225,9 +226,12 @@ void TrivialButNonPODThroughEllipsis() {
Ellipsis(1, TrivialButNonPOD()); // expected-warning {{passing object of trivial but non-POD type 'TrivialButNonPOD' through variadic function is incompatible with C++98}}
}
+// FIXME I think we generate this diagnostic in C++20
+#ifndef CXX20COMPAT
struct HasExplicitConversion {
explicit operator bool(); // expected-warning {{explicit conversion functions are incompatible with C++98}}
};
+#endif
struct Struct {};
enum Enum { enum_val = 0 };
>From dece2b9c85709aa5733aeb30f16234ef474a05a7 Mon Sep 17 00:00:00 2001
From: Shafik Yaghmour <shafik.yaghmour at intel.com>
Date: Mon, 29 Sep 2025 16:25:01 -0700
Subject: [PATCH 2/3] Adding tests.
---
clang/test/SemaCXX/cxx98-compat.cpp | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp
index 5651eee5a5c41..104ccb4640c11 100644
--- a/clang/test/SemaCXX/cxx98-compat.cpp
+++ b/clang/test/SemaCXX/cxx98-compat.cpp
@@ -434,3 +434,15 @@ void ctad_test() {
CTAD t = s; // expected-warning {{class template argument deduction is incompatible with C++ standards before C++17}}
}
#endif
+
+namespace GH161702 {
+struct S {
+ enum E { A };
+ using E::A; // expected-warning {{enumeration type in nested name specifier is incompatible with C++98}}
+#ifndef CXX20COMPAT
+ // expected-error at -2 {{using declaration refers to its own class}}
+#else
+ // expected-warning at -4 {{member using declaration naming non-class ''E'' enumerator is incompatible with C++ standards before C++20}}
+#endif
+};
+}
>From 096c6e4dd039947366051d6c41320ffab56974fb Mon Sep 17 00:00:00 2001
From: Shafik Yaghmour <shafik.yaghmour at intel.com>
Date: Tue, 30 Sep 2025 13:37:40 -0700
Subject: [PATCH 3/3] Update test based on feedback.
---
clang/test/SemaCXX/cxx98-compat.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp
index 104ccb4640c11..692289cfa609e 100644
--- a/clang/test/SemaCXX/cxx98-compat.cpp
+++ b/clang/test/SemaCXX/cxx98-compat.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s
// RUN: %clang_cc1 -fsyntax-only -std=c++14 -Wc++98-compat -verify %s -DCXX14COMPAT
// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat -verify %s -DCXX14COMPAT -DCXX17COMPAT
-// RUN: %clang_cc1 -fsyntax-only -std=c++20 -Wc++98-compat -verify %s -DCXX14COMPAT -DCXX17COMPAT -DCXX20COMPAT
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -Wc++98-compat -verify=expected,cpp20 %s -DCXX14COMPAT -DCXX17COMPAT -DCXX20COMPAT
namespace std {
struct type_info;
@@ -226,7 +226,7 @@ void TrivialButNonPODThroughEllipsis() {
Ellipsis(1, TrivialButNonPOD()); // expected-warning {{passing object of trivial but non-POD type 'TrivialButNonPOD' through variadic function is incompatible with C++98}}
}
-// FIXME I think we generate this diagnostic in C++20
+// FIXME I think we should generate this diagnostic in C++20
#ifndef CXX20COMPAT
struct HasExplicitConversion {
explicit operator bool(); // expected-warning {{explicit conversion functions are incompatible with C++98}}
@@ -441,8 +441,7 @@ struct S {
using E::A; // expected-warning {{enumeration type in nested name specifier is incompatible with C++98}}
#ifndef CXX20COMPAT
// expected-error at -2 {{using declaration refers to its own class}}
-#else
- // expected-warning at -4 {{member using declaration naming non-class ''E'' enumerator is incompatible with C++ standards before C++20}}
#endif
+ // cpp20-warning at -4 {{member using declaration naming non-class ''E'' enumerator is incompatible with C++ standards before C++20}}
};
}
More information about the cfe-commits
mailing list