On Wed, Dec 23, 2009 at 4:30 PM, Eli Friedman <[email protected]> wrote: > On Wed, Dec 23, 2009 at 3:25 PM, Douglas Gregor <[email protected]> wrote: >> >> On Dec 23, 2009, at 3:21 PM, Eli Friedman wrote: >> >>> On Wed, Dec 23, 2009 at 12:51 PM, Douglas Gregor <[email protected]> >>> wrote: >>>> >>>> Author: dgregor >>>> Date: Wed Dec 23 14:51:04 2009 >>>> New Revision: 92041 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=92041&view=rev >>>> Log: >>>> Remove cv-qualifiers from the argument to typeid >>>> >>>> Modified: >>>> cfe/trunk/lib/Sema/SemaExprCXX.cpp >>>> cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp >>>> >>>> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=92041&r1=92040&r2=92041&view=diff >>>> >>>> >>>> ============================================================================== >>>> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) >>>> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Dec 23 14:51:04 2009 >>>> @@ -31,9 +31,14 @@ >>>> if (!StdNamespace) >>>> return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); >>>> >>>> - if (isType) >>>> + if (isType) { >>>> + // C++ [expr.typeid]p4: >>>> + // The top-level cv-qualifiers of the lvalue expression or the >>>> type-id >>>> + // that is the operand of typeid are always ignored. >>>> // FIXME: Preserve type source info. >>>> - TyOrExpr = GetTypeFromParser(TyOrExpr).getAsOpaquePtr(); >>>> + // FIXME: Preserve the type before we stripped the cv-qualifiers? >>>> + TyOrExpr >>>> =GetTypeFromParser(TyOrExpr).getUnqualifiedType().getAsOpaquePtr(); >>>> + } >>>> >>>> IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info"); >>>> LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName); >>>> @@ -45,21 +50,35 @@ >>>> QualType TypeInfoType = Context.getTypeDeclType(TypeInfoRecordDecl); >>>> >>>> if (!isType) { >>>> - // C++0x [expr.typeid]p3: >>>> - // When typeid is applied to an expression other than an lvalue of >>>> a >>>> - // polymorphic class type [...] [the] expression is an unevaluated >>>> - // operand. >>>> - >>>> - // FIXME: if the type of the expression is a class type, the class >>>> - // shall be completely defined. >>>> bool isUnevaluatedOperand = true; >>>> Expr *E = static_cast<Expr *>(TyOrExpr); >>>> - if (E && !E->isTypeDependent() && E->isLvalue(Context) == >>>> Expr::LV_Valid) { >>>> + if (E && !E->isTypeDependent()) { >>>> QualType T = E->getType(); >>>> if (const RecordType *RecordT = T->getAs<RecordType>()) { >>>> CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl()); >>>> - if (RecordD->isPolymorphic()) >>>> + // C++ [expr.typeid]p3: >>>> + // When typeid is applied to an expression other than an >>>> lvalue of a >>>> + // polymorphic class type [...] [the] expression is an >>>> unevaluated >>>> + // operand. [...] >>>> + if (RecordD->isPolymorphic() && E->isLvalue(Context) == >>>> Expr::LV_Valid) >>>> isUnevaluatedOperand = false; >>>> + else { >>>> + // C++ [expr.typeid]p3: >>>> + // [...] If the type of the expression is a class type, the >>>> class >>>> + // shall be completely-defined. >>>> + // FIXME: implement this! >>>> + } >>>> + } >>>> + >>>> + // C++ [expr.typeid]p4: >>>> + // [...] If the type of the type-id is a reference to a possibly >>>> + // cv-qualified type, the result of the typeid expression refers >>>> to a >>>> + // std::type_info object representing the cv-unqualified >>>> referenced >>>> + // type. >>>> + if (T.hasQualifiers()) { >>>> + ImpCastExprToType(E, T.getUnqualifiedType(), CastExpr::CK_NoOp, >>>> + E->isLvalue(Context)); >>>> + TyOrExpr = E; >>>> } >>>> } >>> >>> Umm, applying getUnqualifiedType to a non-canonical type? >> >> Yes, that works now; I fixed it a few weeks ago after seeing too many bugs >> where it did the wrong thing for non-canonical types. We desugar the type as >> far as we need to to find an unqualified type. > > Hmm, but in this particular context, it'll screw up something like the > following: > #include <typeinfo> > typedef int A[10]; > std::type_info a() { return typeid(const A); }
Oops, umm, actually, it looks like we get that right, but mess up "typeid(const int[10])". -Eli _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
