[clang] 79e17cd - [clang] Improve bit-field in ref NTTP diagnostic (#71077)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 9 09:14:21 PST 2024


Author: Andrey Ali Khan Bolshakov
Date: 2024-01-09T18:14:17+01:00
New Revision: 79e17cd01491c0fde241097ad4c5c24afbb1883e

URL: https://github.com/llvm/llvm-project/commit/79e17cd01491c0fde241097ad4c5c24afbb1883e
DIFF: https://github.com/llvm/llvm-project/commit/79e17cd01491c0fde241097ad4c5c24afbb1883e.diff

LOG: [clang] Improve bit-field in ref NTTP diagnostic (#71077)

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](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1907r1.html)).
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

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaOverload.cpp
    clang/test/CXX/drs/dr12xx.cpp
    clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c89488e54ef494..ddeb1186d65ac8 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: <https://github.com/llvm/llvm-project/issues/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 a97182cad5d513..3884dca59e2f3b 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 e6c267bb79e60b..64bc3851980272 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 adf7f56711c451..cb4cc5aef17371 100644
--- a/clang/test/CXX/drs/dr12xx.cpp
+++ b/clang/test/CXX/drs/dr12xx.cpp
@@ -154,7 +154,7 @@ namespace dr1295 { // dr1295: 4
   Y<x.bitfield> y; // #dr1295-y
   // cxx98-14-error at -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 792dc78464b2a8..982f6ec2215708 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 <A> struct X {};
   void f(X<1.0f>) {}
   void g(X<2>) {}
+
+  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