[clang] [clang] Improve bit-field in ref NTTP diagnostic (PR #71077)
Andrey Ali Khan Bolshakov via cfe-commits
cfe-commits at lists.llvm.org
Sun Dec 3 07:59:21 PST 2023
https://github.com/bolshakov-a updated https://github.com/llvm/llvm-project/pull/71077
>From bc2ea1ab74b613f700b11390a4715a0f2bec10e7 Mon Sep 17 00:00:00 2001
From: Bolshakov <bolsh.andrey at yandex.ru>
Date: Thu, 2 Nov 2023 19:20:27 +0300
Subject: [PATCH] [clang] Improve bit-field in ref NTTP diagnostic
Prior to this, attempts to bind a bit-field to an NTTP of reference type
produced an error because references to subobjects in NTTPs are
disallowed. But C++20 allows references to subobjects in NTTPs generally
(see P1907R1). Without this change, implementing P1907R1 would cause
a bug allowing bit-fields to be bound to reference template arguments.
Extracted from https://reviews.llvm.org/D140996
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
clang/lib/Sema/SemaOverload.cpp | 10 ++++++++++
clang/test/CXX/drs/dr12xx.cpp | 2 +-
clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp | 6 ++++++
4 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 474afc2fb99c1..94b836252eda5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2251,6 +2251,8 @@ def warn_cxx17_compat_aggregate_init_paren_list : Warning<
def err_reference_bind_to_bitfield : Error<
"%select{non-const|volatile}0 reference cannot bind to "
"bit-field%select{| %1}2">;
+def err_reference_bind_to_bitfield_in_cce : Error<
+ "reference cannot bind to bit-field in converted constant expression">;
def err_reference_bind_to_vector_element : Error<
"%select{non-const|volatile}0 reference cannot bind to vector element">;
def err_reference_bind_to_matrix_element : Error<
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index d3d2dfed2ce0c..befc27811ef45 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -6028,6 +6028,16 @@ static ExprResult BuildConvertedConstantExpression(Sema &S, Expr *From,
diag::err_typecheck_converted_constant_expression_indirect)
<< From->getType() << From->getSourceRange() << T;
}
+ // 'TryCopyInitialization' returns incorrect info for attempts to bind
+ // a reference to a bit-field due to C++ [over.ics.ref]p4. Namely,
+ // 'SCS->DirectBinding' occurs to be set to 'true' despite it is not
+ // the direct binding according to C++ [dcl.init.ref]p5. Hence, check this
+ // case explicitly.
+ if (From->refersToBitField() && T.getTypePtr()->isReferenceType()) {
+ return S.Diag(From->getBeginLoc(),
+ diag::err_reference_bind_to_bitfield_in_cce)
+ << From->getSourceRange();
+ }
// Usually we can simply apply the ImplicitConversionSequence we formed
// earlier, but that's not guaranteed to work when initializing an object of
diff --git a/clang/test/CXX/drs/dr12xx.cpp b/clang/test/CXX/drs/dr12xx.cpp
index c23a515ba56cb..81c113d4c1c5a 100644
--- a/clang/test/CXX/drs/dr12xx.cpp
+++ b/clang/test/CXX/drs/dr12xx.cpp
@@ -138,7 +138,7 @@ namespace dr1295 { // dr1295: 4
#if __cplusplus <= 201402L
// expected-error at -2 {{does not refer to any declaration}} expected-note at -3 {{here}}
#else
- // expected-error at -4 {{refers to subobject}}
+ // expected-error at -4 {{reference cannot bind to bit-field in converted constant expression}}
#endif
#if __cplusplus >= 201103L
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
index 9f9aad604d5f1..cd65a20bbf679 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
@@ -92,6 +92,12 @@ namespace ConvertedConstant {
template <A> struct X {};
void f(X<1.0f>) {} // OK, user-defined conversion
void f(X<2>) {} // expected-error {{conversion from 'int' to 'A' is not allowed in a converted constant expression}}
+
+ struct {
+ int i : 2;
+ } b;
+ template <const int&> struct Y {};
+ void f(Y<b.i>) {} // expected-error {{reference cannot bind to bit-field in converted constant expression}}
}
namespace CopyCounting {
More information about the cfe-commits
mailing list