diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c89488e54ef49..ddeb1186d65ac 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -520,6 +520,8 @@ Improvements to Clang's diagnostics - Clang now diagnoses narrowing conversions involving const references. (`#63151: `_). - Clang now diagnoses unexpanded packs within the template argument lists of function template specializations. +- Clang now diagnoses attempts to bind a bitfield to an NTTP of a reference type as erroneous + converted constant expression and not as a reference to subobject. Improvements to Clang's time-trace diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a97182cad5d51..3884dca59e2f3 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2253,6 +2253,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 e6c267bb79e60..64bc385198027 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -6056,6 +6056,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 adf7f56711c45..cb4cc5aef1737 100644 --- a/clang/test/CXX/drs/dr12xx.cpp +++ b/clang/test/CXX/drs/dr12xx.cpp @@ -154,7 +154,7 @@ namespace dr1295 { // dr1295: 4 Y y; // #dr1295-y // cxx98-14-error@-1 {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#dr1295-Y {{template parameter is declared here}} - // since-cxx17-error@#dr1295-y {{non-type template argument refers to subobject 'x.bitfield'}} + // since-cxx17-error@#dr1295-y {{reference cannot bind to bit-field in converted constant expression}} #if __cplusplus >= 201103L const unsigned other = 0; diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp index 792dc78464b2a..982f6ec221570 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp @@ -93,6 +93,12 @@ namespace ConvertedConstant { template struct X {}; void f(X<1.0f>) {} void g(X<2>) {} + + struct { + int i : 2; + } b; + template struct Y {}; + void f(Y) {} // expected-error {{reference cannot bind to bit-field in converted constant expression}} } namespace CopyCounting {