Skip to content

Commit 4435d1e

Browse files
committed
[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
1 parent b5f2db9 commit 4435d1e

File tree

5 files changed

+21
-1
lines changed

5 files changed

+21
-1
lines changed

clang/docs/ReleaseNotes.rst

+2
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,8 @@ Improvements to Clang's diagnostics
520520
- Clang now diagnoses narrowing conversions involving const references.
521521
(`#63151: <https://github.com/llvm/llvm-project/issues/63151>`_).
522522
- Clang now diagnoses unexpanded packs within the template argument lists of function template specializations.
523+
- Clang now diagnoses attempts to bind a bitfield to an NTTP of a reference type as erroneous
524+
converted constant expression and not as a reference to subobject.
523525

524526

525527
Improvements to Clang's time-trace

clang/include/clang/Basic/DiagnosticSemaKinds.td

+2
Original file line numberDiff line numberDiff line change
@@ -2253,6 +2253,8 @@ def warn_cxx17_compat_aggregate_init_paren_list : Warning<
22532253
def err_reference_bind_to_bitfield : Error<
22542254
"%select{non-const|volatile}0 reference cannot bind to "
22552255
"bit-field%select{| %1}2">;
2256+
def err_reference_bind_to_bitfield_in_cce : Error<
2257+
"reference cannot bind to bit-field in converted constant expression">;
22562258
def err_reference_bind_to_vector_element : Error<
22572259
"%select{non-const|volatile}0 reference cannot bind to vector element">;
22582260
def err_reference_bind_to_matrix_element : Error<

clang/lib/Sema/SemaOverload.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -6056,6 +6056,16 @@ static ExprResult BuildConvertedConstantExpression(Sema &S, Expr *From,
60566056
diag::err_typecheck_converted_constant_expression_indirect)
60576057
<< From->getType() << From->getSourceRange() << T;
60586058
}
6059+
// 'TryCopyInitialization' returns incorrect info for attempts to bind
6060+
// a reference to a bit-field due to C++ [over.ics.ref]p4. Namely,
6061+
// 'SCS->DirectBinding' occurs to be set to 'true' despite it is not
6062+
// the direct binding according to C++ [dcl.init.ref]p5. Hence, check this
6063+
// case explicitly.
6064+
if (From->refersToBitField() && T.getTypePtr()->isReferenceType()) {
6065+
return S.Diag(From->getBeginLoc(),
6066+
diag::err_reference_bind_to_bitfield_in_cce)
6067+
<< From->getSourceRange();
6068+
}
60596069

60606070
// Usually we can simply apply the ImplicitConversionSequence we formed
60616071
// earlier, but that's not guaranteed to work when initializing an object of

clang/test/CXX/drs/dr12xx.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ namespace dr1295 { // dr1295: 4
154154
Y<x.bitfield> y; // #dr1295-y
155155
// cxx98-14-error@-1 {{non-type template argument does not refer to any declaration}}
156156
// cxx98-14-note@#dr1295-Y {{template parameter is declared here}}
157-
// since-cxx17-error@#dr1295-y {{non-type template argument refers to subobject 'x.bitfield'}}
157+
// since-cxx17-error@#dr1295-y {{reference cannot bind to bit-field in converted constant expression}}
158158

159159
#if __cplusplus >= 201103L
160160
const unsigned other = 0;

clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ namespace ConvertedConstant {
9393
template <A> struct X {};
9494
void f(X<1.0f>) {}
9595
void g(X<2>) {}
96+
97+
struct {
98+
int i : 2;
99+
} b;
100+
template <const int&> struct Y {};
101+
void f(Y<b.i>) {} // expected-error {{reference cannot bind to bit-field in converted constant expression}}
96102
}
97103

98104
namespace CopyCounting {

0 commit comments

Comments
 (0)