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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
