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

Douglas Gregor dgregor at apple.com
Tue Jan 12 12:42:11 PST 2010


On Jan 12, 2010, at 12:32 PM, Chandler Carruth wrote:

> 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.

Thanks!

> 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); }
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list