[cfe-commits] r93252 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/Sema/SemaInit.cpp test/CodeGenCXX/reference-init.cpp

Chandler Carruth chandlerc at gmail.com
Tue Jan 12 12:32:25 PST 2010


Author: chandlerc
Date: Tue Jan 12 14:32:25 2010
New Revision: 93252

URL: http://llvm.org/viewvc/llvm-project?rev=93252&view=rev
Log:
Fix the CodeGen half of PR5911 by changing reference initialization to
correctly look through arrays to see cv-qualifiers. Also enhances the routine
for doing this to preserve more type sugaring for diagnostics.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/CodeGenCXX/reference-init.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=93252&r1=93251&r2=93252&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Jan 12 14:32:25 2010
@@ -898,17 +898,18 @@
     return getCanonicalType(T1) == getCanonicalType(T2);
   }
 
-  /// \brief Returns this type as a completely-unqualified array type, capturing
-  /// the qualifiers in Quals. This only operates on canonical types in order
-  /// to ensure the ArrayType doesn't itself have qualifiers.
+  /// \brief Returns this type as a completely-unqualified array type,
+  /// capturing the qualifiers in Quals. This will remove the minimal amount of
+  /// sugaring from the types, similar to the behavior of
+  /// QualType::getUnqualifiedType().
   ///
-  /// \param T is the canonicalized QualType, which may be an ArrayType
+  /// \param T is the qualified type, which may be an ArrayType
   ///
   /// \param Quals will receive the full set of qualifiers that were
-  /// applied to the element type of the array.
+  /// applied to the array.
   ///
   /// \returns if this is an array type, the completely unqualified array type
-  /// that corresponds to it. Otherwise, returns this->getUnqualifiedType().
+  /// that corresponds to it. Otherwise, returns T.getUnqualifiedType().
   QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals);
 
   /// \brief Determine whether the given types are equivalent after

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=93252&r1=93251&r2=93252&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Jan 12 14:32:25 2010
@@ -2374,13 +2374,11 @@
 
 QualType ASTContext::getUnqualifiedArrayType(QualType T,
                                              Qualifiers &Quals) {
-  assert(T.isCanonical() && "Only operates on canonical types");
+  Quals = T.getQualifiers();
   if (!isa<ArrayType>(T)) {
-    Quals = T.getLocalQualifiers();
-    return T.getLocalUnqualifiedType();
+    return T.getUnqualifiedType();
   }
 
-  assert(!T.hasQualifiers() && "canonical array type has qualifiers!");
   const ArrayType *AT = cast<ArrayType>(T);
   QualType Elt = AT->getElementType();
   QualType UnqualElt = getUnqualifiedArrayType(Elt, Quals);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Jan 12 14:32:25 2010
@@ -2227,9 +2227,11 @@
   
   QualType DestType = Entity.getType();
   QualType cv1T1 = DestType->getAs<ReferenceType>()->getPointeeType();
-  QualType T1 = cv1T1.getUnqualifiedType();
+  Qualifiers T1Quals;
+  QualType T1 = S.Context.getUnqualifiedArrayType(cv1T1, T1Quals);
   QualType cv2T2 = Initializer->getType();
-  QualType T2 = cv2T2.getUnqualifiedType();
+  Qualifiers T2Quals;
+  QualType T2 = S.Context.getUnqualifiedArrayType(cv2T2, T2Quals);
   SourceLocation DeclLoc = Initializer->getLocStart();
   
   // If the initializer is the address of an overloaded function, try
@@ -2279,9 +2281,9 @@
       // can occur. This property will be checked by PerformInitialization.
       if (DerivedToBase)
         Sequence.AddDerivedToBaseCastStep(
-                         S.Context.getQualifiedType(T1, cv2T2.getQualifiers()), 
+                         S.Context.getQualifiedType(T1, T2Quals), 
                          /*isLValue=*/true);
-      if (cv1T1.getQualifiers() != cv2T2.getQualifiers())
+      if (T1Quals != T2Quals)
         Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true);
       Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/false);
       return;
@@ -2312,7 +2314,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 && cv1T1.getCVRQualifiers() == Qualifiers::Const) ||
+  if (!((isLValueRef && T1Quals.hasConst()) ||
         (isRValueRef && InitLvalue != Expr::LV_Valid))) {
     if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
       Sequence.SetOverloadFailure(
@@ -2339,9 +2341,9 @@
         RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
       if (DerivedToBase)
         Sequence.AddDerivedToBaseCastStep(
-                         S.Context.getQualifiedType(T1, cv2T2.getQualifiers()), 
+                         S.Context.getQualifiedType(T1, T2Quals), 
                          /*isLValue=*/false);
-      if (cv1T1.getQualifiers() != cv2T2.getQualifiers())
+      if (T1Quals != T2Quals)
         Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/false);
       Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
       return;
@@ -2406,8 +2408,10 @@
   //        [...] If T1 is reference-related to T2, cv1 must be the
   //        same cv-qualification as, or greater cv-qualification
   //        than, cv2; otherwise, the program is ill-formed.
+  unsigned T1CVRQuals = T1Quals.getCVRQualifiers();
+  unsigned T2CVRQuals = T2Quals.getCVRQualifiers();
   if (RefRelationship == Sema::Ref_Related && 
-      !cv1T1.isAtLeastAsQualifiedAs(cv2T2)) {
+      (T1CVRQuals | T2CVRQuals) != T1CVRQuals) {
     Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
     return;
   }

Modified: cfe/trunk/test/CodeGenCXX/reference-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/reference-init.cpp?rev=93252&r1=93251&r2=93252&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenCXX/reference-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/reference-init.cpp Tue Jan 12 14:32:25 2010
@@ -7,3 +7,10 @@
 void a(XPTParamDescriptor *params) {
   const nsXPTParamInfo& paramInfo = params[0];
 }
+
+// CodeGen of reference initialized const arrays.
+namespace PR5911 {
+  template <typename T, int N> int f(const T (&a)[N]) { return N; }
+  int iarr[] = { 1 };
+  int test() { return f(iarr); }
+}





More information about the cfe-commits mailing list