[cfe-commits] r108253 - in /cfe/trunk: include/clang/AST/DeclObjC.h include/clang/AST/Type.h lib/AST/DeclTemplate.cpp lib/AST/Type.cpp lib/CodeGen/CGExprComplex.cpp lib/Sema/SemaCXXCast.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/cv-unqual-rvalues.cpp

Douglas Gregor dgregor at apple.com
Tue Jul 13 11:40:04 PDT 2010


Author: dgregor
Date: Tue Jul 13 13:40:04 2010
New Revision: 108253

URL: http://llvm.org/viewvc/llvm-project?rev=108253&view=rev
Log:
Whenever we're creating an expression that is typically an rvalue
(e.g., a call, cast, etc.), immediately adjust the expression's type
to strip cv-qualifiers off of all non-class types (in C++) or all
types (in C). This effectively extends my previous fix for PR7463,
which was restricted to calls, to other kinds of expressions within
similar characteristics. I've audited every use of
getNonReferenceType() in the code base, switching to the newly-renamed
getNonLValueExprType() where necessary. 

Big thanks to Eli for pointing out just how incomplete my original fix
for PR7463 actually was. We've been handling cv-qualifiers on rvalues
wrong for a very, very long time. Fixes PR7463.

Added:
    cfe/trunk/test/SemaCXX/cv-unqual-rvalues.cpp   (with props)
Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/CodeGen/CGExprComplex.cpp
    cfe/trunk/lib/Sema/SemaCXXCast.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=108253&r1=108252&r2=108253&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Tue Jul 13 13:40:04 2010
@@ -242,7 +242,7 @@
   /// \brief Determine the type of an expression that sends a message to this 
   /// function.
   QualType getSendResultType() const {
-    return getResultType().getCallResultType(getASTContext());
+    return getResultType().getNonLValueExprType(getASTContext());
   }
   
   TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=108253&r1=108252&r2=108253&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Tue Jul 13 13:40:04 2010
@@ -629,13 +629,15 @@
   bool isAtLeastAsQualifiedAs(QualType Other) const;
   QualType getNonReferenceType() const;
 
-  /// \brief Determine the type of an expression that calls a function of
-  /// with the given result type.
+  /// \brief Determine the type of a (typically non-lvalue) expression with the
+  /// specified result type.
   ///                       
-  /// This routine removes a top-level reference (since there are no 
+  /// This routine should be used for expressions for which the return type is
+  /// explicitly specified (e.g., in a cast or call) and isn't necessarily
+  /// an lvalue. It removes a top-level reference (since there are no 
   /// expressions of reference type) and deletes top-level cvr-qualifiers
   /// from non-class types (in C++) or all types (in C).
-  QualType getCallResultType(ASTContext &Context) const;
+  QualType getNonLValueExprType(ASTContext &Context) const;
   
   /// getDesugaredType - Return the specified type with any "sugar" removed from
   /// the type.  This takes off typedefs, typeof's etc.  If the outer level of
