[cfe-commits] r94831 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaInit.cpp test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp

Douglas Gregor dgregor at apple.com
Fri Jan 29 11:39:16 PST 2010


Author: dgregor
Date: Fri Jan 29 13:39:15 2010
New Revision: 94831

URL: http://llvm.org/viewvc/llvm-project?rev=94831&view=rev
Log:
Fix reference-binding when we have a reference to const volatile type;
previously, we were allowing this to bind to a temporary. Now, we
don't; add test-cases and improve diagnostics.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=94831&r1=94830&r2=94831&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 29 13:39:15 2010
@@ -560,14 +560,14 @@
 def err_lvalue_to_rvalue_ambig_ref : Error<"rvalue reference cannot bind to lvalue "
                                            "due to multiple conversion functions">;
 def err_not_reference_to_const_init : Error<
-  "non-const lvalue reference to type %0 cannot be initialized "
-  "with a %select{value|temporary}1 of type %2">;
+  "%select{non-const|volatile}0 lvalue reference to type %1 cannot be "
+  "initialized with a %select{value|temporary}2 of type %3">;
 def err_lvalue_reference_bind_to_temporary : Error<
-  "non-const lvalue reference to type %0 cannot bind to a temporary of type "
-  "%1">;
+  "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
+  "temporary of type %2">;
 def err_lvalue_reference_bind_to_unrelated : Error<
-  "non-const lvalue reference to type %0 cannot bind to a value of unrelated "
-  "type %1">;
+  "%select{non-const|volatile}0 lvalue reference to type %1 cannot bind to a "
+  "value of unrelated type %2">;
 def err_reference_bind_drops_quals : Error<
   "binding of reference to type %0 to a value of type %1 drops qualifiers">;
 def err_reference_bind_failed : Error<

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=94831&r1=94830&r2=94831&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Jan 29 13:39:15 2010
@@ -4616,6 +4616,7 @@
   if (!isRValRef && T1.getCVRQualifiers() != Qualifiers::Const) {
     if (!ICS)
       Diag(DeclLoc, diag::err_not_reference_to_const_init)
+        << T1.isVolatileQualified()
         << T1 << int(InitLvalue != Expr::LV_Valid)
         << T2 << Init->getSourceRange();
     return true;

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=94831&r1=94830&r2=94831&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Jan 29 13:39:15 2010
@@ -2369,7 +2369,7 @@
   //       non-volatile const type (i.e., cv1 shall be const), or the reference
   //       shall be an rvalue reference and the initializer expression shall 
   //       be an rvalue.
-  if (!((isLValueRef && T1Quals.hasConst()) ||
+  if (!((isLValueRef && T1Quals.hasConst() && !T1Quals.hasVolatile()) ||
         (isRValueRef && InitLvalue != Expr::LV_Valid))) {
     if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
       Sequence.SetOverloadFailure(
@@ -3556,6 +3556,7 @@
            Failure == FK_NonConstLValueReferenceBindingToTemporary
              ? diag::err_lvalue_reference_bind_to_temporary
              : diag::err_lvalue_reference_bind_to_unrelated)
+      << DestType.getNonReferenceType().isVolatileQualified()
       << DestType.getNonReferenceType()
       << Args[0]->getType()
       << Args[0]->getSourceRange();

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp?rev=94831&r1=94830&r2=94831&view=diff

==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp Fri Jan 29 13:39:15 2010
@@ -68,17 +68,23 @@
   volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'struct Base volatile' to a value of type 'struct Derived const volatile' drops qualifiers}}
   
   volatile int &ir = ivc; // expected-error{{binding of reference to type 'int volatile' to a value of type 'int const volatile' drops qualifiers}}
+
+  const volatile Base &bcvr1 = b;
+  const volatile Base &bcvr2 = d;
 }
 
 void bind_lvalue_to_rvalue() {
   Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a temporary of type 'struct Base'}}
   Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a temporary of type 'struct Derived'}}
+  const volatile Base &br3 = Base(); // expected-error{{volatile lvalue reference to type 'struct Base const volatile' cannot bind to a temporary of type 'struct Base'}}
+  const volatile Base &br4 = Derived(); // expected-error{{volatile lvalue reference to type 'struct Base const volatile' cannot bind to a temporary of type 'struct Derived'}}
 
   int &ir = 17; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
 }
 
 void bind_lvalue_to_unrelated(Unrelated ur) {
   Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a value of unrelated type 'struct Unrelated'}}
+  const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'struct Base const volatile' cannot bind to a value of unrelated type 'struct Unrelated'}}
 }
 
 void bind_lvalue_to_conv_lvalue() {





More information about the cfe-commits mailing list