@@ -1907,7 +1909,7 @@
   /// \brief Determine the type of an expression that calls a function of
   /// this type.
   QualType getCallResultType(ASTContext &Context) const { 
-    return getResultType().getCallResultType(Context);
+    return getResultType().getNonLValueExprType(Context);
   }
 
   static llvm::StringRef getNameForCallConv(CallingConv CC);

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=108253&r1=108252&r2=108253&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Tue Jul 13 13:40:04 2010
@@ -223,7 +223,7 @@
     } else if (NonTypeTemplateParmDecl *NTTP =
                  dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
       Expr *E = new (Context) DeclRefExpr(NTTP,
-                                          NTTP->getType().getNonReferenceType(),
+                                  NTTP->getType().getNonLValueExprType(Context),
                                           NTTP->getLocation());
       TemplateArgs.push_back(TemplateArgument(E));
     } else {

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=108253&r1=108252&r2=108253&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Tue Jul 13 13:40:04 2010
@@ -992,7 +992,7 @@
 
 void FunctionType::ANCHOR() {} // Key function for FunctionType.
 
-QualType QualType::getCallResultType(ASTContext &Context) const {
+QualType QualType::getNonLValueExprType(ASTContext &Context) const {
   if (const ReferenceType *RefType = getTypePtr()->getAs<ReferenceType>())
     return RefType->getPointeeType();
   

Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=108253&r1=108252&r2=108253&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Tue Jul 13 13:40:04 2010
@@ -572,8 +572,8 @@
   TestAndClearIgnoreImag();
   bool ignreal = TestAndClearIgnoreRealAssign();
   bool ignimag = TestAndClearIgnoreImagAssign();
-  assert(CGF.getContext().getCanonicalType(E->getLHS()->getType()) ==
-         CGF.getContext().getCanonicalType(E->getRHS()->getType()) &&
+  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), 
+                                                 E->getRHS()->getType()) &&
          "Invalid assignment");
   // Emit the RHS.
   ComplexPairTy Val = Visit(E->getRHS());

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=108253&r1=108252&r2=108253&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Tue Jul 13 13:40:04 2010
@@ -153,7 +153,8 @@
   case tok::kw_const_cast:
     if (!TypeDependent)
       CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
-    return Owned(new (Context) CXXConstCastExpr(DestType.getNonReferenceType(),
+    return Owned(new (Context) CXXConstCastExpr(
+                                        DestType.getNonLValueExprType(Context),
                                                 Ex, DestTInfo, OpLoc));
 
   case tok::kw_dynamic_cast: {
@@ -161,7 +162,8 @@
     CXXBaseSpecifierArray BasePath;
     if (!TypeDependent)
       CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange, Kind, BasePath);
-    return Owned(new (Context)CXXDynamicCastExpr(DestType.getNonReferenceType(),
+    return Owned(new (Context)CXXDynamicCastExpr(
+                                          DestType.getNonLValueExprType(Context),
                                                  Kind, Ex, BasePath, DestTInfo,
                                                  OpLoc));
   }
@@ -170,7 +172,7 @@
     if (!TypeDependent)
       CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind);
     return Owned(new (Context) CXXReinterpretCastExpr(
-                                  DestType.getNonReferenceType(),
+                                  DestType.getNonLValueExprType(Context),
                                   Kind, Ex, CXXBaseSpecifierArray(), 
                                   DestTInfo, OpLoc));
   }
@@ -180,7 +182,8 @@
     if (!TypeDependent)
       CheckStaticCast(*this, Ex, DestType, OpRange, Kind, BasePath);
     
-    return Owned(new (Context) CXXStaticCastExpr(DestType.getNonReferenceType(),
+    return Owned(new (Context) CXXStaticCastExpr(
+                                         DestType.getNonLValueExprType(Context),
                                                  Kind, Ex, BasePath,
                                                  DestTInfo, OpLoc));
   }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=108253&r1=108252&r2=108253&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jul 13 13:40:04 2010
@@ -475,6 +475,7 @@
     if (isa<NonTypeTemplateParmDecl>(VD)) {
       // Non-type template parameters can be referenced anywhere they are
       // visible.
+      Ty = Ty.getNonLValueExprType(Context);
     } else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
       if (const FunctionDecl *FD = MD->getParent()->isLocalClass()) {
         if (VD->hasLocalStorage() && VD->getDeclContext() != CurContext) {
@@ -4008,7 +4009,8 @@
     return ExprError();
 
   Op.release();
-  return Owned(new (Context) CStyleCastExpr(Ty->getType().getNonReferenceType(),
+  return Owned(new (Context) CStyleCastExpr(
+                                    Ty->getType().getNonLValueExprType(Context),
                                             Kind, castExpr, BasePath, Ty,
                                             LParenLoc, RParenLoc));
 }
@@ -4904,7 +4906,7 @@
   // The getNonReferenceType() call makes sure that the resulting expression
   // does not have reference type.
   if (result != Incompatible && rExpr->getType() != lhsType)
-    ImpCastExprToType(rExpr, lhsType.getNonReferenceType(),
+    ImpCastExprToType(rExpr, lhsType.getNonLValueExprType(Context),
                       CastExpr::CK_Unknown);
   return result;
 }
@@ -7348,7 +7350,8 @@
   // FIXME: Warn if a non-POD type is passed in.
 
   expr.release();
-  return Owned(new (Context) VAArgExpr(BuiltinLoc, E, T.getNonReferenceType(),
+  return Owned(new (Context) VAArgExpr(BuiltinLoc, E, 
+                                       T.getNonLValueExprType(Context),
                                        RPLoc));
 }
 

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=108253&r1=108252&r2=108253&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Jul 13 13:40:04 2010
@@ -540,7 +540,8 @@
 
     exprs.release();
 
-    return Owned(new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(),
+    return Owned(new (Context) CXXFunctionalCastExpr(
+                                              Ty.getNonLValueExprType(Context),
                                                      TInfo, TyBeginLoc, Kind,
                                                      Exprs[0], BasePath,
                                                      RParenLoc));
@@ -1879,7 +1880,7 @@
   case ICK_Qualification:
     // FIXME: Not sure about lvalue vs rvalue here in the presence of rvalue
     // references.
-    ImpCastExprToType(From, ToType.getNonReferenceType(),
+    ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
                       CastExpr::CK_NoOp, ToType->isLValueReferenceType());
 
     if (SCS.DeprecatedStringLiteralToCharPtr)

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=108253&r1=108252&r2=108253&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Jul 13 13:40:04 2010
@@ -523,8 +523,9 @@
   StructuredList->setSyntacticForm(IList);
   CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true, 
                         Index, StructuredList, StructuredIndex, TopLevelObject);
-  IList->setType(T.getNonReferenceType());
-  StructuredList->setType(T.getNonReferenceType());
+  QualType ExprTy = T.getNonLValueExprType(SemaRef.Context);
+  IList->setType(ExprTy);
+  StructuredList->setType(ExprTy);
   if (hadError)
     return;
 
@@ -1716,7 +1717,7 @@
                                          InitRange.getBegin(), 0, 0,
                                          InitRange.getEnd());
 
-  Result->setType(CurrentObjectType.getNonReferenceType());
+  Result->setType(CurrentObjectType.getNonLValueExprType(SemaRef.Context));
 
   // Pre-allocate storage for the structured initializer list.
   unsigned NumElements = 0;
@@ -2370,13 +2371,14 @@
 
   // Add the user-defined conversion step.
   Sequence.AddUserConversionStep(Function, Best->FoundDecl,
-                                 T2.getNonReferenceType());
+                                 T2.getNonLValueExprType(S.Context));
 
   // Determine whether we need to perform derived-to-base or 
   // cv-qualification adjustments.
   bool NewDerivedToBase = false;
   Sema::ReferenceCompareResult NewRefRelationship
-    = S.CompareReferenceRelationship(DeclLoc, T1, T2.getNonReferenceType(),
+    = S.CompareReferenceRelationship(DeclLoc, T1, 
+                                     T2.getNonLValueExprType(S.Context),
                                      NewDerivedToBase);
   if (NewRefRelationship == Sema::Ref_Incompatible) {
     // If the type we've converted to is not reference-related to the

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=108253&r1=108252&r2=108253&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Jul 13 13:40:04 2010
@@ -3727,7 +3727,7 @@
   // there are 0 arguments (i.e., nothing is allocated using ASTContext's
   // allocator).
   CallExpr Call(Context, &ConversionFn, 0, 0,
-                Conversion->getConversionType().getNonReferenceType(),
+                Conversion->getConversionType().getNonLValueExprType(Context),
                 From->getLocStart());
   ImplicitConversionSequence ICS =
     TryCopyInitialization(*this, &Call, ToType,

Added: cfe/trunk/test/SemaCXX/cv-unqual-rvalues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cv-unqual-rvalues.cpp?rev=108253&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/cv-unqual-rvalues.cpp (added)
+++ cfe/trunk/test/SemaCXX/cv-unqual-rvalues.cpp Tue Jul 13 13:40:04 2010
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR7463: Make sure that when we have an rvalue, it does not have
+// cv-qualified non-class type.
+template <typename T_> void g (T_&); // expected-note 7{{not viable}}
+
+template<const int X> void h() { 
+  g(X); // expected-error{{no matching function for call to 'g'}}
+}
+
+template<typename T, T X> void h2() { 
+  g(X); // expected-error{{no matching function for call to 'g'}}
+}
+
+void a(__builtin_va_list x) {
+  g(__builtin_va_arg(x, const int)); // expected-error{{no matching function for call to 'g'}}
+  g((const int)0); // expected-error{{no matching function for call to 'g'}}
+  typedef const int cint;
+  g(cint(0)); // expected-error{{no matching function for call to 'g'}}
+  g(static_cast<const int>(1)); // expected-error{{no matching function for call to 'g'}}
+  g(reinterpret_cast<int *const>(0)); // expected-error{{no matching function for call to 'g'}}
+  h<0>(); 
+  h2<const int, 0>(); // expected-note{{instantiation of}}
+}

Propchange: cfe/trunk/test/SemaCXX/cv-unqual-rvalues.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/SemaCXX/cv-unqual-rvalues.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/SemaCXX/cv-unqual-rvalues.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list